]> Cypherpunks repositories - gostls13.git/commitdiff
time: handle invalid UTF-8 byte sequences in quote to prevent panic
authorAndy Pan <panjf2000@gmail.com>
Wed, 23 Jun 2021 04:59:48 +0000 (12:59 +0800)
committerEmmanuel Odeke <emmanuel@orijtech.com>
Thu, 24 Jun 2021 03:20:33 +0000 (03:20 +0000)
Fixes #46883
Updates CL 267017

Change-Id: I15c307bfb0aaa2877a148d32527681f79df1a650
Reviewed-on: https://go-review.googlesource.com/c/go/+/330289
Reviewed-by: Kevin Burke <kev@inburke.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Emmanuel Odeke <emmanuel@orijtech.com>

src/time/format.go
src/time/time_test.go

index 6040ed5aebc9d07ed90647dae7f45e10e139552d..bb173a21c2d4584f7b9015eb1c832ba7d63d86dc 100644 (file)
@@ -751,8 +751,11 @@ type ParseError struct {
 
 // These are borrowed from unicode/utf8 and strconv and replicate behavior in
 // that package, since we can't take a dependency on either.
-const runeSelf = 0x80
-const lowerhex = "0123456789abcdef"
+const (
+       lowerhex  = "0123456789abcdef"
+       runeSelf  = 0x80
+       runeError = '\uFFFD'
+)
 
 func quote(s string) string {
        buf := make([]byte, 1, len(s)+2) // slice will be at least len(s) + quotes
@@ -765,7 +768,16 @@ func quote(s string) string {
                        // reproduce strconv.Quote's behavior with full fidelity but
                        // given how rarely we expect to hit these edge cases, speed and
                        // conciseness are better.
-                       for j := 0; j < len(string(c)) && j < len(s); j++ {
+                       var width int
+                       if c == runeError {
+                               width = 1
+                               if i+2 < len(s) && s[i:i+3] == string(runeError) {
+                                       width = 3
+                               }
+                       } else {
+                               width = len(string(c))
+                       }
+                       for j := 0; j < width; j++ {
                                buf = append(buf, `\x`...)
                                buf = append(buf, lowerhex[s[i+j]>>4])
                                buf = append(buf, lowerhex[s[i+j]&0xF])
index f272bbd5587734128435e1c7fc7f22c1a457b8ea..cea5f2d3f5acebcd18214e0167bf6a2a8de9f5d7 100644 (file)
@@ -917,6 +917,11 @@ var parseDurationErrorTests = []struct {
        {".s", `".s"`},
        {"+.s", `"+.s"`},
        {"1d", `"1d"`},
+       {"\x85\x85", `"\x85\x85"`},
+       {"\xffff", `"\xffff"`},
+       {"hello \xffff world", `"hello \xffff world"`},
+       {"\uFFFD", `"\xef\xbf\xbd"`},                                             // utf8.RuneError
+       {"\uFFFD hello \uFFFD world", `"\xef\xbf\xbd hello \xef\xbf\xbd world"`}, // utf8.RuneError
        // overflow
        {"9223372036854775810ns", `"9223372036854775810ns"`},
        {"9223372036854775808ns", `"9223372036854775808ns"`},