authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-06-22 20:07:43-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-06-22 20:07:43-04:00
log78c6d39cd49225bdfd2de4da7b1730ba26a41ba4
tree9956a770d099291106cdbb754475b3c7e47c29f1
parent923c0feda1e42dcaf65ab80bafd7400996b39861
parent7cb41a415a6eca7d13980a62ee5727b4adcad8b0
signature Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #5667 from cartr/windows-arguments-unclosed-quote

In std.process.ArgIteratorWindows, don't treat unclosed quotes like they're escaped

1 files changed, 7 insertions(+), 34 deletions(-)

lib/std/process.zig+7-34
......@@ -281,9 +281,6 @@ pub const ArgIteratorWasi = struct {
281281pub const ArgIteratorWindows = struct {
282282 index: usize,
283283 cmd_line: [*]const u8,
284 in_quote: bool,
285 quote_count: usize,
286 seen_quote_count: usize,
287284
288285 pub const NextError = error{OutOfMemory};
289286
......@@ -295,9 +292,6 @@ pub const ArgIteratorWindows = struct {
295292 return ArgIteratorWindows{
296293 .index = 0,
297294 .cmd_line = cmd_line,
298 .in_quote = false,
299 .quote_count = countQuotes(cmd_line),
300 .seen_quote_count = 0,
301295 };
302296 }
303297
......@@ -328,6 +322,7 @@ pub const ArgIteratorWindows = struct {
328322 }
329323
330324 var backslash_count: usize = 0;
325 var in_quote = false;
331326 while (true) : (self.index += 1) {
332327 const byte = self.cmd_line[self.index];
333328 switch (byte) {
......@@ -335,14 +330,14 @@ pub const ArgIteratorWindows = struct {
335330 '"' => {
336331 const quote_is_real = backslash_count % 2 == 0;
337332 if (quote_is_real) {
338 self.seen_quote_count += 1;
333 in_quote = !in_quote;
339334 }
340335 },
341336 '\\' => {
342337 backslash_count += 1;
343338 },
344339 ' ', '\t' => {
345 if (self.seen_quote_count % 2 == 0 or self.seen_quote_count == self.quote_count) {
340 if (!in_quote) {
346341 return true;
347342 }
348343 backslash_count = 0;
......@@ -360,6 +355,7 @@ pub const ArgIteratorWindows = struct {
360355 defer buf.deinit();
361356
362357 var backslash_count: usize = 0;
358 var in_quote = false;
363359 while (true) : (self.index += 1) {
364360 const byte = self.cmd_line[self.index];
365361 switch (byte) {
......@@ -370,10 +366,7 @@ pub const ArgIteratorWindows = struct {
370366 backslash_count = 0;
371367
372368 if (quote_is_real) {
373 self.seen_quote_count += 1;
374 if (self.seen_quote_count == self.quote_count and self.seen_quote_count % 2 == 1) {
375 try buf.append('"');
376 }
369 in_quote = !in_quote;
377370 } else {
378371 try buf.append('"');
379372 }
......@@ -384,7 +377,7 @@ pub const ArgIteratorWindows = struct {
384377 ' ', '\t' => {
385378 try self.emitBackslashes(&buf, backslash_count);
386379 backslash_count = 0;
387 if (self.seen_quote_count % 2 == 1 and self.seen_quote_count != self.quote_count) {
380 if (in_quote) {
388381 try buf.append(byte);
389382 } else {
390383 return buf.toOwnedSlice();
......@@ -405,26 +398,6 @@ pub const ArgIteratorWindows = struct {
405398 try buf.append('\\');
406399 }
407400 }
408
409 fn countQuotes(cmd_line: [*]const u8) usize {
410 var result: usize = 0;
411 var backslash_count: usize = 0;
412 var index: usize = 0;
413 while (true) : (index += 1) {
414 const byte = cmd_line[index];
415 switch (byte) {
416 0 => return result,
417 '\\' => backslash_count += 1,
418 '"' => {
419 result += 1 - (backslash_count % 2);
420 backslash_count = 0;
421 },
422 else => {
423 backslash_count = 0;
424 },
425 }
426 }
427 }
428401};
429402
430403pub const ArgIterator = struct {
......@@ -578,7 +551,7 @@ test "windows arg parsing" {
578551 testWindowsCmdLine("a\\\\\\b d\"e f\"g h", &[_][]const u8{ "a\\\\\\b", "de fg", "h" });
579552 testWindowsCmdLine("a\\\\\\\"b c d", &[_][]const u8{ "a\\\"b", "c", "d" });
580553 testWindowsCmdLine("a\\\\\\\\\"b c\" d e", &[_][]const u8{ "a\\\\b c", "d", "e" });
581 testWindowsCmdLine("a b\tc \"d f", &[_][]const u8{ "a", "b", "c", "\"d", "f" });
554 testWindowsCmdLine("a b\tc \"d f", &[_][]const u8{ "a", "b", "c", "d f" });
582555
583556 testWindowsCmdLine("\".\\..\\zig-cache\\build\" \"bin\\zig.exe\" \".\\..\" \".\\..\\zig-cache\" \"--help\"", &[_][]const u8{
584557 ".\\..\\zig-cache\\build",