-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathshell_escaper.go
More file actions
92 lines (84 loc) · 1.65 KB
/
shell_escaper.go
File metadata and controls
92 lines (84 loc) · 1.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package escapeshellchar
import "strings"
// EscapeShellString escapes the string so that it can be safely processed by split, etc
func EscapeShellString(s string) string {
s = strings.Replace(s, "\\", "\\\\", -1)
s = strings.Replace(s, " ", "\\ ", -1)
s = strings.Replace(s, "'", "\\'", -1)
s = strings.Replace(s, "$", "\\$", -1)
s = strings.Replace(s, "\"", "\\\"", -1)
s = strings.Replace(s, "<", "\\<", -1)
s = strings.Replace(s, ">", "\\>", -1)
s = strings.Replace(s, ";", "\\;", -1)
s = strings.Replace(s, "|", "\\|", -1)
hexCount := 0
for i := 0; i < len(s); i++ {
c := s[i]
if shouldEscape(c) {
hexCount++
}
}
t := make([]byte, len(s)+2*hexCount)
j := 0
for i := 0; i < len(s); i++ {
switch c := s[i]; {
case shouldEscape(c):
t[j] = '%'
t[j+1] = "0123456789ABCDEF"[c>>4]
t[j+2] = "0123456789ABCDEF"[c&15]
j += 3
default:
t[j] = s[i]
j++
}
}
return string(t)
}
// UnEscapeShellString unescapes a shell string
func UnEscapeShellString(s string) string {
n := 0
for i := 0; i < len(s); {
if s[i] == '%' {
n++
i += 3
} else {
i++
}
}
if n == 0 {
return s
}
t := make([]byte, len(s)-2*n)
j := 0
for i := 0; i < len(s); {
switch s[i] {
case '%':
t[j] = unhex(s[i+1])<<4 | unhex(s[i+2])
j++
i += 3
default:
t[j] = s[i]
j++
i++
}
}
return string(t)
}
func unhex(c byte) byte {
switch {
case '0' <= c && c <= '9':
return c - '0'
case 'a' <= c && c <= 'f':
return c - 'a' + 10
case 'A' <= c && c <= 'F':
return c - 'A' + 10
}
return 0
}
func shouldEscape(c byte) bool {
switch c {
case ' ', '\'', '|', '$', '&', ';', '<', '>', '%':
return true
}
return false
}