Browse Source

Avoid integer overflow in Date.setMilliseconds()

Dmitry Panov 6 years ago
parent
commit
cf1b11d287
2 changed files with 13 additions and 8 deletions
  1. 8 7
      builtin_date.go
  2. 5 1
      date_test.go

+ 8 - 7
builtin_date.go

@@ -531,9 +531,10 @@ func (r *Runtime) dateproto_setMilliseconds(call FunctionCall) Value {
 	obj := r.toObject(call.This)
 	if d, ok := obj.self.(*dateObject); ok {
 		if d.isSet {
-			msec := int(call.Argument(0).ToInteger())
-			d.time = time.Date(d.time.Year(), d.time.Month(), d.time.Day(), d.time.Hour(), d.time.Minute(), d.time.Second(), msec*1e6, time.Local)
-			return intToValue(timeToMsec(d.time))
+			msec := call.Argument(0).ToInteger()
+			m := timeToMsec(d.time) - int64(d.time.Nanosecond())/1e6 + msec
+			d.time = timeFromMsec(m)
+			return intToValue(m)
 		} else {
 			return _NaN
 		}
@@ -546,10 +547,10 @@ func (r *Runtime) dateproto_setUTCMilliseconds(call FunctionCall) Value {
 	obj := r.toObject(call.This)
 	if d, ok := obj.self.(*dateObject); ok {
 		if d.isSet {
-			msec := int(call.Argument(0).ToInteger())
-			t := d.time.In(time.UTC)
-			d.time = time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), msec*1e6, time.UTC).In(time.Local)
-			return intToValue(timeToMsec(d.time))
+			msec := call.Argument(0).ToInteger()
+			m := timeToMsec(d.time) - int64(d.time.Nanosecond())/1e6 + msec
+			d.time = timeFromMsec(m)
+			return intToValue(m)
 		} else {
 			return _NaN
 		}

+ 5 - 1
date_test.go

@@ -186,7 +186,8 @@ func TestDateValueOf(t *testing.T) {
 
 func TestDateSetters(t *testing.T) {
 	const SCRIPT = `
-	assert.sameValue((new Date(0)).setMilliseconds(2345), 2345, "setMilliseconds()");
+	assert.sameValue((new Date(0)).setMilliseconds(2345), 2345, "setMilliseconds(2345)");
+	assert.sameValue(new Date(1000).setMilliseconds(23450000000000), 23450000001000, "setMilliseconds(23450000000000)");
 	assert.sameValue((new Date(0)).setUTCMilliseconds(2345), 2345, "setUTCMilliseconds()");
 	assert.sameValue((new Date(0)).setSeconds(12), 12000, "setSeconds()");
 	assert.sameValue((new Date(0)).setUTCSeconds(12), 12000, "setUTCSeconds()");
@@ -203,6 +204,9 @@ func TestDateSetters(t *testing.T) {
 	assert.sameValue((new Date(0)).setUTCFullYear(1971), 31536000000, "setUTCFullYear()");
 	assert.sameValue((new Date(0)).setUTCFullYear(1971, 2, 3), 36806400000, "setUTCFullYear(Y,M,D)");
 
+	var d = new Date();
+	d.setTime(1151877845000);
+	assert.sameValue(d.getHours(), 23, "d.getHours()");
 	`
 
 	l := time.Local