]> Cypherpunks repositories - gostls13.git/commitdiff
time: check int64 overflow in Time.addSec
authorAndy Pan <panjf2000@gmail.com>
Fri, 12 Mar 2021 11:40:46 +0000 (19:40 +0800)
committerIan Lance Taylor <iant@golang.org>
Wed, 17 Mar 2021 19:48:52 +0000 (19:48 +0000)
Change-Id: Ibbed54239228e7ea31ef5978d427425899c3b943
Reviewed-on: https://go-review.googlesource.com/c/go/+/300890
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Trust: Baokun Lee <bk@golangcn.org>

src/time/export_test.go
src/time/internal_test.go
src/time/time.go
src/time/time_test.go

index f4a8cd9b72af6842fa3744728deb0123fbbdcddb..0f2d21053a3489e6383d71c31ee1c115a978fc66 100644 (file)
@@ -51,6 +51,7 @@ const (
        RuleJulian       = RuleKind(ruleJulian)
        RuleDOY          = RuleKind(ruleDOY)
        RuleMonthWeekDay = RuleKind(ruleMonthWeekDay)
+       UnixToInternal   = unixToInternal
 )
 
 type Rule struct {
index ffe54e47c2de530ae10e6724a676fe3c6a704f39..87a4208b058e1bd77e395374e1063e484d02d9a8 100644 (file)
@@ -62,4 +62,6 @@ func CheckRuntimeTimerPeriodOverflow() {
 var (
        MinMonoTime = Time{wall: 1 << 63, ext: -1 << 63, loc: UTC}
        MaxMonoTime = Time{wall: 1 << 63, ext: 1<<63 - 1, loc: UTC}
+
+       NotMonoNegativeTime = Time{wall: 0, ext: -1<<63 + 50}
 )
index 7e5192a0c97d172e6ec317bc82bfa8206ef08524..841f989293c7f227e6e3f64b9f3630306ef6d6e1 100644 (file)
@@ -189,8 +189,15 @@ func (t *Time) addSec(d int64) {
                t.stripMono()
        }
 
-       // TODO: Check for overflow.
-       t.ext += d
+       // Check if the sum of t.ext and d overflows and handle it properly.
+       sum := t.ext + d
+       if (sum > t.ext) == (d > 0) {
+               t.ext = sum
+       } else if d > 0 {
+               t.ext = 1<<63 - 1
+       } else {
+               t.ext = -(1<<63 - 1)
+       }
 }
 
 // setLoc sets the location associated with the time.
index 8884731e1d0ed9de35b2a568ddfb16969e709f17..3a58bfe4e94a0b49759ea09254e3c7d29b1997a7 100644 (file)
@@ -1481,7 +1481,7 @@ func TestTimeIsDST(t *testing.T) {
        tzFixed := FixedZone("FIXED_TIME", 12345)
 
        tests := [...]struct {
-               time   Time
+               time Time
                want bool
        }{
                0: {Date(2009, 1, 1, 12, 0, 0, 0, UTC), false},
@@ -1501,3 +1501,28 @@ func TestTimeIsDST(t *testing.T) {
                }
        }
 }
+
+func TestTimeAddSecOverflow(t *testing.T) {
+       // Test it with positive delta.
+       var maxInt64 int64 = 1<<63 - 1
+       timeExt := maxInt64 - UnixToInternal - 50
+       notMonoTime := Unix(timeExt, 0)
+       for i := int64(0); i < 100; i++ {
+               sec := notMonoTime.Unix()
+               notMonoTime = notMonoTime.Add(Duration(i * 1e9))
+               if newSec := notMonoTime.Unix(); newSec != sec+i && newSec+UnixToInternal != maxInt64 {
+                       t.Fatalf("time ext: %d overflows with positive delta, overflow threshold: %d", newSec, maxInt64)
+               }
+       }
+
+       // Test it with negative delta.
+       maxInt64 = -maxInt64
+       notMonoTime = NotMonoNegativeTime
+       for i := int64(0); i > -100; i-- {
+               sec := notMonoTime.Unix()
+               notMonoTime = notMonoTime.Add(Duration(i * 1e9))
+               if newSec := notMonoTime.Unix(); newSec != sec+i && newSec+UnixToInternal != maxInt64 {
+                       t.Fatalf("time ext: %d overflows with positive delta, overflow threshold: %d", newSec, maxInt64)
+               }
+       }
+}