aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Pan <panjf2000@gmail.com>2021-06-23 12:59:48 +0800
committerEmmanuel Odeke <emmanuel@orijtech.com>2021-06-24 03:20:33 +0000
commit86d72fa2cba51342ba5617abf43a732f9fd668ca (patch)
tree162035b048cc8c1b60cc8bfa6a894d8cc337a642
parent44a12e5f33bed2189735d8466b38fe455fe9b752 (diff)
downloadgo-86d72fa2cba51342ba5617abf43a732f9fd668ca.tar.gz
go-86d72fa2cba51342ba5617abf43a732f9fd668ca.zip
time: handle invalid UTF-8 byte sequences in quote to prevent panic
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>
-rw-r--r--src/time/format.go18
-rw-r--r--src/time/time_test.go5
2 files changed, 20 insertions, 3 deletions
diff --git a/src/time/format.go b/src/time/format.go
index 6040ed5aeb..bb173a21c2 100644
--- a/src/time/format.go
+++ b/src/time/format.go
@@ -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])
diff --git a/src/time/time_test.go b/src/time/time_test.go
index f272bbd558..cea5f2d3f5 100644
--- a/src/time/time_test.go
+++ b/src/time/time_test.go
@@ -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"`},