8013337: Issues with Date.prototype's get, set functions

Reviewed-by: jlaskey, hannesw, lagergren
This commit is contained in:
Athijegannathan Sundararajan 2013-04-26 18:31:42 +05:30
parent 806256d657
commit b165a1a882
3 changed files with 114 additions and 42 deletions

View File

@ -519,7 +519,7 @@ public final class NativeDate extends ScriptObject {
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object getTimezoneOffset(final Object self) {
final NativeDate nd = getNativeDate(self);
if (nd != null) {
if (nd != null && nd.isValidDate()) {
final long msec = (long) nd.getTime();
return - nd.getTimeZone().getOffset(msec) / msPerMinute;
}
@ -535,8 +535,8 @@ public final class NativeDate extends ScriptObject {
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object setTime(final Object self, final Object time) {
final double num = timeClip(JSType.toNumber(time));
final NativeDate nd = getNativeDate(self);
final double num = timeClip(JSType.toNumber(time));
nd.setTime(num);
return num;
}
@ -551,9 +551,7 @@ public final class NativeDate extends ScriptObject {
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object setMilliseconds(final Object self, final Object... args) {
final NativeDate nd = getNativeDate(self);
if (nd.isValidDate()) {
setFields(nd, MILLISECOND, args, true);
}
setFields(nd, MILLISECOND, args, true);
return nd.getTime();
}
@ -567,9 +565,7 @@ public final class NativeDate extends ScriptObject {
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object setUTCMilliseconds(final Object self, final Object... args) {
final NativeDate nd = getNativeDate(self);
if (nd.isValidDate()) {
setFields(nd, MILLISECOND, args, false);
}
setFields(nd, MILLISECOND, args, false);
return nd.getTime();
}
@ -583,9 +579,7 @@ public final class NativeDate extends ScriptObject {
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
public static Object setSeconds(final Object self, final Object... args) {
final NativeDate nd = getNativeDate(self);
if (nd.isValidDate()) {
setFields(nd, SECOND, args, true);
}
setFields(nd, SECOND, args, true);
return nd.getTime();
}
@ -599,9 +593,7 @@ public final class NativeDate extends ScriptObject {
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
public static Object setUTCSeconds(final Object self, final Object... args) {
final NativeDate nd = getNativeDate(self);
if (nd.isValidDate()) {
setFields(nd, SECOND, args, false);
}
setFields(nd, SECOND, args, false);
return nd.getTime();
}
@ -615,9 +607,7 @@ public final class NativeDate extends ScriptObject {
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 3)
public static Object setMinutes(final Object self, final Object... args) {
final NativeDate nd = getNativeDate(self);
if (nd.isValidDate()) {
setFields(nd, MINUTE, args, true);
}
setFields(nd, MINUTE, args, true);
return nd.getTime();
}
@ -631,9 +621,7 @@ public final class NativeDate extends ScriptObject {
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 3)
public static Object setUTCMinutes(final Object self, final Object... args) {
final NativeDate nd = getNativeDate(self);
if (nd.isValidDate()) {
setFields(nd, MINUTE, args, false);
}
setFields(nd, MINUTE, args, false);
return nd.getTime();
}
@ -647,9 +635,7 @@ public final class NativeDate extends ScriptObject {
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 4)
public static Object setHours(final Object self, final Object... args) {
final NativeDate nd = getNativeDate(self);
if (nd.isValidDate()) {
setFields(nd, HOUR, args, true);
}
setFields(nd, HOUR, args, true);
return nd.getTime();
}
@ -663,9 +649,7 @@ public final class NativeDate extends ScriptObject {
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 4)
public static Object setUTCHours(final Object self, final Object... args) {
final NativeDate nd = getNativeDate(self);
if (nd.isValidDate()) {
setFields(nd, HOUR, args, false);
}
setFields(nd, HOUR, args, false);
return nd.getTime();
}
@ -679,9 +663,7 @@ public final class NativeDate extends ScriptObject {
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object setDate(final Object self, final Object... args) {
final NativeDate nd = getNativeDate(self);
if (nd.isValidDate()) {
setFields(nd, DAY, args, true);
}
setFields(nd, DAY, args, true);
return nd.getTime();
}
@ -695,9 +677,7 @@ public final class NativeDate extends ScriptObject {
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object setUTCDate(final Object self, final Object... args) {
final NativeDate nd = getNativeDate(self);
if (nd.isValidDate()) {
setFields(nd, DAY, args, false);
}
setFields(nd, DAY, args, false);
return nd.getTime();
}
@ -711,9 +691,7 @@ public final class NativeDate extends ScriptObject {
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
public static Object setMonth(final Object self, final Object... args) {
final NativeDate nd = getNativeDate(self);
if (nd.isValidDate()) {
setFields(nd, MONTH, args, true);
}
setFields(nd, MONTH, args, true);
return nd.getTime();
}
@ -727,9 +705,7 @@ public final class NativeDate extends ScriptObject {
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
public static Object setUTCMonth(final Object self, final Object... args) {
final NativeDate nd = ensureNativeDate(self);
if (nd.isValidDate()) {
setFields(nd, MONTH, args, false);
}
setFields(nd, MONTH, args, false);
return nd.getTime();
}
@ -747,7 +723,11 @@ public final class NativeDate extends ScriptObject {
setFields(nd, YEAR, args, true);
} else {
final double[] d = convertArgs(args, 0, YEAR, YEAR, 3);
nd.setTime(timeClip(utc(makeDate(makeDay(d[0], d[1], d[2]), 0), nd.getTimeZone())));
if (d != null) {
nd.setTime(timeClip(utc(makeDate(makeDay(d[0], d[1], d[2]), 0), nd.getTimeZone())));
} else {
nd.setTime(NaN);
}
}
return nd.getTime();
}
@ -782,13 +762,13 @@ public final class NativeDate extends ScriptObject {
public static Object setYear(final Object self, final Object year) {
final NativeDate nd = getNativeDate(self);
if (isNaN(nd.getTime())) {
return null;
nd.setTime(utc(0, nd.getTimeZone()));
}
final double yearNum = JSType.toNumber(year);
if (isNaN(yearNum)) {
nd.setTime(NaN);
return nd;
return nd.getTime();
}
int yearInt = JSType.toInteger(yearNum);
if (0 <= yearInt && yearInt <= 99) {
@ -796,7 +776,7 @@ public final class NativeDate extends ScriptObject {
}
setFields(nd, YEAR, new Object[] {yearInt}, true);
return nd;
return nd.getTime();
}
/**
@ -1298,6 +1278,10 @@ public final class NativeDate extends ScriptObject {
final double time = local ? nd.getLocalTime() : nd.getTime();
final double d[] = convertArgs(args, time, fieldId, start, length);
if (! nd.isValidDate()) {
return;
}
double newTime;
if (d == null) {
newTime = NaN;

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8013337: Issues with Date.prototype's get, set functions
*
* @test
* @option -timezone=Asia/Calcutta
* @run
*/
function check(str) {
print(str + " = " + eval(str));
}
check('new Date(NaN).setFullYear(NaN)');
check('new Date(0).setYear(70)');
check('new Date(0).setYear(NaN)');
check('new Date(NaN).setYear(70)');
check('new Date(NaN).getTimezoneOffset()');
function checkGetterCalled(func) {
var getterCalled = false;
new Date(NaN)[func]( { valueOf: function() { getterCalled = true } } );
if (getterCalled) {
print("Date.prototype." + func + " calls valueOf on arg");
}
}
checkGetterCalled("setMilliseconds");
checkGetterCalled("setUTCMilliseconds");
checkGetterCalled("setSeconds");
checkGetterCalled("setUTCSeconds");
checkGetterCalled("setMinutes");
checkGetterCalled("setUTCMinutes");
checkGetterCalled("setHours");
checkGetterCalled("setUTCHours");
checkGetterCalled("setDate");
checkGetterCalled("setUTCDate");
checkGetterCalled("setMonth");
checkGetterCalled("setUTCMonth");
try {
Date.prototype.setTime.call({}, { valueOf: function() { throw "err" } })
} catch (e) {
if (! (e instanceof TypeError)) {
fail("TypeError expected, got " + e);
}
}

View File

@ -0,0 +1,17 @@
new Date(NaN).setFullYear(NaN) = NaN
new Date(0).setYear(70) = 0
new Date(0).setYear(NaN) = NaN
new Date(NaN).setYear(70) = -19800000
new Date(NaN).getTimezoneOffset() = NaN
Date.prototype.setMilliseconds calls valueOf on arg
Date.prototype.setUTCMilliseconds calls valueOf on arg
Date.prototype.setSeconds calls valueOf on arg
Date.prototype.setUTCSeconds calls valueOf on arg
Date.prototype.setMinutes calls valueOf on arg
Date.prototype.setUTCMinutes calls valueOf on arg
Date.prototype.setHours calls valueOf on arg
Date.prototype.setUTCHours calls valueOf on arg
Date.prototype.setDate calls valueOf on arg
Date.prototype.setUTCDate calls valueOf on arg
Date.prototype.setMonth calls valueOf on arg
Date.prototype.setUTCMonth calls valueOf on arg