Skip to content

Commit

Permalink
Ensure NaN time values are correctly handled in various Date setters
Browse files Browse the repository at this point in the history
Related PR: tc39/ecma262#2136
  • Loading branch information
anba authored and ptomato committed Oct 11, 2024
1 parent 5ae7de9 commit 92b5925
Show file tree
Hide file tree
Showing 30 changed files with 1,162 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-date.prototype.setyear
description: >
Read [[DateValue]] and then call ToNumber when stored time-value is invalid.
info: |
Date.prototype.setYear ( year )
...
3. Let t be dateObject.[[DateValue]].
4. Let y be ? ToNumber(year).
5. If t is NaN, set t to +0𝔽; otherwise, set t to LocalTime(t).
6. Let yyyy be MakeFullYear(y).
...
---*/

var dt = new Date(NaN);

var valueOfCalled = 0;

var value = {
valueOf() {
valueOfCalled++;
dt.setTime(0);
return 1;
}
};

var result = dt.setYear(value);

assert.sameValue(valueOfCalled, 1, "valueOf called exactly once");

assert.notSameValue(result, NaN, "result is not NaN");

assert.sameValue(result, dt.getTime(), "result is equal to getTime");

assert.sameValue(dt.getYear(), 1, "date value correctly updated");
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-date.prototype.setyear
description: >
Read [[DateValue]] and then call ToNumber when stored time-value is valid.
info: |
Date.prototype.setYear ( year )
...
3. Let t be dateObject.[[DateValue]].
4. Let y be ? ToNumber(year).
5. If t is NaN, set t to +0𝔽; otherwise, set t to LocalTime(t).
6. Let yyyy be MakeFullYear(y).
...
---*/

var dt = new Date(0);

var valueOfCalled = 0;

var value = {
valueOf() {
valueOfCalled++;
dt.setTime(NaN);
return 1;
}
};

var result = dt.setYear(value);

assert.sameValue(valueOfCalled, 1, "valueOf called exactly once");

assert.notSameValue(result, NaN, "result is not NaN");

assert.sameValue(result, dt.getTime(), "result is equal to getTime");

assert.sameValue(dt.getYear(), 1, "date value correctly updated");
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-date.prototype.setdate
description: >
Read [[DateValue]] and then call ToNumber when stored time-value is invalid.
info: |
Date.prototype.setDate ( date )
...
3. Let t be dateObject.[[DateValue]].
4. Let dt be ? ToNumber(date).
5. If t is NaN, return NaN.
...
---*/

var dt = new Date(NaN);

var valueOfCalled = 0;

var value = {
valueOf() {
valueOfCalled++;
dt.setTime(0);
return 1;
}
};

var result = dt.setDate(value);

assert.sameValue(valueOfCalled, 1, "valueOf called exactly once");

assert.sameValue(result, NaN, "result is NaN");

assert.sameValue(dt.getTime(), 0, "time updated in valueOf");
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-date.prototype.setdate
description: >
Read [[DateValue]] and then call ToNumber when stored time-value is valid.
info: |
Date.prototype.setDate ( date )
...
3. Let t be dateObject.[[DateValue]].
4. Let dt be ? ToNumber(date).
5. If t is NaN, return NaN.
6. Set t to LocalTime(t).
...
---*/

var dt = new Date(0);

var valueOfCalled = 0;

var value = {
valueOf() {
valueOfCalled++;
dt.setTime(NaN);
return 1;
}
};

var result = dt.setDate(value);

assert.sameValue(valueOfCalled, 1, "valueOf called exactly once");

assert.notSameValue(result, NaN, "result is not NaN");

assert.sameValue(result, dt.getTime(), "result is equal to getTime");

assert.sameValue(dt.getDate(), 1, "date value correctly updated");
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-date.prototype.setfullyear
description: >
Read [[DateValue]] and then call ToNumber when stored time-value is invalid.
info: |
Date.prototype.setFullYear ( year [ , month [ , date ] ] )
...
3. Let t be dateObject.[[DateValue]].
4. Let y be ? ToNumber(year).
5. If t is NaN, set t to +0𝔽; otherwise, set t to LocalTime(t).
...
---*/

var dt = new Date(NaN);

var valueOfCalled = 0;

var value = {
valueOf() {
valueOfCalled++;
dt.setTime(0);
return 1;
}
};

var result = dt.setFullYear(value);

assert.sameValue(valueOfCalled, 1, "valueOf called exactly once");

assert.notSameValue(result, NaN, "result is not NaN");

assert.sameValue(result, dt.getTime(), "result is equal to getTime");

assert.sameValue(dt.getFullYear(), 1, "date value correctly updated");
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-date.prototype.setfullyear
description: >
Read [[DateValue]] and then call ToNumber when stored time-value is valid.
info: |
Date.prototype.setFullYear ( year [ , month [ , date ] ] )
...
3. Let t be dateObject.[[DateValue]].
4. Let y be ? ToNumber(year).
5. If t is NaN, set t to +0𝔽; otherwise, set t to LocalTime(t).
...
---*/

var dt = new Date(0);

var valueOfCalled = 0;

var value = {
valueOf() {
valueOfCalled++;
dt.setTime(NaN);
return 1;
}
};

var result = dt.setFullYear(value);

assert.sameValue(valueOfCalled, 1, "valueOf called exactly once");

assert.notSameValue(result, NaN, "result is not NaN");

assert.sameValue(result, dt.getTime(), "result is equal to getTime");

assert.sameValue(dt.getFullYear(), 1, "date value correctly updated");
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-date.prototype.sethours
description: >
Read [[DateValue]] and then call ToNumber when stored time-value is invalid.
info: |
Date.prototype.setHours ( hour [ , min [ , sec [ , ms ] ] ] )
...
3. Let t be dateObject.[[DateValue]].
4. Let h be ? ToNumber(hour).
5. If min is present, let m be ? ToNumber(min).
6. If sec is present, let s be ? ToNumber(sec).
7. If ms is present, let milli be ? ToNumber(ms).
8. If t is NaN, return NaN.
...
---*/

var dt = new Date(NaN);

var valueOfCalled = 0;

var value = {
valueOf() {
valueOfCalled++;
dt.setTime(0);
return 1;
}
};

var result = dt.setHours(value);

assert.sameValue(valueOfCalled, 1, "valueOf called exactly once");

assert.sameValue(result, NaN, "result is NaN");

assert.sameValue(dt.getTime(), 0, "time updated in valueOf");
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-date.prototype.sethours
description: >
Read [[DateValue]] and then call ToNumber when stored time-value is valid.
info: |
Date.prototype.setHours ( hour [ , min [ , sec [ , ms ] ] ] )
...
3. Let t be dateObject.[[DateValue]].
4. Let h be ? ToNumber(hour).
5. If min is present, let m be ? ToNumber(min).
6. If sec is present, let s be ? ToNumber(sec).
7. If ms is present, let milli be ? ToNumber(ms).
8. If t is NaN, return NaN.
9. Set t to LocalTime(t).
...
---*/

var dt = new Date(0);

var valueOfCalled = 0;

var value = {
valueOf() {
valueOfCalled++;
dt.setTime(NaN);
return 1;
}
};

var result = dt.setHours(value);

assert.sameValue(valueOfCalled, 1, "valueOf called exactly once");

assert.notSameValue(result, NaN, "result is not NaN");

assert.sameValue(result, dt.getTime(), "result is equal to getTime");

assert.sameValue(dt.getHours(), 1, "date value correctly updated");
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-date.prototype.setmilliseconds
description: >
Read [[DateValue]] and then call ToNumber when stored time-value is invalid.
info: |
Date.prototype.setMilliseconds ( ms )
...
3. Let t be dateObject.[[DateValue]].
4. Set ms to ? ToNumber(ms).
5. If t is NaN, return NaN.
...
---*/

var dt = new Date(NaN);

var valueOfCalled = 0;

var value = {
valueOf() {
valueOfCalled++;
dt.setTime(0);
return 1;
}
};

var result = dt.setMilliseconds(value);

assert.sameValue(valueOfCalled, 1, "valueOf called exactly once");

assert.sameValue(result, NaN, "result is NaN");

assert.sameValue(dt.getTime(), 0, "time updated in valueOf");
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-date.prototype.setmilliseconds
description: >
Read [[DateValue]] and then call ToNumber when stored time-value is valid.
info: |
Date.prototype.setMilliseconds ( ms )
...
3. Let t be dateObject.[[DateValue]].
4. Set ms to ? ToNumber(ms).
5. If t is NaN, return NaN.
6. Set t to LocalTime(t).
...
---*/

var dt = new Date(0);

var valueOfCalled = 0;

var value = {
valueOf() {
valueOfCalled++;
dt.setTime(NaN);
return 1;
}
};

var result = dt.setMilliseconds(value);

assert.sameValue(valueOfCalled, 1, "valueOf called exactly once");

assert.notSameValue(result, NaN, "result is not NaN");

assert.sameValue(result, dt.getTime(), "result is equal to getTime");

assert.sameValue(dt.getMilliseconds(), 1, "date value correctly updated");
Loading

0 comments on commit 92b5925

Please sign in to comment.