1
0
mirror of https://github.com/golang/go synced 2024-11-26 04:17:59 -07:00

time: check int64 overflow in Time.addSec

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>
This commit is contained in:
Andy Pan 2021-03-12 19:40:46 +08:00 committed by Ian Lance Taylor
parent 5423f6023c
commit a5df88355c
4 changed files with 38 additions and 3 deletions

View File

@ -51,6 +51,7 @@ const (
RuleJulian = RuleKind(ruleJulian)
RuleDOY = RuleKind(ruleDOY)
RuleMonthWeekDay = RuleKind(ruleMonthWeekDay)
UnixToInternal = unixToInternal
)
type Rule struct {

View 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}
)

View 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.

View 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)
}
}
}