From ae00468dca858411dcd48b1267d8717c915dbf44 Mon Sep 17 00:00:00 2001 From: Orestis Floros Date: Sun, 12 Apr 2020 00:48:01 +0200 Subject: [PATCH] Fix load_layout crash when floating node doesn't have CT_FLOATING_CON parent Fixes #3901 --- src/load_layout.c | 13 ++++++++ testcases/t/215-layout-restore-crash.t | 46 +++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/load_layout.c b/src/load_layout.c index 4f107cd6..461508c9 100644 --- a/src/load_layout.c +++ b/src/load_layout.c @@ -170,6 +170,19 @@ static int json_end_map(void *ctx) { con_attach(json_node, json_node->parent, true); LOG("Creating window\n"); x_con_init(json_node); + + /* Fix erroneous JSON input regarding floating containers to avoid + * crashing, see #3901. */ + const int old_floating_mode = json_node->floating; + if (old_floating_mode >= FLOATING_AUTO_ON && json_node->parent->type != CT_FLOATING_CON) { + LOG("Fixing floating node without CT_FLOATING_CON parent\n"); + + /* Force floating_enable to work */ + json_node->floating = FLOATING_AUTO_OFF; + floating_enable(json_node, false); + json_node->floating = old_floating_mode; + } + json_node = json_node->parent; incomplete--; DLOG("incomplete = %d\n", incomplete); diff --git a/testcases/t/215-layout-restore-crash.t b/testcases/t/215-layout-restore-crash.t index 0306425a..d9fcd54a 100644 --- a/testcases/t/215-layout-restore-crash.t +++ b/testcases/t/215-layout-restore-crash.t @@ -212,7 +212,7 @@ subtest 'issue 2755' => sub { EOT $fh->flush; $reply = cmd "append_layout $filename"; - ok(!$reply->[0]->{success}, 'IPC reply indicated success'); + ok(!$reply->[0]->{success}, 'IPC reply did not indicate success'); does_i3_live; @@ -276,5 +276,49 @@ does_i3_live; close($fh); +################################################################################ +# Issue with floating key being set, without proper parent +# See #3901 +################################################################################ +subtest 'issue 3901' => sub { + kill_all_windows; + $ws = fresh_workspace; + is(scalar @{get_ws($ws)->{floating_nodes}}, 0, 'No floating nodes yet'); + + ($fh, $filename) = tempfile(UNLINK => 1); + print $fh <<'EOT'; +// vim:ts=4:sw=4:et +{ + "border": "pixel", + "current_border_width": 1, + "floating": "auto_on", // crashes: user_on, auto_on, no crash: user_off, auto_off + "geometry": { + "height": 400, + "width": 300, + "x": 820, + "y": 350 + }, + "name": "Click me to crash", + "percent": 0.5, // still crashes if this field is absent + "swallows": [ + { + "class": "^this doesn't matter as long as it doesn't match a new window$" + } + ], + "type": "con" +} + +EOT + $fh->flush; + $reply = cmd "append_layout $filename"; + ok($reply->[0]->{success}, 'IPC reply indicated success'); + + cmd '[floating] focus'; + is(scalar @{get_ws($ws)->{floating_nodes}}, 1, 'one floating node on this ws'); + + does_i3_live; + + close($fh); +}; done_testing;