From c1b1642f1bb9c338210b3a9235b871ad09ddeb21 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Wed, 17 Jan 2007 19:35:06 +0000 Subject: [PATCH] 2007-01-17 Marcus Brinkmann * w32-io.c (build_commandline): Quote all command line arguments. * w32-glib-io.c (build_commandline): Likewise. --- gpgme/ChangeLog | 5 ++++ gpgme/w32-glib-io.c | 70 +++++++++++++++++++++++++++++---------------- gpgme/w32-io.c | 70 +++++++++++++++++++++++++++++---------------- 3 files changed, 95 insertions(+), 50 deletions(-) diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 7c1835e..f1ea70e 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,8 @@ +2007-01-17 Marcus Brinkmann + + * w32-io.c (build_commandline): Quote all command line arguments. + * w32-glib-io.c (build_commandline): Likewise. + 2007-01-10 Werner Koch * ttyname_r.c (ttyname_r) [W32]: Return a dummy name. diff --git a/gpgme/w32-glib-io.c b/gpgme/w32-glib-io.c index 97758ba..87b65fb 100644 --- a/gpgme/w32-glib-io.c +++ b/gpgme/w32-glib-io.c @@ -347,37 +347,57 @@ _gpgme_io_set_nonblocking (int fd) static char * -build_commandline ( char **argv ) +build_commandline (char **argv) { - int i, n = 0; - char *buf, *p; + int i; + int j; + int n = 0; + char *buf; + char *p; - /* FIXME: we have to quote some things because under Windows the - * program parses the commandline and does some unquoting. For now - * we only do very basic quoting to the first argument because this - * one often contains a space (e.g. C:\\Program Files\GNU\GnuPG\gpg.exe) - * and we would produce an invalid line in that case. */ - for (i=0; argv[i]; i++) - n += strlen (argv[i]) + 2 + 1; /* 2 extra bytes for possible quoting */ + /* We have to quote some things because under Windows the program + parses the commandline and does some unquoting. We enclose the + whole argument in double-quotes, and escape literal double-quotes + as well as backslashes with a backslash. We end up with a + trailing space at the end of the line, but that is harmless. */ + for (i = 0; argv[i]; i++) + { + p = argv[i]; + /* The leading double-quote. */ + n++; + while (*p) + { + /* An extra one for each literal that must be escaped. */ + if (*p == '\\' || *p == '"') + n++; + n++; + p++; + } + /* The trailing double-quote and the delimiter. */ + n += 2; + } + /* And a trailing zero. */ + n++; + buf = p = malloc (n); - if ( !buf ) + if (!buf) return NULL; - *buf = 0; - if ( argv[0] ) + for (i = 0; argv[i]; i++) { - if (strpbrk (argv[0], " \t")) - p = stpcpy (stpcpy (stpcpy (p, "\""), argv[0]), "\""); - else - p = stpcpy (p, argv[0]); - for (i = 1; argv[i]; i++) - { - if (!*argv[i]) - p = stpcpy (p, " \"\""); - else - p = stpcpy (stpcpy (p, " "), argv[i]); - } + char *argvp = argv[i]; + + *(p++) = '"'; + while (*argvp) + { + if (*p == '\\' || *p == '"') + *(p++) = '\\'; + *(p++) = *(argvp++); + } + *(p++) = '"'; + *(p++) = ' '; } - + *(p++) = 0; + return buf; } diff --git a/gpgme/w32-io.c b/gpgme/w32-io.c index 8acaa44..6810fd5 100644 --- a/gpgme/w32-io.c +++ b/gpgme/w32-io.c @@ -799,37 +799,57 @@ _gpgme_io_set_nonblocking ( int fd ) static char * -build_commandline ( char **argv ) +build_commandline (char **argv) { - int i, n = 0; - char *buf, *p; + int i; + int j; + int n = 0; + char *buf; + char *p; - /* FIXME: we have to quote some things because under Windows the - * program parses the commandline and does some unquoting. For now - * we only do very basic quoting to the first argument because this - * one often contains a space (e.g. C:\\Program Files\GNU\GnuPG\gpg.exe) - * and we would produce an invalid line in that case. */ - for (i=0; argv[i]; i++) - n += strlen (argv[i]) + 2 + 1; /* 2 extra bytes for possible quoting */ + /* We have to quote some things because under Windows the program + parses the commandline and does some unquoting. We enclose the + whole argument in double-quotes, and escape literal double-quotes + as well as backslashes with a backslash. We end up with a + trailing space at the end of the line, but that is harmless. */ + for (i = 0; argv[i]; i++) + { + p = argv[i]; + /* The leading double-quote. */ + n++; + while (*p) + { + /* An extra one for each literal that must be escaped. */ + if (*p == '\\' || *p == '"') + n++; + n++; + p++; + } + /* The trailing double-quote and the delimiter. */ + n += 2; + } + /* And a trailing zero. */ + n++; + buf = p = malloc (n); - if ( !buf ) + if (!buf) return NULL; - *buf = 0; - if ( argv[0] ) + for (i = 0; argv[i]; i++) { - if (strpbrk (argv[0], " \t")) - p = stpcpy (stpcpy (stpcpy (p, "\""), argv[0]), "\""); - else - p = stpcpy (p, argv[0]); - for (i = 1; argv[i]; i++) - { - if (!*argv[i]) - p = stpcpy (p, " \"\""); - else - p = stpcpy (stpcpy (p, " "), argv[i]); - } + char *argvp = argv[i]; + + *(p++) = '"'; + while (*argvp) + { + if (*p == '\\' || *p == '"') + *(p++) = '\\'; + *(p++) = *(argvp++); + } + *(p++) = '"'; + *(p++) = ' '; } - + *(p++) = 0; + return buf; } -- 2.26.2