fix #18670 quoteShellCommand, quoteShell, quoteShellWindows on windows (#18671)

This commit is contained in:
Timothee Cour
2021-08-12 07:50:08 -07:00
committed by GitHub
parent 018465a234
commit 5c1304a418
2 changed files with 18 additions and 6 deletions

View File

@@ -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 = {'%', '+', '-', '.', '/', '_', ':', '=', '@',

View File

@@ -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("") == "''"