diff --git a/icu4c/source/common/uloc_tag.cpp b/icu4c/source/common/uloc_tag.cpp index 0e1743699ce..1c10c48182c 100644 --- a/icu4c/source/common/uloc_tag.cpp +++ b/icu4c/source/common/uloc_tag.cpp @@ -1558,10 +1558,8 @@ _appendLDMLExtensionAsKeywords(const char* ldmlext, ExtensionListEntry** appendT return; } - if (!_addAttributeToList(&attrFirst, attr)) { - *status = U_ILLEGAL_ARGUMENT_ERROR; - return; - } + // duplicate attribute is ignored, causes no error. + _addAttributeToList(&attrFirst, attr); /* next tag */ pTag += len; diff --git a/icu4c/source/test/cintltst/cloctst.c b/icu4c/source/test/cintltst/cloctst.c index 4809f5cb8e6..e8ddf76e840 100644 --- a/icu4c/source/test/cintltst/cloctst.c +++ b/icu4c/source/test/cintltst/cloctst.c @@ -255,8 +255,8 @@ void addLocaleTest(TestNode** root) TESTCASE(TestLikelySubtags); TESTCASE(TestToLanguageTag); TESTCASE(TestBug20132); + TESTCASE(TestBug20149); TESTCASE(TestForLanguageTag); - TESTCASE(TestInvalidLanguageTag); TESTCASE(TestLangAndRegionCanonicalize); TESTCASE(TestTrailingNull); TESTCASE(TestUnicodeDefines); @@ -6200,35 +6200,6 @@ static void TestForLanguageTag(void) { } } -/* See https://unicode-org.atlassian.net/browse/ICU-20149 . - * Depending on the resolution of that bug, this test may have - * to be revised. - */ -static void TestInvalidLanguageTag(void) { - static const char* invalid_lang_tags[] = { - "zh-u-foo-foo-co-pinyin", /* duplicate attribute in U extension */ - "zh-cmn-hans-u-foo-foo-co-pinyin", /* duplicate attribute in U extension */ -#if 0 - /* - * These do not lead to an error. Instead, parsing stops at the 1st - * invalid subtag. - */ - "de-DE-1901-1901", /* duplicate variant */ - "en-a-bbb-a-ccc", /* duplicate extension */ -#endif - NULL - }; - char locale[256]; - for (const char** tag = invalid_lang_tags; *tag != NULL; tag++) { - UErrorCode status = U_ZERO_ERROR; - uloc_forLanguageTag(*tag, locale, sizeof(locale), NULL, &status); - if (status != U_ILLEGAL_ARGUMENT_ERROR) { - log_err("Error returned by uloc_forLanguageTag for input language tag [%s] : %s - expected error: %s\n", - *tag, u_errorName(status), u_errorName(U_ILLEGAL_ARGUMENT_ERROR)); - } - } -} - static const struct { const char *input; const char *canonical; @@ -6558,3 +6529,18 @@ static void TestBug20370() { log_err("FAIL: Expected LCID value of 0 for invalid localeID input."); } } + +// Test case for ICU-20149 +// Handle the duplicate U extension attribute +static void TestBug20149() { + const char *localeID = "zh-u-foo-foo-co-pinyin"; + char locale[256]; + UErrorCode status = U_ZERO_ERROR; + int32_t parsedLen; + locale[0] = '\0'; + uloc_forLanguageTag(localeID, locale, sizeof(locale), &parsedLen, &status); + if (U_FAILURE(status) || + 0 !=strcmp("zh@attribute=foo;collation=pinyin", locale)) { + log_err("ERROR: in uloc_forLanguageTag %s return %s\n", myErrorName(status), locale); + } +} diff --git a/icu4c/source/test/cintltst/cloctst.h b/icu4c/source/test/cintltst/cloctst.h index f415dbbe278..a88a49cf8d8 100644 --- a/icu4c/source/test/cintltst/cloctst.h +++ b/icu4c/source/test/cintltst/cloctst.h @@ -124,7 +124,6 @@ static void TestLikelySubtags(void); * language tag */ static void TestForLanguageTag(void); -static void TestInvalidLanguageTag(void); static void TestToLanguageTag(void); static void TestBug20132(void); static void TestLangAndRegionCanonicalize(void); @@ -133,6 +132,7 @@ static void TestToUnicodeLocaleKey(void); static void TestToLegacyKey(void); static void TestToUnicodeLocaleType(void); static void TestToLegacyType(void); +static void TestBug20149(void); /** * locale data