github.com/alloyci/alloy-runner@v1.0.1-0.20180222164613-925503ccafd6/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 <= LOWERCASE_Z: 116 literal(char) 117 case char <= TILDA: 118 quoted(char) 119 case char == DEL: 120 hex(char) 121 default: 122 hex(char) 123 } 124 i++ 125 } 126 127 outStr := out.String() 128 129 if escape { 130 outStr = "$'" + outStr + "'" 131 } 132 133 return outStr 134 } 135 136 func ToBackslash(path string) string { 137 return strings.Replace(path, "/", "\\", -1) 138 } 139 140 func ToSlash(path string) string { 141 return strings.Replace(path, "\\", "/", -1) 142 }