Mark assignment as run before executing it.

We need to store the information that an assignment was run for a window
before actually executing the command. Otherwise, if the command causes
a change that causes assignments to be run again, the window might be
matched again, causing an infinite loop and hence i3 to freeze or crash.
This commit is contained in:
Ingo Bürk 2015-10-25 14:27:08 +01:00
parent ac4ac94181
commit ad10a366d6

View File

@ -40,6 +40,13 @@ void run_assignments(i3Window *window) {
if (skip) if (skip)
continue; continue;
/* Store that we ran this assignment to not execute it again. We have
* to do this before running the actual command to prevent infinite
* loops. */
window->nr_assignments++;
window->ran_assignments = srealloc(window->ran_assignments, sizeof(Assignment *) * window->nr_assignments);
window->ran_assignments[window->nr_assignments - 1] = current;
DLOG("matching assignment, would do:\n"); DLOG("matching assignment, would do:\n");
if (current->type == A_COMMAND) { if (current->type == A_COMMAND) {
DLOG("execute command %s\n", current->dest.command); DLOG("execute command %s\n", current->dest.command);
@ -53,11 +60,6 @@ void run_assignments(i3Window *window) {
command_result_free(result); command_result_free(result);
} }
/* Store that we ran this assignment to not execute it again */
window->nr_assignments++;
window->ran_assignments = srealloc(window->ran_assignments, sizeof(Assignment *) * window->nr_assignments);
window->ran_assignments[window->nr_assignments - 1] = current;
} }
/* If any of the commands required re-rendering, we will do that now. */ /* If any of the commands required re-rendering, we will do that now. */