[PATCH] Fix for backslash quoting in argument list passing (spawn_guts)

Pierre Bogossian bogus@bsdshell.net
Mon Nov 20 09:55:00 GMT 2000


The argument passing to non-cygwin program doesn't work as expected
in some rare cases.

Here is an example that demonstrates the problem:

/tmp $ cat <<EOF > print_args.c
> #include <stdio.h>
>
> int
> main(int argc, char** argv) {
>   int i;
>   for(i = 1; i < argc; i++) {
>     printf("%d: %s\n", i, argv[i]);
>   }
>   exit(0);
> }
> EOF
/tmp $ gcc -o print_args_cygwin print_args.c
/tmp $ gcc -o print_args_nocygwin -mno-cygwin print_args.c
/tmp $ ./print_args_cygwin.exe '\\" a\'
1: \\" a\
/tmp $ ./print_args_nocygwin.exe '\\" a\'
1: \\
2: a"

As you can see the non-cygwin program gets an inconsistent argv.
The problem comes from spawn_guts and the way it handles blackslash
quoting:

When the command line is build in spawn_guts, the literal '"' are
preceded by a '\'. But if a litteral '"' is itself preceded by one or
several literal '\', each literal '\' has to be doubled (currently
this is only done for one preceding '\'). If the closing '"' (ie not
literal), is itself preceded by one or several literal '\', those '\'
have to be doubled too (this isn't done at all currently).

The patch below should fix the problem.
I'm looking forward to you comments, I already submitted a similar
patch 6 months ago but I haven't get any feedback :(

Pierre Bogossian

---

diff -pur winsup-20001116-orig/cygwin/spawn.cc winsup-20001116-patched/cygwin/spawn.cc
--- winsup-20001116-orig/cygwin/spawn.cc        Mon Nov 20 03:43:02 2000
+++ winsup-20001116-patched/cygwin/spawn.cc     Mon Nov 20 03:57:10 2000
@@ -479,16 +479,19 @@ spawn_guts (HANDLE hToken, const char * 
            one_line.add (a, len);
          else
            {
+             char *fpbs;           /* The first preceding backslash */
              one_line.add ("\"", 1);
-             for (; (p = strpbrk (a, "\"\")); a = ++p)
+             for (; (p = strchr (a, '"')); a = ++p)
                {
                  one_line.add (a, p - a);
-                 if ((*p == '\' && p[1] == '"') || *p == '"')
-                   one_line.add ("\", 1);
-                 one_line.add (p, 1);
+                 for (fpbs = p; fpbs != a && fpbs[-1] == '\'; fpbs--);
+                 one_line.add (fpbs, p - fpbs);
+                 one_line.add ("\\"", 2);
                }
-             if (*a)
-               one_line.add (a);
+             p = strchr (a, '\0');
+             one_line.add (a, p - a);
+             for (fpbs = p; fpbs[-1] == '\'; fpbs--);
+             one_line.add (fpbs, p - fpbs);
              one_line.add ("\"", 1);
            }
          MALLOC_CHECK;

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com



More information about the Cygwin mailing list