diff options
author | Colin Cross <ccross@android.com> | 2019-03-04 10:22:01 -0800 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2019-03-04 10:22:01 -0800 |
commit | 34c5c48468e9c86c0eeccb0dacfdead88dbe1280 (patch) | |
tree | 51596eabf1da2ebf0948e2bb024c34f0129c3337 | |
parent | 8cb211b3cee8bb4907636d25fc026024546e5325 (diff) | |
parent | 2a80a36834c1b53dec5717bd3815dd1169a0f959 (diff) | |
download | blueprint-34c5c48468e9c86c0eeccb0dacfdead88dbe1280.tar.gz |
Merge remote-tracking branch 'aosp/upstream' into master
am: 2a80a36834
Change-Id: Icae8e6316a18cfb42da278008e77f8d5c86e42e3
-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) |