Throw when case mapping result > max string length

Throw 'Range Error: invalid string length' when the result of
case mapping is longer than the max string length (kMaxLength in
objects.h = 1 << 28 - 16).

This is for case mapping with ICU.

BUG=v8:5271
TEST=intl/general/case-mapping.js with --icu_case_mapping

Review-Url: https://codereview.chromium.org/2236593002
Cr-Commit-Position: refs/heads/master@{#38565}
This commit is contained in:
jshin 2016-08-10 14:45:50 -07:00 committed by Commit bot
parent fe555065ea
commit c7a2046670
2 changed files with 29 additions and 2 deletions

View File

@ -859,8 +859,8 @@ MUST_USE_RESULT Object* LocaleConvertCase(Handle<String> s, Isolate* isolate,
// This is not a real loop. It'll be executed only once (no overflow) or
// twice (overflow).
for (int i = 0; i < 2; ++i) {
result =
isolate->factory()->NewRawTwoByteString(dest_length).ToHandleChecked();
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result, isolate->factory()->NewRawTwoByteString(dest_length));
DisallowHeapAllocation no_gc;
String::FlatContent flat = s->GetFlatContent();
const UChar* src = GetUCharBufferFromFlat(flat, &sap, src_length);

View File

@ -136,3 +136,30 @@ assertEquals("\u{10CC0}", "\u{10C80}".toLocaleLowerCase());
assertEquals("\u{10C80}", "\u{10CC0}".toLocaleUpperCase(["tr"]));
assertEquals("\u{10C80}", "\u{10CC0}".toLocaleUpperCase(["tr"]));
assertEquals("\u{10CC0}", "\u{10C80}".toLocaleLowerCase());
// If the result of case mapping is longer than the max string length
// (1<<28 - 16), it should throw a range error instead of crashing.
var invalidValues = [
{ c: "\u0390", opType: 0 },
{ c: "ß", opType: 0 },
{ c: "\uFB01", opType: 0 }, // fi ligature
{ c: "\uFB04", opType: 0 }, // ffl ligature
{ c: "\u0390", opType: 1, locale: "und" },
{ c: "\u00CC", opType: 2, locale: "lt" },
{ c: "\u0130", opType: 2, locale: "en" },
];
for (var {c, opType, locale} of invalidValues) {
var s = c.repeat(1<<27);
switch (opType) {
case 0:
assertThrows(() => s.toUpperCase(), RangeError);
break;
case 1:
assertThrows(() => s.toLocaleUpperCase(locale), RangeError);
break;
case 2:
assertThrows(() => s.toLocaleLowerCase(locale), RangeError);
break;
}
}