From ad78b401c576978430c3e6d46419fead91ce08cf Mon Sep 17 00:00:00 2001 From: Jeff Genovy <29107334+jefgen@users.noreply.github.com> Date: Wed, 27 Jan 2021 19:32:53 -0800 Subject: [PATCH] ICU-21449 Infinite loop can occur with locale IDs that contain RES_PATH_SEPARATOR --- icu4c/source/common/uresbund.cpp | 2 ++ icu4c/source/test/cintltst/cloctst.c | 16 ++++++++++++++-- icu4c/source/test/cintltst/cloctst.h | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/icu4c/source/common/uresbund.cpp b/icu4c/source/common/uresbund.cpp index e95e961a526b..d2746b17d9e0 100644 --- a/icu4c/source/common/uresbund.cpp +++ b/icu4c/source/common/uresbund.cpp @@ -1908,6 +1908,8 @@ ures_getByKeyWithFallback(const UResourceBundle *resB, } else { break; } + } else if (res == RES_BOGUS) { + break; } } while(*myPath); /* Continue until the whole path is consumed */ } diff --git a/icu4c/source/test/cintltst/cloctst.c b/icu4c/source/test/cintltst/cloctst.c index 73124533ee50..b74d5a05c5a9 100644 --- a/icu4c/source/test/cintltst/cloctst.c +++ b/icu4c/source/test/cintltst/cloctst.c @@ -280,6 +280,7 @@ void addLocaleTest(TestNode** root) TESTCASE(TestBug20370); TESTCASE(TestBug20321UnicodeLocaleKey); TESTCASE(TestUsingDefaultWarning); + TESTCASE(TestBug21449InfiniteLoop); } @@ -6978,11 +6979,12 @@ static void TestUsingDefaultWarning() { log_err("ERROR: in uloc_getDisplayKeywordValue %s %s return len:%d %s with status %d %s\n", keyword_value, keyword, length, errorOutputBuff, status, myErrorName(status)); } -} +} + // Test case for ICU-20575 // This test checks if the environment variable LANG is set, // and if so ensures that both C and C.UTF-8 cause ICU's default locale to be en_US_POSIX. -static void TestCDefaultLocale(){ +static void TestCDefaultLocale() { const char *defaultLocale = uloc_getDefault(); char *env_var = getenv("LANG"); if (env_var == NULL) { @@ -6993,3 +6995,13 @@ static void TestCDefaultLocale(){ log_err("The default locale for LANG=%s should be en_US_POSIX, not %s\n", env_var, defaultLocale); } } + +// Test case for ICU-21449 +static void TestBug21449InfiniteLoop() { + UErrorCode status = U_ZERO_ERROR; + const char* invalidLocaleId = RES_PATH_SEPARATOR_S; + + // The issue causes an infinite loop to occur when looking up a non-existent resource for the invalid locale ID, + // so the test is considered passed if the call to the API below returns anything at all. + uloc_getDisplayLanguage(invalidLocaleId, invalidLocaleId, NULL, 0, &status); +} diff --git a/icu4c/source/test/cintltst/cloctst.h b/icu4c/source/test/cintltst/cloctst.h index af7fa5d06a31..69f4e6f1b626 100644 --- a/icu4c/source/test/cintltst/cloctst.h +++ b/icu4c/source/test/cintltst/cloctst.h @@ -142,6 +142,7 @@ static void TestToUnicodeLocaleType(void); static void TestToLegacyType(void); static void TestBug20149(void); static void TestCDefaultLocale(void); +static void TestBug21449InfiniteLoop(void); /**