Bug 912701 - When removing Unicode extension sequences from a locale, ignore similar syntax that might be found in a privateuse component. r=abargull

This commit is contained in:
Jeff Walden 2015-06-28 07:00:01 -07:00
parent d264043149
commit a970903611
2 changed files with 53 additions and 6 deletions

View File

@ -81,7 +81,7 @@ internalIntlRegExps.currencyDigitsRE = null;
function getUnicodeLocaleExtensionSequenceRE() {
return internalIntlRegExps.unicodeLocaleExtensionSequenceRE ||
(internalIntlRegExps.unicodeLocaleExtensionSequenceRE =
regexp_construct_no_statics("-u(-[a-z0-9]{2,8})+"));
regexp_construct_no_statics("-u(?:-[a-z0-9]{2,8})+"));
}
@ -89,15 +89,38 @@ function getUnicodeLocaleExtensionSequenceRE() {
* Removes Unicode locale extension sequences from the given language tag.
*/
function removeUnicodeExtensions(locale) {
// Don't use std_String_replace directly with a regular expression,
// as that would set RegExp statics.
// A wholly-privateuse locale has no extension sequences.
if (callFunction(std_String_startsWith, locale, "x-"))
return locale;
// Otherwise, split on "-x-" marking the start of any privateuse component.
// Replace Unicode locale extension sequences in the left half, and return
// the concatenation.
var pos = callFunction(std_String_indexOf, locale, "-x-");
if (pos < 0)
pos = locale.length;
var left = callFunction(std_String_substring, locale, 0, pos);
var right = callFunction(std_String_substring, locale, pos);
var extensions;
var unicodeLocaleExtensionSequenceRE = getUnicodeLocaleExtensionSequenceRE();
while ((extensions = regexp_exec_no_statics(unicodeLocaleExtensionSequenceRE, locale)) !== null) {
locale = callFunction(std_String_replace, locale, extensions[0], "");
while ((extensions = regexp_exec_no_statics(unicodeLocaleExtensionSequenceRE, left)) !== null) {
left = callFunction(std_String_replace, left, extensions[0], "");
unicodeLocaleExtensionSequenceRE.lastIndex = 0;
}
return locale;
var combined = left + right;
assert(IsStructurallyValidLanguageTag(combined), "recombination produced an invalid language tag");
assert(function() {
var uindex = callFunction(std_String_indexOf, combined, "-u-");
if (uindex < 0)
return true;
var xindex = callFunction(std_String_indexOf, combined, "-x-");
return xindex > 0 && xindex < uindex;
}(), "recombination failed to remove all Unicode locale extension sequences");
return combined;
}

View File

@ -0,0 +1,24 @@
// |reftest| skip-if(!this.hasOwnProperty("Intl"))
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Locale processing is supposed to internally remove any Unicode extension
// sequences in the locale. Test that various weird testcases invoking
// algorithmic edge cases don't assert or throw exceptions.
var weirdCases =
[
"x-u-foo",
"en-x-u-foo",
"en-a-bar-x-u-foo",
"en-x-u-foo-a-bar",
"en-a-bar-u-baz-x-u-foo",
];
for (var locale of weirdCases)
Intl.NumberFormat(locale).format(5);
if (typeof reportCompare === "function")
reportCompare(true, true);