diff --git a/harness/temporalHelpers.js b/harness/temporalHelpers.js index 947ba282ec..33a8a9c9d8 100644 --- a/harness/temporalHelpers.js +++ b/harness/temporalHelpers.js @@ -933,6 +933,32 @@ var TemporalHelpers = { return new CalendarCheckFieldsPrototypePollution(); }, + /* + * A custom calendar used in prototype pollution checks. Verifies that the + * mergeFields() method is always called with null-prototype fields objects. + */ + calendarCheckMergeFieldsPrototypePollution() { + class CalendarCheckMergeFieldsPrototypePollution extends Temporal.Calendar { + constructor() { + super("iso8601"); + this.mergeFieldsCallCount = 0; + } + + toString() { + return "merge-fields-null-proto"; + } + + mergeFields(fields, additionalFields) { + this.mergeFieldsCallCount++; + assert.sameValue(Object.getPrototypeOf(fields), null, "mergeFields should be called with null-prototype fields object (first argument)"); + assert.sameValue(Object.getPrototypeOf(additionalFields), null, "mergeFields should be called with null-prototype fields object (second argument)"); + return super.mergeFields(fields, additionalFields); + } + } + + return new CalendarCheckMergeFieldsPrototypePollution(); + }, + /* * A custom calendar used in prototype pollution checks. Verifies that methods * are always called with a null-prototype options object. diff --git a/test/built-ins/Temporal/PlainDate/prototype/with/calendar-mergefields-called-with-null-prototype-fields.js b/test/built-ins/Temporal/PlainDate/prototype/with/calendar-mergefields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..d422c91b8b --- /dev/null +++ b/test/built-ins/Temporal/PlainDate/prototype/with/calendar-mergefields-called-with-null-prototype-fields.js @@ -0,0 +1,15 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.with +description: > + Calendar.mergeFields method is called with null-prototype fields objects +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarCheckMergeFieldsPrototypePollution(); +const instance = new Temporal.PlainDate(2000, 5, 2, calendar); +instance.with({ day: 24 }); +assert.sameValue(calendar.mergeFieldsCallCount, 1, "mergeFields should have been called on the calendar"); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/with/calendar-mergefields-called-with-null-prototype-fields.js b/test/built-ins/Temporal/PlainDateTime/prototype/with/calendar-mergefields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..bbfe4145be --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/with/calendar-mergefields-called-with-null-prototype-fields.js @@ -0,0 +1,15 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.with +description: > + Calendar.mergeFields method is called with null-prototype fields objects +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarCheckMergeFieldsPrototypePollution(); +const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, calendar); +instance.with({ day: 24 }); +assert.sameValue(calendar.mergeFieldsCallCount, 1, "mergeFields should have been called on the calendar"); diff --git a/test/built-ins/Temporal/PlainMonthDay/prototype/toPlainDate/calendar-mergefields-called-with-null-prototype-fields.js b/test/built-ins/Temporal/PlainMonthDay/prototype/toPlainDate/calendar-mergefields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..6561cef7f3 --- /dev/null +++ b/test/built-ins/Temporal/PlainMonthDay/prototype/toPlainDate/calendar-mergefields-called-with-null-prototype-fields.js @@ -0,0 +1,15 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.toplaindate +description: > + Calendar.mergeFields method is called with null-prototype fields objects +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarCheckMergeFieldsPrototypePollution(); +const instance = new Temporal.PlainMonthDay(5, 2, calendar); +instance.toPlainDate({ year: 2019 }); +assert.sameValue(calendar.mergeFieldsCallCount, 1, "mergeFields should have been called on the calendar"); diff --git a/test/built-ins/Temporal/PlainMonthDay/prototype/with/calendar-mergefields-called-with-null-prototype-fields.js b/test/built-ins/Temporal/PlainMonthDay/prototype/with/calendar-mergefields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..0f2985bab6 --- /dev/null +++ b/test/built-ins/Temporal/PlainMonthDay/prototype/with/calendar-mergefields-called-with-null-prototype-fields.js @@ -0,0 +1,15 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.with +description: > + Calendar.mergeFields method is called with null-prototype fields objects +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarCheckMergeFieldsPrototypePollution(); +const instance = new Temporal.PlainMonthDay(5, 2, calendar); +instance.with({ day: 24 }); +assert.sameValue(calendar.mergeFieldsCallCount, 1, "mergeFields should have been called on the calendar"); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/toPlainDate/calendar-mergefields-called-with-null-prototype-fields.js b/test/built-ins/Temporal/PlainYearMonth/prototype/toPlainDate/calendar-mergefields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..2b4f8fd901 --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/toPlainDate/calendar-mergefields-called-with-null-prototype-fields.js @@ -0,0 +1,15 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.toplaindate +description: > + Calendar.mergeFields method is called with null-prototype fields objects +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarCheckMergeFieldsPrototypePollution(); +const instance = new Temporal.PlainYearMonth(2000, 5, calendar); +instance.toPlainDate({ day: 24 }); +assert.sameValue(calendar.mergeFieldsCallCount, 1, "mergeFields should have been called on the calendar"); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/with/calendar-mergefields-called-with-null-prototype-fields.js b/test/built-ins/Temporal/PlainYearMonth/prototype/with/calendar-mergefields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..96b5e99466 --- /dev/null +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/with/calendar-mergefields-called-with-null-prototype-fields.js @@ -0,0 +1,15 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: > + Calendar.mergeFields method is called with null-prototype fields objects +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarCheckMergeFieldsPrototypePollution(); +const instance = new Temporal.PlainYearMonth(2000, 5, calendar); +instance.with({ year: 2019 }); +assert.sameValue(calendar.mergeFieldsCallCount, 1, "mergeFields should have been called on the calendar"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/with/calendar-mergefields-called-with-null-prototype-fields.js b/test/built-ins/Temporal/ZonedDateTime/prototype/with/calendar-mergefields-called-with-null-prototype-fields.js new file mode 100644 index 0000000000..88192d8a16 --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/with/calendar-mergefields-called-with-null-prototype-fields.js @@ -0,0 +1,15 @@ +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.with +description: > + Calendar.mergeFields method is called with null-prototype fields objects +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const calendar = TemporalHelpers.calendarCheckMergeFieldsPrototypePollution(); +const instance = new Temporal.ZonedDateTime(0n, "UTC", calendar); +instance.with({ day: 24 }); +assert.sameValue(calendar.mergeFieldsCallCount, 1, "mergeFields should have been called on the calendar");