]> git.sur5r.net Git - i3/i3/commitdiff
Bugfix: Correctly handle --no-startup-id with quoted exec commands (Thanks aksr)
authorMichael Stapelberg <michael@stapelberg.de>
Fri, 11 Nov 2011 00:28:04 +0000 (00:28 +0000)
committerMichael Stapelberg <michael@stapelberg.de>
Fri, 11 Nov 2011 00:28:04 +0000 (00:28 +0000)
Parser changes shortly before a release. What could possibly go wrong.

src/cfgparse.l
src/cfgparse.y
src/cmdparse.l
src/cmdparse.y
testcases/t/175-startup-notification.t

index 1f584c327196476b31511391599885d3ef76c0ed..1566e24f879fabd4a162500cb28057a8b4461344 100644 (file)
@@ -63,6 +63,8 @@ EOL     (\r?\n)
 %x BAR_COLORS
 %x BAR_COLOR
 
+%x EXEC
+
 %%
 
     {
@@ -142,6 +144,8 @@ EOL     (\r?\n)
 <COLOR_COND>#[0-9a-fA-F]+       { yy_pop_state(); yylval.string = sstrdup(yytext); return HEXCOLOR; }
 <ASSIGN_TARGET_COND>[ \t]*→[ \t]*     { BEGIN(WANT_STRING); }
 <ASSIGN_TARGET_COND>[ \t]+      { BEGIN(WANT_STRING); }
+<EXEC>--no-startup-id           { printf("no startup id\n"); yy_pop_state(); return TOK_NO_STARTUP_ID; }
+<EXEC>.                         { 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; }
index 9bce2f376b726be6758db00adc5e94fb7d4ba96d..79da317d2e19a3b9cc668aee4918d5af043d76e3 100644 (file)
@@ -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   <number>        popup_setting
 %type   <number>        bar_position_position
 %type   <number>        bar_mode_mode
+%type   <number>        optional_no_startup_id
 %type   <string>        command
 %type   <string>        word_or_number
 %type   <string>        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
     {
index 9a5b3d7b4f64522b5443c6d8bc966bcf3b22151e..5a727658aced1493281c617025fb05b29d23a253 100644 (file)
@@ -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; }
 <EAT_WHITESPACE>[ \t]*          { yy_pop_state(); }
 
 [ \t]*                          { /* ignore whitespace */ ; }
-exec                            { WS_STRING; return TOK_EXEC; }
+<EXEC>--no-startup-id           { printf("no startup id\n"); yy_pop_state(); return TOK_NO_STARTUP_ID; }
+<EXEC>.                         { 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; }
index a1fb0473020af29634d011f07481e22d1c9eaae0..e413f21ba8c5f4f5f3f3ea137be566e1357a7bea 100644 (file)
@@ -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   <number>    resize_way
 %type   <number>    resize_tiling
 %type   <number>    optional_kill_mode
+%type   <number>    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
     {
index 635ee4765087a6637c57e39304e1584d079cc761..55df41429f75705e7b144be60f2e81ce91a57857 100644 (file)
@@ -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;