aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Orzechowski <orzechowski.alexander@gmail.com>2022-09-27 20:07:08 -0400
committerKirill Primak <vyivel@eclair.cafe>2022-10-10 08:09:55 +0000
commitdd9cfd3e2f38c8f67694961acdc6b68222d067ea (patch)
tree754f1e1bcb342df1d68078311b0775f6caa85261
parent954974950726f3b6dbc8c5341722c942eade07f1 (diff)
wlr_scene: Be resilient against overflow conditions
If the area calculations for output overlap overflow a signed int, we may not consider it to be a primary output. Turn this into an unsigned type so this happens less frequently. Additionally, it is possible the overflow would produce 0, we can handle this by simply changing the comparison to more than or equal. While we're here, let's assert that we always assign a primary output if there are any intersecting outputs.
-rw-r--r--types/scene/wlr_scene.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c
index dff664d2..89aae843 100644
--- a/types/scene/wlr_scene.c
+++ b/types/scene/wlr_scene.c
@@ -296,7 +296,7 @@ static void update_node_update_outputs(struct wlr_scene_node *node,
struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_from_node(node);
- int largest_overlap = 0;
+ uint32_t largest_overlap = 0;
scene_buffer->primary_output = NULL;
uint64_t active_outputs = 0;
@@ -326,8 +326,8 @@ static void update_node_update_outputs(struct wlr_scene_node *node,
output_box.x, output_box.y, output_box.width, output_box.height);
if (pixman_region32_not_empty(&intersection)) {
- int overlap = region_area(&intersection);
- if (overlap > largest_overlap) {
+ uint32_t overlap = region_area(&intersection);
+ if (overlap >= largest_overlap) {
largest_overlap = overlap;
scene_buffer->primary_output = scene_output;
}
@@ -352,6 +352,10 @@ static void update_node_update_outputs(struct wlr_scene_node *node,
wl_signal_emit_mutable(&scene_buffer->events.output_leave, scene_output);
}
}
+
+ // if there are active outputs on this node, we should always have a primary
+ // output
+ assert(!scene_buffer->active_outputs || scene_buffer->primary_output);
}
static bool scene_node_update_iterator(struct wlr_scene_node *node,