Fix the i3 crash caused by mark + restart commands (#2779)

This patch fixes the issue #2511(https://github.com/i3/i3/issues/2511).

1). Memorize the marks, but only call con_mark once the container has finished parsing. (Credit: This is @Airblader's patch.)

2). Add a test case 267-regress-mark-restart.t for regression test to check if mark and restart command crash i3.
This commit is contained in:
Chih-Chyuan Hwang 2017-05-23 14:47:11 +08:00 committed by Michael Stapelberg
parent 990100317a
commit 13372d511a
2 changed files with 47 additions and 2 deletions

View File

@ -29,6 +29,8 @@ static bool parsing_focus;
static bool parsing_marks; static bool parsing_marks;
struct Match *current_swallow; struct Match *current_swallow;
static bool swallow_is_empty; static bool swallow_is_empty;
static int num_marks;
static char **marks;
/* This list is used for reordering the focus stack after parsing the 'focus' /* This list is used for reordering the focus stack after parsing the 'focus'
* array. */ * array. */
@ -148,6 +150,16 @@ static int json_end_map(void *ctx) {
floating_check_size(json_node); floating_check_size(json_node);
} }
if (num_marks > 0) {
for (int i = 0; i < num_marks; i++) {
con_mark(json_node, marks[i], MM_ADD);
free(marks[i]);
}
free(marks);
num_marks = 0;
}
LOG("attaching\n"); LOG("attaching\n");
con_attach(json_node, json_node->parent, true); con_attach(json_node, json_node->parent, true);
LOG("Creating window\n"); LOG("Creating window\n");
@ -230,8 +242,10 @@ static int json_key(void *ctx, const unsigned char *val, size_t len) {
if (strcasecmp(last_key, "focus") == 0) if (strcasecmp(last_key, "focus") == 0)
parsing_focus = true; parsing_focus = true;
if (strcasecmp(last_key, "marks") == 0) if (strcasecmp(last_key, "marks") == 0) {
num_marks = 0;
parsing_marks = true; parsing_marks = true;
}
return 1; return 1;
} }
@ -261,7 +275,8 @@ static int json_string(void *ctx, const unsigned char *val, size_t len) {
char *mark; char *mark;
sasprintf(&mark, "%.*s", (int)len, val); sasprintf(&mark, "%.*s", (int)len, val);
con_mark(json_node, mark, MM_ADD); marks = srealloc(marks, (++num_marks) * sizeof(char *));
marks[num_marks - 1] = sstrdup(mark);
} else { } else {
if (strcasecmp(last_key, "name") == 0) { if (strcasecmp(last_key, "name") == 0) {
json_node->name = scalloc(len + 1, 1); json_node->name = scalloc(len + 1, 1);

View File

@ -0,0 +1,30 @@
#!perl
# vim:ts=4:sw=4:expandtab
#
# Please read the following documents before working on tests:
# • http://build.i3wm.org/docs/testsuite.html
# (or docs/testsuite)
#
# • http://build.i3wm.org/docs/lib-i3test.html
# (alternatively: perldoc ./testcases/lib/i3test.pm)
#
# • http://build.i3wm.org/docs/ipc.html
# (or docs/ipc)
#
# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
# (unless you are already familiar with Perl)
#
# Regression test to check if mark and restart commands crash i3
#
use i3test;
cmd 'open';
cmd 'mark foo';
cmd 'restart';
diag('Checking if i3 still lives');
does_i3_live;
done_testing;