Commit f5dac714 authored by Frank Tang's avatar Frank Tang Committed by Commit Bot

Fix crash in creating NumberFormat

setUnicodeKeywordValue doesn't remove unrelated keyword/value pairs
when the locale is too long, which causes NumberFormat to fail when
calling createInstance. Fix this by using LocaleBuilder to add keyword/value
into a new locale instead of removing the keyword.

Also see https://unicode-org.atlassian.net/browse/ICU-20862

Bug: chromium:1012579
Change-Id: I0f664f60dad8fe786443c8ca8b21ea43323cbf49
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1855586Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Frank Tang <ftang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64253}
parent 0b4e0f85
......@@ -33,6 +33,7 @@
#include "unicode/datefmt.h"
#include "unicode/decimfmt.h"
#include "unicode/formattedvalue.h"
#include "unicode/localebuilder.h"
#include "unicode/locid.h"
#include "unicode/normalizer2.h"
#include "unicode/numberformatter.h"
......@@ -1611,6 +1612,8 @@ std::map<std::string, std::string> LookupAndValidateUnicodeExtensions(
std::map<std::string, std::string> extensions;
UErrorCode status = U_ZERO_ERROR;
icu::LocaleBuilder builder;
builder.setLocale(*icu_locale).clearExtensions();
std::unique_ptr<icu::StringEnumeration> keywords(
icu_locale->createKeywords(status));
if (U_FAILURE(status)) return extensions;
......@@ -1672,20 +1675,14 @@ std::map<std::string, std::string> LookupAndValidateUnicodeExtensions(
if (is_valid_value) {
extensions.insert(
std::pair<std::string, std::string>(bcp47_key, bcp47_value));
continue;
builder.setUnicodeLocaleKeyword(bcp47_key, bcp47_value);
}
}
status = U_ZERO_ERROR;
icu_locale->setUnicodeKeywordValue(
bcp47_key == nullptr ? keyword : bcp47_key, nullptr, status);
// Ignore failures in ICU and skip to the next keyword.
//
// This is fine.™
if (U_FAILURE(status)) {
status = U_ZERO_ERROR;
}
}
status = U_ZERO_ERROR;
*icu_locale = builder.build(status);
return extensions;
}
......
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let longLocale = 'de-u-cf-cu-em-kk-kr-ks-kv-lb-lw-ms-nu-rg-sd-ss-tz';
rtf = new Intl.RelativeTimeFormat(longLocale);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment