Skip to content

Commit 77262e1

Browse files
committed
---
yaml --- r: 7807 b: refs/heads/snap-stage3 c: ab223e0 h: refs/heads/master i: 7805: 55d8873 7803: b73157a 7799: 1451f60 7791: 9abbb08 7775: 29a57b4 7743: 927ad5d 7679: 95afb6e v: v3
1 parent abeff97 commit 77262e1

File tree

2 files changed

+63
-5
lines changed

2 files changed

+63
-5
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
refs/heads/master: 2898dcc5d97da9427ac367542382b6239d9c0bbf
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 746fa279889b3ce2ed671aa06d34f15c4f34e902
4+
refs/heads/snap-stage3: ab223e06181434dd7b98fa27a8f902f2d15d7759
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105

branches/snap-stage3/src/rt/rust_run_program.cpp

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,64 @@
55
#include <process.h>
66
#include <io.h>
77

8+
bool backslash_run_ends_in_quote(char const *c) {
9+
while (*c == '\\') ++c;
10+
return *c == '"';
11+
}
12+
13+
void append_first_char(char *&buf, char const *c) {
14+
switch (*c) {
15+
16+
case '"':
17+
// Escape quotes.
18+
*buf++ = '\\';
19+
*buf++ = '"';
20+
break;
21+
22+
23+
case '\\':
24+
if (backslash_run_ends_in_quote(c)) {
25+
// Double all backslashes that are in runs before quotes.
26+
*buf++ = '\\';
27+
*buf++ = '\\';
28+
} else {
29+
// Pass other backslashes through unescaped.
30+
*buf++ = '\\';
31+
}
32+
break;
33+
34+
default:
35+
*buf++ = *c;
36+
}
37+
}
38+
39+
bool contains_whitespace(char const *arg) {
40+
while (*arg) {
41+
switch (*arg++) {
42+
case ' ':
43+
case '\t':
44+
return true;
45+
}
46+
}
47+
return false;
48+
}
49+
50+
void append_arg(char *& buf, char const *arg, bool last) {
51+
bool quote = contains_whitespace(arg);
52+
if (quote)
53+
*buf++ = '"';
54+
while (*arg)
55+
append_first_char(buf, arg++);
56+
if (quote)
57+
*buf++ = '"';
58+
59+
if (! last) {
60+
*buf++ = ' ';
61+
} else {
62+
*buf++ = '\0';
63+
}
64+
}
65+
866
extern "C" CDECL int
967
rust_run_program(const char* argv[], int in_fd, int out_fd, int err_fd) {
1068
STARTUPINFO si;
@@ -29,14 +87,14 @@ rust_run_program(const char* argv[], int in_fd, int out_fd, int err_fd) {
2987
size_t cmd_len = 0;
3088
for (const char** arg = argv; *arg; arg++) {
3189
cmd_len += strlen(*arg);
32-
cmd_len++; // Space or \0
90+
cmd_len += 3; // Two quotes plus trailing space or \0
3391
}
92+
cmd_len *= 2; // Potentially backslash-escape everything.
93+
3494
char* cmd = (char*)malloc(cmd_len);
3595
char* pos = cmd;
3696
for (const char** arg = argv; *arg; arg++) {
37-
strcpy(pos, *arg);
38-
pos += strlen(*arg);
39-
if (*(arg+1)) *(pos++) = ' ';
97+
append_arg(pos, *arg, *(arg+1) == NULL);
4098
}
4199

42100
PROCESS_INFORMATION pi;

0 commit comments

Comments
 (0)