> This breaks quotes, for example try:
>
>   neww -n "a;neww"

I knew the patch caused this behavior.


> I know the existing code allows things like 'neww -n "a;" neww'

And that's why I didn't think it was a problem.  I figured it was
established behavior that semicolons weren't safe in quotes.  People
could escape semicolons if they needed to make sure the parsing
wouldn't split on them.


> It would seem that it'd be better to do this in cmd_string_parse which
> would fix both.

Ok.

> But the problem is that will stop it working with the argv given to main
> which has already been split by the shell.
>
> cmd_list_parse is only used for that argv though... maybe we just make
> it so cmd_string_parse doesn't call cmd_list_parse and they both do the
> same ; stuff in a different way.


I've attached a patch that modifies cmd_string_parse as you described.
diff --git a/cmd-string.c b/cmd-string.c
index e793ea0..5f9a6bc 100644
--- a/cmd-string.c
+++ b/cmd-string.c
@@ -62,11 +62,13 @@ int
 cmd_string_parse(const char *s, struct cmd_list **cmdlist, const char *file,
     u_int line, char **cause)
 {
-       size_t          p;
-       int             ch, i, argc, rval;
-       char          **argv, *buf, *t;
-       const char     *whitespace, *equals;
-       size_t          len;
+       size_t                  p;
+       int                     ch, i, argc;
+       char                  **argv, *buf, *t;
+       const char             *whitespace, *equals;
+       size_t                  len;
+       struct cmd_list        *tmpcmdlist;
+       struct cmd             *cmd;
 
        argv = NULL;
        argc = 0;
@@ -75,9 +77,7 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, 
const char *file,
        len = 0;
 
        *cause = NULL;
-
-       *cmdlist = NULL;
-       rval = -1;
+       tmpcmdlist = NULL;
 
        p = 0;
        for (;;) {
@@ -102,9 +102,14 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, 
const char *file,
                        /* Comment: discard rest of line. */
                        while ((ch = cmd_string_getc(s, &p)) != EOF)
                                ;
+
+                       if (argc == 0 && buf == NULL)
+                               goto out;
+
                        /* FALLTHROUGH */
                case EOF:
                case ' ':
+               case ';':
                case '\t':
                        if (buf != NULL) {
                                buf = xrealloc(buf, 1, len + 1);
@@ -117,26 +122,47 @@ cmd_string_parse(const char *s, struct cmd_list 
**cmdlist, const char *file,
                                len = 0;
                        }
 
-                       if (ch != EOF)
+                       if (ch != EOF && ch != ';')
                                break;
 
-                       while (argc != 0) {
-                               equals = strchr(argv[0], '=');
-                               whitespace = argv[0] + strcspn(argv[0], " \t");
-                               if (equals == NULL || equals > whitespace)
-                                       break;
-                               environ_put(&global_environ, argv[0]);
-                               argc--;
-                               memmove(argv, argv + 1, argc * (sizeof *argv));
+                       if (argc > 0 ) {
+                               while (argc != 0) {
+                                       equals = strchr(argv[0], '=');
+                                       whitespace = argv[0] + strcspn(argv[0], 
" \t");
+                                       if (equals == NULL || equals > 
whitespace)
+                                               break;
+                                       environ_put(&global_environ, argv[0]);
+                                       argc--;
+                                       memmove(argv, argv + 1, argc * (sizeof 
*argv));
+                               }
+                               if (argc == 0) {
+                                       if (ch == ';')
+                                               break;
+                                       else
+                                               goto out;
+                               }
                        }
-                       if (argc == 0)
-                               goto out;
 
-                       *cmdlist = cmd_list_parse(argc, argv, file, line, 
cause);
-                       if (*cmdlist == NULL)
-                               goto out;
+                       cmd = cmd_parse(argc, argv, file, line, cause);
+                       if (cmd == NULL)
+                               goto bad;
+
+                       if (tmpcmdlist == NULL) {
+                               tmpcmdlist = xcalloc(1, sizeof *tmpcmdlist);
+                               tmpcmdlist->references = 1;
+                               TAILQ_INIT(&tmpcmdlist->list);
+                       }
+
+                       TAILQ_INSERT_TAIL(&tmpcmdlist->list, cmd, qentry);
+
+
+                       for (i = 0; i < argc; i++)
+                               free(argv[i]);
+                       argc = 0;
+
+                       if (ch == ';')
+                               break;
 
-                       rval = 0;
                        goto out;
                case '~':
                        if (buf == NULL) {
@@ -160,7 +186,15 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, 
const char *file,
 error:
        xasprintf(cause, "invalid or unknown command: %s", s);
 
+bad:
+       if (tmpcmdlist != NULL) {
+               cmd_list_free(tmpcmdlist);
+               tmpcmdlist = NULL;
+       }
+
 out:
+       *cmdlist = tmpcmdlist;
+
        free(buf);
 
        if (argv != NULL) {
@@ -169,7 +203,10 @@ out:
                free(argv);
        }
 
-       return (rval);
+       if (*cmdlist != NULL)
+               return (0);
+
+       return (-1);
 }
 
 void
------------------------------------------------------------------------------
WatchGuard Dimension instantly turns raw network data into actionable 
security intelligence. It gives you real-time visual feedback on key
security issues and trends.  Skip the complicated setup - simply import
a virtual appliance and go from zero to informed in seconds.
http://pubads.g.doubleclick.net/gampad/clk?id=123612991&iu=/4140/ostg.clktrk
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to