]> Cypherpunks.ru repositories - gostls13.git/commitdiff
strconv: detect invalid UTF-8 in the Unquote fast path
authorBrad Fitzpatrick <bradfitz@golang.org>
Wed, 7 Feb 2018 04:28:49 +0000 (04:28 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 13 Feb 2018 18:33:44 +0000 (18:33 +0000)
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>

src/strconv/quote.go
src/strconv/quote_test.go

index 156a510d213b274cb6487e62c6b3ba9b4243db42..d514b5f552795e3d0d66fa8574ab59054b023ddb 100644 (file)
@@ -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) {
index a4b5804fc89c9ca1cfdf49e10a990a71a0c2a1e4..cdc9aafd559e04e8da15762dfdcf02c5b2cecae2 100644 (file)
@@ -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."`)