11/*
22 This source file is part of the Swift.org open source project
33
4- Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
4+ Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
55 Licensed under Apache License v2.0 with Runtime Library Exception
66
77 See http://swift.org/LICENSE.txt for license information
1515///
1616/// - Returns: True if shell escaping is not needed.
1717private func inShellWhitelist( _ codeUnit: UInt8 ) -> Bool {
18+ #if os(Windows)
19+ if codeUnit == UInt8 ( ascii: " \\ " ) {
20+ return true
21+ }
22+ #endif
1823 switch codeUnit {
1924 case UInt8 ( ascii: " a " ) ... UInt8 ( ascii: " z " ) ,
2025 UInt8 ( ascii: " A " ) ... UInt8 ( ascii: " Z " ) ,
@@ -38,7 +43,7 @@ private func inShellWhitelist(_ codeUnit: UInt8) -> Bool {
3843extension String {
3944
4045 /// Creates a shell escaped string. If the string does not need escaping, returns the original string.
41- /// Otherwise escapes using single quotes. For example:
46+ /// Otherwise escapes using single quotes on Unix and double quotes on Windows . For example:
4247 /// hello -> hello, hello$world -> 'hello$world', input A -> 'input A'
4348 ///
4449 /// - Returns: Shell escaped string.
@@ -49,23 +54,30 @@ extension String {
4954 return self
5055 }
5156
52- // If there are no single quotes then we can just wrap the string around single quotes.
53- guard let singleQuotePos = utf8 [ pos... ] . firstIndex ( of: UInt8 ( ascii: " ' " ) ) else {
54- return " ' " + self + " ' "
57+ #if os(Windows)
58+ let quoteCharacter : Character = " \" "
59+ let escapedQuoteCharacter = " \" \" "
60+ #else
61+ let quoteCharacter : Character = " ' "
62+ let escapedQuoteCharacter = " ' \\ '' "
63+ #endif
64+ // If there are no quote characters then we can just wrap the string within the quotes.
65+ guard let quotePos = utf8 [ pos... ] . firstIndex ( of: quoteCharacter. asciiValue!) else {
66+ return String ( quoteCharacter) + self + String( quoteCharacter)
5567 }
5668
5769 // Otherwise iterate and escape all the single quotes.
58- var newString = " ' " + String( self [ ..< singleQuotePos ] )
70+ var newString = String ( quoteCharacter ) + String( self [ ..< quotePos ] )
5971
60- for char in self [ singleQuotePos ... ] {
61- if char == " ' " {
62- newString += " ' \\ '' "
72+ for char in self [ quotePos ... ] {
73+ if char == quoteCharacter {
74+ newString += escapedQuoteCharacter
6375 } else {
6476 newString += String ( char)
6577 }
6678 }
6779
68- newString += " ' "
80+ newString += String ( quoteCharacter )
6981
7082 return newString
7183 }
0 commit comments