diff options
author | Timothee Cour <timothee.cour2@gmail.com> | 2021-08-12 07:50:08 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-12 16:50:08 +0200 |
commit | 5c1304a4181596e764b05679cd8a0044ab3398dd (patch) | |
tree | a68e7a65e1725012e38d8a0acea9857742f0a5b2 | |
parent | 018465a2345b2d11f7d1d711010d97e636af98d0 (diff) | |
download | Nim-5c1304a4181596e764b05679cd8a0044ab3398dd.tar.gz |
fix #18670 quoteShellCommand, quoteShell, quoteShellWindows on windows (#18671)
-rw-r--r-- | lib/pure/os.nim | 11 | ||||
-rw-r--r-- | tests/stdlib/tos.nim | 13 |
2 files changed, 18 insertions, 6 deletions
diff --git a/lib/pure/os.nim b/lib/pure/os.nim index fd618e93c..cfdacdb3c 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1045,15 +1045,12 @@ proc expandTilde*(path: string): string {. # TODO: handle `~bob` and `~bob/` which means home of bob result = path -# TODO: consider whether quoteShellPosix, quoteShellWindows, quoteShell, quoteShellCommand -# belong in `strutils` instead; they are not specific to paths proc quoteShellWindows*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} = ## Quote `s`, so it can be safely passed to Windows API. ## ## Based on Python's `subprocess.list2cmdline`. ## See `this link <http://msdn.microsoft.com/en-us/library/17w5ykft.aspx>`_ ## for more details. - let needQuote = {' ', '\t'} in s or s.len == 0 result = "" var backslashBuff = "" @@ -1064,8 +1061,8 @@ proc quoteShellWindows*(s: string): string {.noSideEffect, rtl, extern: "nosp$1" if c == '\\': backslashBuff.add(c) elif c == '\"': - result.add(backslashBuff) - result.add(backslashBuff) + for i in 0..<backslashBuff.len*2: + result.add('\\') backslashBuff.setLen(0) result.add("\\\"") else: @@ -1074,9 +1071,13 @@ proc quoteShellWindows*(s: string): string {.noSideEffect, rtl, extern: "nosp$1" backslashBuff.setLen(0) result.add(c) + if backslashBuff.len > 0: + result.add(backslashBuff) if needQuote: + result.add(backslashBuff) result.add("\"") + proc quoteShellPosix*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} = ## Quote ``s``, so it can be safely passed to POSIX shell. const safeUnixChars = {'%', '+', '-', '.', '/', '_', ':', '=', '@', diff --git a/tests/stdlib/tos.nim b/tests/stdlib/tos.nim index dcb2d44f4..b7816fd41 100644 --- a/tests/stdlib/tos.nim +++ b/tests/stdlib/tos.nim @@ -622,7 +622,18 @@ block: # quoteShellWindows doAssert quoteShellWindows("aaa\"") == "aaa\\\"" doAssert quoteShellWindows("") == "\"\"" -block: # quoteShellWindows +block: # quoteShellCommand + when defined(windows): + doAssert quoteShellCommand(["a b c", "d", "e"]) == """"a b c" d e""" + doAssert quoteShellCommand(["""ab"c""", r"\", "d"]) == """ab\"c \ d""" + doAssert quoteShellCommand(["""ab"c""", """ \""", "d"]) == """ab\"c " \\" d""" + doAssert quoteShellCommand(["""a\\\b""", """de fg""", "h"]) == """a\\\b "de fg" h""" + doAssert quoteShellCommand(["""a\"b""", "c", "d"]) == """a\\\"b c d""" + doAssert quoteShellCommand(["""a\\b c""", "d", "e"]) == """"a\\b c" d e""" + doAssert quoteShellCommand(["""a\\b\ c""", "d", "e"]) == """"a\\b\ c" d e""" + doAssert quoteShellCommand(["ab", ""]) == """ab """"" + +block: # quoteShellPosix doAssert quoteShellPosix("aaa") == "aaa" doAssert quoteShellPosix("aaa a") == "'aaa a'" doAssert quoteShellPosix("") == "''" |