From 36abd250a6f639e74276822ff6ad08df94dd1278 Mon Sep 17 00:00:00 2001 From: usa Date: Wed, 19 May 2010 01:46:51 +0000 Subject: merge from trunk (r27862) * win32/win32.c (argv_size): merged into join_argv() to maintain the agreement with it. removed code has a calclulation bug. fixed [Bug#2388] * win32/win32.c (join_argv): calc and return the length of joined argv. the cause of the original bug was clarified by Masaya TARUI and the solution was suggested by him, too. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_2@27875 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- win32/win32.c | 92 ++++++++++++++++++++++++++--------------------------------- 1 file changed, 40 insertions(+), 52 deletions(-) (limited to 'win32') diff --git a/win32/win32.c b/win32/win32.c index fa49cf17de..b60ea8cadd 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -864,53 +864,19 @@ rb_w32_get_osfhandle(int fh) } static int -argv_size(char *const *argv, BOOL escape) -{ - const char *p; - char *const *t; - int len, n, bs, quote; - - for (t = argv, len = 0; *t; t++) { - for (p = *t, n = quote = bs = 0; *p; ++p) { - switch (*p) { - case '\\': - ++bs; - break; - case '<': case '>': case '|': case '^': - bs = 0; - if (escape && !quote) n++; - break; - case '"': - n += bs + 1; bs = 0; - quote = 1; - break; - case ' ': case '\t': - quote = 1; - default: - bs = 0; - p = CharNext(p) - 1; - break; - } - } - len += p - *t + n + 1; - if (p - *t == 0 || quote) len += 2; - } - return len; -} - -static char * join_argv(char *cmd, char *const *argv, BOOL escape) { const char *p, *s; char *q, *const *t; - int n, bs, quote; + int len, n, bs, quote; - for (t = argv, q = cmd; p = *t; t++) { + for (t = argv, q = cmd, len = 0; p = *t; t++) { quote = 0; s = p; if (!*p || strpbrk(p, " \t\"'")) { quote = 1; - *q++ = '"'; + len++; + if (q) *q++ = '"'; } for (bs = 0; *p; ++p) { switch (*p) { @@ -918,13 +884,28 @@ join_argv(char *cmd, char *const *argv, BOOL escape) ++bs; break; case '"': - memcpy(q, s, n = p - s); q += n; s = p; - memset(q, '\\', ++bs); q += bs; bs = 0; + len += n = p - s; + if (q) { + memcpy(q, s, n); + q += n; + } + s = p; + len += ++bs; + if (q) { + memset(q, '\\', bs); + q += bs; + } + bs = 0; break; case '<': case '>': case '|': case '^': if (escape && !quote) { - memcpy(q, s, n = p - s); q += n; s = p; - *q++ = '^'; + len += (n = p - s) + 1; + if (q) { + memcpy(q, s, n); + q += n; + *q++ = '^'; + } + s = p; break; } default: @@ -933,14 +914,21 @@ join_argv(char *cmd, char *const *argv, BOOL escape) break; } } - memcpy(q, s, n = p - s); - q += n; - if (quote) *q++ = '"'; - *q++ = ' '; + len += (n = p - s) + 1; + if (quote) len++; + if (q) { + memcpy(q, s, n); + q += n; + if (quote) *q++ = '"'; + *q++ = ' '; + } + } + if (q > cmd) --len; + if (q) { + if (q > cmd) --q; + *q = '\0'; } - if (q > cmd) --q; - *q = '\0'; - return cmd; + return len; } #ifdef HAVE_SYS_PARAM_H @@ -1204,10 +1192,10 @@ rb_w32_aspawn(int mode, const char *prog, char *const *argv) char *progs[2]; progs[0] = (char *)prog; progs[1] = NULL; - len = argv_size(progs, ntcmd); + len = join_argv(NULL, progs, ntcmd); if (c_switch) len += 3; else ++argv; - if (argv[0]) len += argv_size(argv, ntcmd); + if (argv[0]) len += join_argv(NULL, argv, ntcmd); cmd = ALLOCA_N(char, len); join_argv(cmd, progs, ntcmd); if (c_switch) strlcat(cmd, " /c", len); @@ -1215,7 +1203,7 @@ rb_w32_aspawn(int mode, const char *prog, char *const *argv) prog = c_switch ? shell : 0; } else { - len = argv_size(argv, FALSE); + len = join_argv(NULL, argv, FALSE); cmd = ALLOCA_N(char, len); join_argv(cmd, argv, FALSE); } -- cgit v1.2.3