summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-05-17 12:15:47 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-05-17 12:15:47 +0000
commitd165fa25044b09785b57184936f8b7241be9516e (patch)
tree1ba58619deba2a93b79f4d8d673650fd2b94afb1 /win32
parentf8d97b0026284219aca766db4fa55d6c7357dd4d (diff)
* 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 <tarui AT prx.jp> and the solution was suggested by him, too. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27862 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'win32')
-rw-r--r--win32/win32.c92
1 files changed, 40 insertions, 52 deletions
diff --git a/win32/win32.c b/win32/win32.c
index 739ff571c0..62498cb47c 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -875,53 +875,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) {
@@ -929,13 +895,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:
@@ -944,14 +925,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
@@ -1215,10 +1203,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);
@@ -1226,7 +1214,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);
}