diff options
author | Colin Cross <ccross@android.com> | 2018-09-19 16:05:43 -0700 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2018-09-19 16:17:10 -0700 |
commit | cc1ec0fedc0e74183891973c327d21201734c585 (patch) | |
tree | bd035ec59d0845e95b0df9cada2fe9a87ce52bdd | |
parent | 0799fad550029be4109db6d81189edf20eb720c7 (diff) | |
download | android_build_blueprint-cc1ec0fedc0e74183891973c327d21201734c585.tar.gz android_build_blueprint-cc1ec0fedc0e74183891973c327d21201734c585.tar.bz2 android_build_blueprint-cc1ec0fedc0e74183891973c327d21201734c585.zip |
Replace *Escape with *EscapeList
NinjaEscape and ShellEscape operated on lists, which led to
awkward NinjaEscape([]string{s})[0]. Replace NinjaEscape
and ShellEscape with NinjaEscapeList and ShellEscapeList,
and add new NinjaEscape and ShellEscape functions that
operate on a string.
Test: m checkbuild
Change-Id: I283d92cdddc8e0066a300015863a3eab66f77c23
-rw-r--r-- | proptools/escape.go | 57 | ||||
-rw-r--r-- | proptools/escape_test.go | 6 |
2 files changed, 42 insertions, 21 deletions
diff --git a/proptools/escape.go b/proptools/escape.go index 1cd9feb..e7f0456 100644 --- a/proptools/escape.go +++ b/proptools/escape.go @@ -16,28 +16,51 @@ package proptools import "strings" -// NinjaEscape takes a slice of strings that may contain characters that are meaningful to ninja +// NinjaEscapeList takes a slice of strings that may contain characters that are meaningful to ninja // ($), and escapes each string so they will be passed to bash. It is not necessary on input, // output, or dependency names, those are handled by ModuleContext.Build. It is generally required // on strings from properties in Blueprint files that are used as Args to ModuleContext.Build. A // new slice containing the escaped strings is returned. -func NinjaEscape(slice []string) []string { +func NinjaEscapeList(slice []string) []string { slice = append([]string(nil), slice...) for i, s := range slice { - slice[i] = ninjaEscaper.Replace(s) + slice[i] = NinjaEscape(s) } return slice } +// NinjaEscapeList takes a string that may contain characters that are meaningful to ninja +// ($), and escapes it so it will be passed to bash. It is not necessary on input, +// output, or dependency names, those are handled by ModuleContext.Build. It is generally required +// on strings from properties in Blueprint files that are used as Args to ModuleContext.Build. A +// new slice containing the escaped strings is returned. +func NinjaEscape(s string) string { + return ninjaEscaper.Replace(s) +} + var ninjaEscaper = strings.NewReplacer( "$", "$$") -// ShellEscape takes a slice of strings that may contain characters that are meaningful to bash and -// escapes if necessary by wrapping them in single quotes, and replacing internal single quotes with +// ShellEscapeList takes a slice of strings that may contain characters that are meaningful to bash and +// escapes them if necessary by wrapping them in single quotes, and replacing internal single quotes with // '\'' (one single quote to end the quoting, a shell-escaped single quote to insert a real single // quote, and then a single quote to restarting quoting. A new slice containing the escaped strings // is returned. -func ShellEscape(slice []string) []string { +func ShellEscapeList(slice []string) []string { + slice = append([]string(nil), slice...) + + for i, s := range slice { + slice[i] = ShellEscape(s) + } + return slice + +} + +// ShellEscapeList takes string that may contain characters that are meaningful to bash and +// escapes it if necessary by wrapping it in single quotes, and replacing internal single quotes with +// '\'' (one single quote to end the quoting, a shell-escaped single quote to insert a real single +// quote, and then a single quote to restarting quoting. +func ShellEscape(s string) string { shellUnsafeChar := func(r rune) bool { switch { case 'A' <= r && r <= 'Z', @@ -57,22 +80,20 @@ func ShellEscape(slice []string) []string { } } - slice = append([]string(nil), slice...) - - for i, s := range slice { - if strings.IndexFunc(s, shellUnsafeChar) == -1 { - // No escaping necessary - continue - } - - slice[i] = `'` + singleQuoteReplacer.Replace(s) + `'` + if strings.IndexFunc(s, shellUnsafeChar) == -1 { + // No escaping necessary + return s } - return slice + return `'` + singleQuoteReplacer.Replace(s) + `'` +} + +func NinjaAndShellEscapeList(slice []string) []string { + return ShellEscapeList(NinjaEscapeList(slice)) } -func NinjaAndShellEscape(slice []string) []string { - return ShellEscape(NinjaEscape(slice)) +func NinjaAndShellEscape(s string) string { + return ShellEscape(NinjaEscape(s)) } var singleQuoteReplacer = strings.NewReplacer(`'`, `'\''`) diff --git a/proptools/escape_test.go b/proptools/escape_test.go index f65b9b0..633d711 100644 --- a/proptools/escape_test.go +++ b/proptools/escape_test.go @@ -93,7 +93,7 @@ var shellEscapeTestCase = []escapeTestCase{ func TestNinjaEscaping(t *testing.T) { for _, testCase := range ninjaEscapeTestCase { - got := NinjaEscape([]string{testCase.in})[0] + got := NinjaEscape(testCase.in) if got != testCase.out { t.Errorf("%s: expected `%s` got `%s`", testCase.name, testCase.out, got) } @@ -102,7 +102,7 @@ func TestNinjaEscaping(t *testing.T) { func TestShellEscaping(t *testing.T) { for _, testCase := range shellEscapeTestCase { - got := ShellEscape([]string{testCase.in})[0] + got := ShellEscape(testCase.in) if got != testCase.out { t.Errorf("%s: expected `%s` got `%s`", testCase.name, testCase.out, got) } @@ -114,7 +114,7 @@ func TestExternalShellEscaping(t *testing.T) { return } for _, testCase := range shellEscapeTestCase { - cmd := "echo -n " + ShellEscape([]string{testCase.in})[0] + cmd := "echo -n " + ShellEscape(testCase.in) got, err := exec.Command("/bin/sh", "-c", cmd).Output() if err != nil { t.Error(err) |