summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2018-02-07 04:28:49 +0000
committerBrad Fitzpatrick <bradfitz@golang.org>2018-02-13 18:33:44 +0000
commitc10e61424f9c17c2972a438287ff9ac90d6b55a4 (patch)
tree6cc9244ae406d27288330a57b23dd85d9d613ba7
parent5412c0c17e5d51ff94b37e5c397601f07912bb96 (diff)
downloadgo-git-c10e61424f9c17c2972a438287ff9ac90d6b55a4.tar.gz
strconv: detect invalid UTF-8 in the Unquote fast path
Fixes #23685 Change-Id: I3625bd01f860077ee0976df9e3dfb66754804bcd Reviewed-on: https://go-review.googlesource.com/92535 Reviewed-by: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-rw-r--r--src/strconv/quote.go4
-rw-r--r--src/strconv/quote_test.go30
2 files changed, 33 insertions, 1 deletions
diff --git a/src/strconv/quote.go b/src/strconv/quote.go
index 156a510d21..d514b5f552 100644
--- a/src/strconv/quote.go
+++ b/src/strconv/quote.go
@@ -385,7 +385,9 @@ func Unquote(s string) (string, error) {
if !contains(s, '\\') && !contains(s, quote) {
switch quote {
case '"':
- return s, nil
+ if utf8.ValidString(s) {
+ return s, nil
+ }
case '\'':
r, size := utf8.DecodeRuneInString(s)
if size == len(s) && (r != utf8.RuneError || size != 1) {
diff --git a/src/strconv/quote_test.go b/src/strconv/quote_test.go
index a4b5804fc8..cdc9aafd55 100644
--- a/src/strconv/quote_test.go
+++ b/src/strconv/quote_test.go
@@ -326,6 +326,36 @@ func TestUnquote(t *testing.T) {
}
}
+// Issue 23685: invalid UTF-8 should not go through the fast path.
+func TestUnquoteInvalidUTF8(t *testing.T) {
+ tests := []struct {
+ in string
+
+ // one of:
+ want string
+ wantErr string
+ }{
+ {in: `"foo"`, want: "foo"},
+ {in: `"foo`, wantErr: "invalid syntax"},
+ {in: `"` + "\xc0" + `"`, want: "\xef\xbf\xbd"},
+ {in: `"a` + "\xc0" + `"`, want: "a\xef\xbf\xbd"},
+ {in: `"\t` + "\xc0" + `"`, want: "\t\xef\xbf\xbd"},
+ }
+ for i, tt := range tests {
+ got, err := Unquote(tt.in)
+ var gotErr string
+ if err != nil {
+ gotErr = err.Error()
+ }
+ if gotErr != tt.wantErr {
+ t.Errorf("%d. Unquote(%q) = err %v; want %q", i, tt.in, err, tt.wantErr)
+ }
+ if tt.wantErr == "" && err == nil && got != tt.want {
+ t.Errorf("%d. Unquote(%q) = %02x; want %02x", i, tt.in, []byte(got), []byte(tt.want))
+ }
+ }
+}
+
func BenchmarkUnquoteEasy(b *testing.B) {
for i := 0; i < b.N; i++ {
Unquote(`"Give me a rock, paper and scissors and I will move the world."`)