//------------------------------------------------------------------------------------------------------- | |
// Copyright (C) Microsoft. All rights reserved. | |
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. | |
//------------------------------------------------------------------------------------------------------- | |
WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js"); | |
const constructors = [Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat]; | |
if (WScript.Platform.INTL_LIBRARY === "icu") { | |
constructors.push(Intl.PluralRules); | |
} | |
testRunner.runTests([ | |
{ | |
name: "OSS-Fuzz #6657: stress uloc_forLanguageTag status code and parsed length on duplicate variant subtags", | |
body() { | |
function test(Ctor, locale) { | |
assert.throws(() => new Ctor(locale), RangeError, `new Intl.${Ctor.name}("${locale}") should throw`); | |
} | |
function testWithVariants(variants) { | |
for (const Ctor of constructors) { | |
for (let i = 0; i < variants.length; ++i) { | |
for (let k = 0; k < variants.length; ++k) { | |
for (let m = 0; m < variants.length; ++m) { | |
test(Ctor, `und-${variants[i]}-${variants[k]}-${variants[m]}`); | |
test(Ctor, `en-${variants[i]}-${variants[k]}-${variants[m]}`); | |
test(Ctor, `de-DE-${variants[i]}-${variants[k]}-${variants[m]}`); | |
test(Ctor, `zh-Hans-CN-${variants[i]}-${variants[k]}-${variants[m]}`); | |
} | |
test(Ctor, `und-${variants[i]}-${variants[k]}`); | |
test(Ctor, `en-${variants[i]}-${variants[k]}`); | |
test(Ctor, `de-DE-${variants[i]}-${variants[k]}`); | |
test(Ctor, `zh-Hans-CN-${variants[i]}-${variants[k]}`); | |
} | |
} | |
} | |
} | |
if (WScript.Platform.INTL_LIBRARY === "icu") { | |
testWithVariants(["gregory", "GREGORY", "gregORY"]); | |
testWithVariants(["invalid", "INVALID", "invaLID"]); | |
} | |
} | |
}, | |
{ | |
name: "OSS-Fuzz #7950: Have option getters redefine themselves", | |
body() { | |
if (WScript.Platform.INTL_LIBRARY === "winglob") { | |
return; | |
} | |
function test(callback, optionName, optionValue, shouldCallSecondGetter) { | |
const options = {}; | |
let calledSecondGetter = false; | |
Object.defineProperty(options, optionName, { | |
get() { | |
Object.defineProperty(options, optionName, { | |
get() { | |
calledSecondGetter = true; | |
return undefined; | |
} | |
}); | |
return optionValue; | |
}, | |
configurable: true | |
}); | |
callback(options); | |
assert.areEqual(shouldCallSecondGetter, calledSecondGetter, "Second getter behavior was incorrect"); | |
} | |
test((options) => assert.areEqual(1, new Intl.Collator("en-US", options).compare("A", "a")), "sensitivity", "case", false); | |
test((options) => assert.areEqual(-1, new Intl.Collator("en-US", options).compare("A", "B")), "sensitivity", "case", false); | |
test((options) => assert.areEqual(0, new Intl.Collator("en-US", options).compare("a", "\u00E2")), "sensitivity", "case", false); | |
test((options) => assert.areEqual("1000", new Intl.NumberFormat("en-US", options).format(1000)), "useGrouping", false, false); | |
test((options) => assert.areEqual("$1.50", new Intl.NumberFormat("en-US", Object.assign(options, { currency: "USD" })).format(1.5)), "style", "currency", false); | |
// This was the original bug - at present, all browsers format the string as "" because the value returned by the second getter dictates format selection | |
test((options) => assert.areEqual("", new Intl.DateTimeFormat("en-US", options).format()), "year", "numeric", true); | |
test((options) => assert.areEqual("", new Intl.DateTimeFormat("en-US", options).format()), "minute", "numeric", true); | |
} | |
} | |
], { verbose: false }); |