Fix two problems in string->argv conversion: 1) multiple backslashes
authordjm <djm@openbsd.org>
Sat, 3 Apr 2021 05:21:46 +0000 (05:21 +0000)
committerdjm <djm@openbsd.org>
Sat, 3 Apr 2021 05:21:46 +0000 (05:21 +0000)
were not being dequoted correctly and 2) quoted space in the middle
of a string was being incorrectly split.

A unit test for these cases has already been committed

prompted by and based on GHPR#223 by Eero Häkkinen; ok markus@

usr.bin/ssh/misc.c

index 88dc5f4..a32d7fe 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.162 2021/02/28 01:50:47 dtucker Exp $ */
+/* $OpenBSD: misc.c,v 1.163 2021/04/03 05:21:46 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2005-2020 Damien Miller.  All rights reserved.
@@ -1846,11 +1846,6 @@ argv_split(const char *s, int *argcp, char ***argvp)
 
                /* Start of a token */
                quote = 0;
-               if (s[i] == '\\' &&
-                   (s[i + 1] == '\'' || s[i + 1] == '\"' || s[i + 1] == '\\'))
-                       i++;
-               else if (s[i] == '\'' || s[i] == '"')
-                       quote = s[i++];
 
                argv = xreallocarray(argv, (argc + 2), sizeof(*argv));
                arg = argv[argc++] = xcalloc(1, strlen(s + i) + 1);
@@ -1870,8 +1865,10 @@ argv_split(const char *s, int *argcp, char ***argvp)
                                }
                        } else if (quote == 0 && (s[i] == ' ' || s[i] == '\t'))
                                break; /* done */
+                       else if (quote == 0 && (s[i] == '\"' || s[i] == '\''))
+                               quote = s[i]; /* quote start */
                        else if (quote != 0 && s[i] == quote)
-                               break; /* done */
+                               quote = 0; /* quote end */
                        else
                                arg[j++] = s[i];
                }