From 60bfc3a600184bf3d1cdab405990e2e009d64357 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Fri, 11 Nov 2011 00:28:04 +0000 Subject: [PATCH] Bugfix: Correctly handle --no-startup-id with quoted exec commands (Thanks aksr) Parser changes shortly before a release. What could possibly go wrong. --- src/cfgparse.l | 8 ++++-- src/cfgparse.y | 39 +++++++++----------------- src/cmdparse.l | 6 +++- src/cmdparse.y | 19 +++++++------ testcases/t/175-startup-notification.t | 17 +++++++++++ 5 files changed, 52 insertions(+), 37 deletions(-) diff --git a/src/cfgparse.l b/src/cfgparse.l index 1f584c32..1566e24f 100644 --- a/src/cfgparse.l +++ b/src/cfgparse.l @@ -63,6 +63,8 @@ EOL (\r?\n) %x BAR_COLORS %x BAR_COLOR +%x EXEC + %% { @@ -142,6 +144,8 @@ EOL (\r?\n) #[0-9a-fA-F]+ { yy_pop_state(); yylval.string = sstrdup(yytext); return HEXCOLOR; } [ \t]*→[ \t]* { BEGIN(WANT_STRING); } [ \t]+ { BEGIN(WANT_STRING); } +--no-startup-id { printf("no startup id\n"); yy_pop_state(); return TOK_NO_STARTUP_ID; } +. { printf("anything else: *%s*\n", yytext); yyless(0); yy_pop_state(); yy_pop_state(); } [0-9]+ { yylval.number = atoi(yytext); return NUMBER; } bar { yy_push_state(BAR); return TOK_BAR; } mode { return TOKMODE; } @@ -195,8 +199,8 @@ tabbed { /* yylval.number = MODE_TABBED; */return TOK_T stack-limit { return TOKSTACKLIMIT; } cols { /* yylval.number = STACK_LIMIT_COLS; */return TOKSTACKLIMIT; } rows { /* yylval.number = STACK_LIMIT_ROWS; */return TOKSTACKLIMIT; } -exec { WS_STRING; return TOKEXEC; } -exec_always { WS_STRING; return TOKEXEC_ALWAYS; } +exec { WS_STRING; yy_push_state(EXEC); yy_push_state(EAT_WHITESPACE); return TOKEXEC; } +exec_always { WS_STRING; yy_push_state(EXEC); yy_push_state(EAT_WHITESPACE); return TOKEXEC_ALWAYS; } client.background { yy_push_state(COLOR_COND); yylval.single_color = &config.client.background; return TOKSINGLECOLOR; } client.focused { yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yylval.color = &config.client.focused; return TOKCOLOR; } client.focused_inactive { yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yylval.color = &config.client.focused_inactive; return TOKCOLOR; } diff --git a/src/cfgparse.y b/src/cfgparse.y index 9bce2f37..79da317d 100644 --- a/src/cfgparse.y +++ b/src/cfgparse.y @@ -715,6 +715,7 @@ void parse_file(const char *f) { %token TOK_BAR_COLOR_ACTIVE_WORKSPACE "active_workspace" %token TOK_BAR_COLOR_INACTIVE_WORKSPACE "inactive_workspace" %token TOK_BAR_COLOR_URGENT_WORKSPACE "urgent_workspace" +%token TOK_NO_STARTUP_ID "--no-startup-id" %token TOK_MARK "mark" %token TOK_CLASS "class" @@ -739,6 +740,7 @@ void parse_file(const char *f) { %type popup_setting %type bar_position_position %type bar_mode_mode +%type optional_no_startup_id %type command %type word_or_number %type qstring_or_number @@ -1508,45 +1510,30 @@ restart_state: ; exec: - TOKEXEC STR + TOKEXEC optional_no_startup_id STR { - char *command = $2; - bool no_startup_id = false; - if (strncasecmp($2, "--no-startup-id ", strlen("--no-startup-id ")) == 0) { - no_startup_id = true; - /* We need to make a copy here, otherwise we leak the - * --no-startup-id bytes in the beginning of the string */ - command = sstrdup(command + strlen("--no-startup-id ")); - free($2); - } - struct Autostart *new = smalloc(sizeof(struct Autostart)); - new->command = command; - new->no_startup_id = no_startup_id; + new->command = $3; + new->no_startup_id = $2; TAILQ_INSERT_TAIL(&autostarts, new, autostarts); } ; exec_always: - TOKEXEC_ALWAYS STR + TOKEXEC_ALWAYS optional_no_startup_id STR { - char *command = $2; - bool no_startup_id = false; - if (strncasecmp($2, "--no-startup-id ", strlen("--no-startup-id ")) == 0) { - no_startup_id = true; - /* We need to make a copy here, otherwise we leak the - * --no-startup-id bytes in the beginning of the string */ - command = sstrdup(command + strlen("--no-startup-id ")); - free($2); - } - struct Autostart *new = smalloc(sizeof(struct Autostart)); - new->command = command; - new->no_startup_id = no_startup_id; + new->command = $3; + new->no_startup_id = $2; TAILQ_INSERT_TAIL(&autostarts_always, new, autostarts_always); } ; +optional_no_startup_id: + /* empty */ { $$ = false; } + | TOK_NO_STARTUP_ID { $$ = true; } + ; + terminal: TOKTERMINAL STR { diff --git a/src/cmdparse.l b/src/cmdparse.l index 9a5b3d7b..5a727658 100644 --- a/src/cmdparse.l +++ b/src/cmdparse.l @@ -48,6 +48,8 @@ EOL (\r?\n) /* handle a quoted string or everything up to the next whitespace */ %s WANT_QSTRING +%x EXEC + %x BUFFER_LINE %% @@ -101,7 +103,9 @@ back_and_forth { BEGIN(INITIAL); return TOK_BACK_AND_FORTH; } [ \t]* { yy_pop_state(); } [ \t]* { /* ignore whitespace */ ; } -exec { WS_STRING; return TOK_EXEC; } +--no-startup-id { printf("no startup id\n"); yy_pop_state(); return TOK_NO_STARTUP_ID; } +. { printf("anything else: *%s*\n", yytext); yyless(0); yy_pop_state(); yy_pop_state(); } +exec { WS_STRING; yy_push_state(EXEC); yy_push_state(EAT_WHITESPACE); return TOK_EXEC; } exit { return TOK_EXIT; } reload { return TOK_RELOAD; } restart { return TOK_RESTART; } diff --git a/src/cmdparse.y b/src/cmdparse.y index a1fb0473..e413f21b 100644 --- a/src/cmdparse.y +++ b/src/cmdparse.y @@ -174,6 +174,7 @@ bool definitelyGreaterThan(float a, float b, float epsilon) { %token TOK_PPT "ppt" %token TOK_NOP "nop" %token TOK_BACK_AND_FORTH "back_and_forth" +%token TOK_NO_STARTUP_ID "--no-startup-id" %token TOK_CLASS "class" %token TOK_INSTANCE "instance" @@ -197,6 +198,7 @@ bool definitelyGreaterThan(float a, float b, float epsilon) { %type resize_way %type resize_tiling %type optional_kill_mode +%type optional_no_startup_id %% @@ -387,21 +389,22 @@ operation: ; exec: - TOK_EXEC STR + TOK_EXEC optional_no_startup_id STR { - char *command = $2; - bool no_startup_id = false; - if (strncasecmp($2, "--no-startup-id ", strlen("--no-startup-id ")) == 0) { - no_startup_id = true; - command += strlen("--no-startup-id "); - } + char *command = $3; + bool no_startup_id = $2; printf("should execute %s, no_startup_id = %d\n", command, no_startup_id); start_application(command, no_startup_id); - free($2); + free($3); } ; +optional_no_startup_id: + /* empty */ { $$ = false; } + | TOK_NO_STARTUP_ID { $$ = true; } + ; + exit: TOK_EXIT { diff --git a/testcases/t/175-startup-notification.t b/testcases/t/175-startup-notification.t index 635ee476..55df4142 100644 --- a/testcases/t/175-startup-notification.t +++ b/testcases/t/175-startup-notification.t @@ -151,4 +151,21 @@ unlink($tmp); is($startup_id, '', 'startup_id empty'); +###################################################################### +# 4) same thing, but with double quotes in exec +###################################################################### + +mkfifo($tmp, 0600) or die "Could not create FIFO in $tmp"; + +cmd qq|exec --no-startup-id "echo \$DESKTOP_STARTUP_ID >$tmp"|; + +open($fh, '<', $tmp); +chomp($startup_id = <$fh>); +close($fh); + +unlink($tmp); + +is($startup_id, '', 'startup_id empty'); + + done_testing; -- 2.39.5