aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Yastrebov <yastrebov.alex@gmail.com>2021-10-03 15:45:38 +0000
committerIan Lance Taylor <iant@golang.org>2021-10-06 19:45:35 +0000
commite38ec96c69f826516a99f16952bd73c766f96719 (patch)
tree5e1e13626cdb51efc6de7a2a4d7f353e7c7534a0
parent39a4df49674540ba8b835ece03edb8d304941187 (diff)
downloadgo-e38ec96c69f826516a99f16952bd73c766f96719.tar.gz
go-e38ec96c69f826516a99f16952bd73c766f96719.zip
time: truncate fractional seconds longer than 9 digits
Fixes #48685 Change-Id: Id246708878c2902b407ab759537f6b545a1f459f GitHub-Last-Rev: 4d985192c5a66ae8891539f166ef88b53cd1cbea GitHub-Pull-Request: golang/go#48750 Reviewed-on: https://go-review.googlesource.com/c/go/+/353713 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com> Trust: Emmanuel Odeke <emmanuel@orijtech.com>
-rw-r--r--src/time/format.go9
-rw-r--r--src/time/format_test.go41
2 files changed, 47 insertions, 3 deletions
diff --git a/src/time/format.go b/src/time/format.go
index 7373892b97..464effdb43 100644
--- a/src/time/format.go
+++ b/src/time/format.go
@@ -1420,16 +1420,19 @@ func parseNanoseconds(value string, nbytes int) (ns int, rangeErrString string,
err = errBad
return
}
+ if nbytes > 10 {
+ value = value[:10]
+ nbytes = 10
+ }
if ns, err = atoi(value[1:nbytes]); err != nil {
return
}
- if ns < 0 || 1e9 <= ns {
+ if ns < 0 {
rangeErrString = "fractional second"
return
}
// We need nanoseconds, which means scaling by the number
- // of missing digits in the format, maximum length 10. If it's
- // longer than 10, we won't scale.
+ // of missing digits in the format, maximum length 10.
scaleDigits := 10 - nbytes
for i := 0; i < scaleDigits; i++ {
ns *= 10
diff --git a/src/time/format_test.go b/src/time/format_test.go
index 93cbcf9401..db95536390 100644
--- a/src/time/format_test.go
+++ b/src/time/format_test.go
@@ -852,3 +852,44 @@ func TestFormatFractionalSecondSeparators(t *testing.T) {
}
}
}
+
+// Issue 48685
+func TestParseFractionalSecondsLongerThanNineDigits(t *testing.T) {
+ tests := []struct {
+ s string
+ want int
+ }{
+ // 9 digits
+ {"2021-09-29T16:04:33.000000000Z", 0},
+ {"2021-09-29T16:04:33.000000001Z", 1},
+ {"2021-09-29T16:04:33.100000000Z", 100_000_000},
+ {"2021-09-29T16:04:33.100000001Z", 100_000_001},
+ {"2021-09-29T16:04:33.999999999Z", 999_999_999},
+ {"2021-09-29T16:04:33.012345678Z", 12_345_678},
+ // 10 digits, truncates
+ {"2021-09-29T16:04:33.0000000000Z", 0},
+ {"2021-09-29T16:04:33.0000000001Z", 0},
+ {"2021-09-29T16:04:33.1000000000Z", 100_000_000},
+ {"2021-09-29T16:04:33.1000000009Z", 100_000_000},
+ {"2021-09-29T16:04:33.9999999999Z", 999_999_999},
+ {"2021-09-29T16:04:33.0123456789Z", 12_345_678},
+ // 11 digits, truncates
+ {"2021-09-29T16:04:33.10000000000Z", 100_000_000},
+ {"2021-09-29T16:04:33.00123456789Z", 1_234_567},
+ // 12 digits, truncates
+ {"2021-09-29T16:04:33.000123456789Z", 123_456},
+ // 15 digits, truncates
+ {"2021-09-29T16:04:33.9999999999999999Z", 999_999_999},
+ }
+
+ for _, tt := range tests {
+ tm, err := Parse(RFC3339, tt.s)
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ continue
+ }
+ if got := tm.Nanosecond(); got != tt.want {
+ t.Errorf("Parse(%q) = got %d, want %d", tt.s, got, tt.want)
+ }
+ }
+}