init_ws_for_output: use workspace_move_to_output
This fixes a crash produced with the following config: # i3 config file (v4) workspace 1 output $screen1 workspace 2 output $screen2 exec --no-startup-id "i3-msg workspace 1, open && i3-msg workspace 2 && xrandr --output $screen2 --off && xrandr --output $screen1 --auto --output $screen2 --auto --right-of $screen1 " Which results in: ERROR: AddressSanitizer: heap-use-after-free on address … READ of size 8 at 0x614000001f48 thread T0 #0 0x5563df6e73a8 in init_ws_for_output i3/src/randr.c:468 #1 0x5563df6ef3b4 in randr_query_outputs i3/src/randr.c:940 #2 0x5563df68dbe1 in handle_screen_change i3/src/handlers.c:450 … is located 264 bytes inside of 448-byte region … freed by thread T0 here: #1 0x5563df634b0a in con_free i3/src/con.c:96 #2 0x5563df7151e6 in tree_close_internal i3/src/tree.c:344 #3 0x5563df7280fe in workspace_show i3/src/workspace.c:499 #4 0x5563df6e7315 in init_ws_for_output i3/src/randr.c:457 #5 0x5563df6ef3b4 in randr_query_outputs i3/src/randr.c:940 #6 0x5563df68dbe1 in handle_screen_change i3/src/handlers.c:450 Which is similar to #3228, #3248.
This commit is contained in:
@ -966,7 +966,11 @@ bool workspace_move_to_output(Con *ws, Output *output) {
|
||||
LOG("got output %p with content %p\n", output, content);
|
||||
|
||||
Con *previously_visible_ws = TAILQ_FIRST(&(content->focus_head));
|
||||
LOG("Previously visible workspace = %p / %s\n", previously_visible_ws, previously_visible_ws->name);
|
||||
if (previously_visible_ws) {
|
||||
DLOG("Previously visible workspace = %p / %s\n", previously_visible_ws, previously_visible_ws->name);
|
||||
} else {
|
||||
DLOG("No previously visible workspace on output.\n");
|
||||
}
|
||||
|
||||
bool workspace_was_visible = workspace_is_visible(ws);
|
||||
if (con_num_children(ws->parent) == 1) {
|
||||
@ -1024,6 +1028,10 @@ bool workspace_move_to_output(Con *ws, Output *output) {
|
||||
workspace_show(ws);
|
||||
}
|
||||
|
||||
if (!previously_visible_ws) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* NB: We cannot simply work with previously_visible_ws since it might
|
||||
* have been cleaned up by workspace_show() already, depending on the
|
||||
* focus order/number of other workspaces on the output.
|
||||
|
Reference in New Issue
Block a user