github.com/nilium/gitlab-runner@v12.5.0+incompatible/helpers/shell_escape.go (about) 1 package helpers 2 3 // https://github.com/zimbatm/direnv/blob/master/shell.go 4 5 import ( 6 "bytes" 7 "encoding/hex" 8 "strings" 9 ) 10 11 /* 12 * Escaping 13 */ 14 15 const ( 16 ACK = 6 17 TAB = 9 18 LF = 10 19 CR = 13 20 US = 31 21 SPACE = 32 22 AMPERSTAND = 38 23 SINGLE_QUOTE = 39 24 PLUS = 43 25 NINE = 57 26 QUESTION = 63 27 LOWERCASE_Z = 90 28 OPEN_BRACKET = 91 29 BACKSLASH = 92 30 UNDERSCORE = 95 31 CLOSE_BRACKET = 93 32 BACKTICK = 96 33 TILDA = 126 34 DEL = 127 35 ) 36 37 // ShellEscape is taken from https://github.com/solidsnack/shell-escape/blob/master/Text/ShellEscape/Bash.hs 38 /* 39 A Bash escaped string. The strings are wrapped in @$\'...\'@ if any 40 bytes within them must be escaped; otherwise, they are left as is. 41 Newlines and other control characters are represented as ANSI escape 42 sequences. High bytes are represented as hex codes. Thus Bash escaped 43 strings will always fit on one line and never contain non-ASCII bytes. 44 */ 45 func ShellEscape(str string) string { 46 if str == "" { 47 return "''" 48 } 49 in := []byte(str) 50 out := bytes.NewBuffer(make([]byte, 0, len(str)*2)) 51 i := 0 52 l := len(in) 53 escape := false 54 55 hex := func(char byte) { 56 escape = true 57 58 data := []byte{BACKSLASH, 'x', 0, 0} 59 hex.Encode(data[2:], []byte{char}) 60 out.Write(data) 61 } 62 63 backslash := func(char byte) { 64 escape = true 65 out.Write([]byte{BACKSLASH, char}) 66 } 67 68 escaped := func(str string) { 69 escape = true 70 out.WriteString(str) 71 } 72 73 quoted := func(char byte) { 74 escape = true 75 out.WriteByte(char) 76 } 77 78 literal := func(char byte) { 79 out.WriteByte(char) 80 } 81 82 for i < l { 83 char := in[i] 84 switch { 85 case char == TAB: 86 escaped(`\t`) 87 case char == LF: 88 escaped(`\n`) 89 case char == CR: 90 escaped(`\r`) 91 case char <= US: 92 hex(char) 93 case char <= AMPERSTAND: 94 quoted(char) 95 case char == SINGLE_QUOTE: 96 backslash(char) 97 case char <= PLUS: 98 quoted(char) 99 case char <= NINE: 100 literal(char) 101 case char <= QUESTION: 102 quoted(char) 103 case char <= LOWERCASE_Z: 104 literal(char) 105 case char == OPEN_BRACKET: 106 quoted(char) 107 case char == BACKSLASH: 108 backslash(char) 109 case char <= CLOSE_BRACKET: 110 quoted(char) 111 case char == UNDERSCORE: 112 literal(char) 113 case char <= BACKTICK: 114 quoted(char) 115 case char <= TILDA: 116 quoted(char) 117 case char == DEL: 118 hex(char) 119 default: 120 hex(char) 121 } 122 i++ 123 } 124 125 outStr := out.String() 126 127 if escape { 128 outStr = "$'" + outStr + "'" 129 } 130 131 return outStr 132 } 133 134 func ToBackslash(path string) string { 135 return strings.Replace(path, "/", "\\", -1) 136 } 137 138 func ToSlash(path string) string { 139 return strings.Replace(path, "\\", "/", -1) 140 }