From e6f11fc5d2e6c876839be0b684fcb82f2692503d Mon Sep 17 00:00:00 2001 From: Leon Henrik Plickat Date: Sat, 27 Mar 2021 07:06:32 +0100 Subject: [PATCH] Fix crash when layer surface dimensions or margins are unexpectedly large --- river/Output.zig | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/river/Output.zig b/river/Output.zig index 03c9f0f..3de9631 100644 --- a/river/Output.zig +++ b/river/Output.zig @@ -400,7 +400,25 @@ fn arrangeLayer( var new_box: Box = undefined; // Horizontal alignment - if (current_state.desired_width == 0) { + const horizontal_margin_size = current_state.margin.left + current_state.margin.right; + if (horizontal_margin_size >= bounds.width) { + // TODO find a better solution + // We currently have not reached a conclusion on how to gracefully + // handle this case yet, so we just close the surface. That will + // cause the output to be re-arranged eventually, so we can just + // exit here. Technically doing this is incorrect, but this case + // should only ever be encountered very rarely and matches the + // behavior of other compositors. + std.log.scoped(.layer_shell).warn( + "margins of layer surface '{}' are too large to be reasonably handled. Closing.", + .{layer_surface.wlr_layer_surface.namespace}, + ); + layer_surface.wlr_layer_surface.close(); + return; + } else if (horizontal_margin_size + current_state.desired_width > bounds.width) { + new_box.y = bounds.y; + new_box.width = bounds.width - horizontal_margin_size; + } else if (current_state.desired_width == 0) { std.debug.assert(current_state.anchor.right and current_state.anchor.left); new_box.x = bounds.x + @intCast(i32, current_state.margin.left); new_box.width = bounds.width - (current_state.margin.left + current_state.margin.right); @@ -417,7 +435,19 @@ fn arrangeLayer( } // Vertical alignment - if (current_state.desired_height == 0) { + const vertical_margin_size = current_state.margin.bottom + current_state.margin.top; + if (vertical_margin_size >= bounds.height) { + // TODO find a better solution, see explanation above + std.log.scoped(.layer_shell).warn( + "margins of layer surface '{}' are too large to be reasonably handled. Closing.", + .{layer_surface.wlr_layer_surface.namespace}, + ); + layer_surface.wlr_layer_surface.close(); + return; + } else if (vertical_margin_size + current_state.desired_height > bounds.height) { + new_box.y = bounds.y; + new_box.height = bounds.height - vertical_margin_size; + } else if (current_state.desired_height == 0) { std.debug.assert(current_state.anchor.top and current_state.anchor.bottom); new_box.y = bounds.y + @intCast(i32, current_state.margin.top); new_box.height = bounds.height - (current_state.margin.top + current_state.margin.bottom);