From 653750ca58d78a50e78fd04542ec8b921f1dbd1b Mon Sep 17 00:00:00 2001 From: Peter Edberg Date: Thu, 9 Feb 2017 19:33:51 +0000 Subject: [PATCH] ICU-12969 protect against using negative ID for resource X-SVN-Rev: 39654 --- icu4c/source/common/uresdata.cpp | 14 ++++++---- icu4c/source/test/cintltst/cloctst.c | 39 ++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/icu4c/source/common/uresdata.cpp b/icu4c/source/common/uresdata.cpp index 64747a25520..8bcb9ab8b88 100644 --- a/icu4c/source/common/uresdata.cpp +++ b/icu4c/source/common/uresdata.cpp @@ -758,7 +758,9 @@ res_getTableItemByIndex(const ResourceData *pResData, Resource table, int32_t indexR, const char **key) { uint32_t offset=RES_GET_OFFSET(table); int32_t length; - U_ASSERT(indexR>=0); /* to ensure the index is not negative */ + if (indexR < 0) { + return RES_BOGUS; + } switch(RES_GET_TYPE(table)) { case URES_TABLE: { if (offset != 0) { /* empty if offset==0 */ @@ -836,7 +838,9 @@ UBool icu::ResourceTable::getKeyAndValue(int32_t i, U_CAPI Resource U_EXPORT2 res_getArrayItem(const ResourceData *pResData, Resource array, int32_t indexR) { uint32_t offset=RES_GET_OFFSET(array); - U_ASSERT(indexR>=0); /* to ensure the index is not negative */ + if (indexR < 0) { + return RES_BOGUS; + } switch(RES_GET_TYPE(array)) { case URES_ARRAY: { if (offset!=0) { /* empty if offset==0 */ @@ -923,14 +927,14 @@ res_findResource(const ResourceData *pResData, Resource r, char** path, const ch if(t2 == RES_BOGUS) { /* if we fail to get the resource by key, maybe we got an index */ indexR = uprv_strtol(pathP, &closeIndex, 10); - if(*closeIndex == 0) { + if(indexR >= 0 && *closeIndex == 0) { /* if we indeed have an index, try to get the item by index */ t2 = res_getTableItemByIndex(pResData, t1, indexR, key); - } + } // else t2 is already RES_BOGUS } } else if(URES_IS_ARRAY(type)) { indexR = uprv_strtol(pathP, &closeIndex, 10); - if(*closeIndex == 0) { + if(indexR >= 0 && *closeIndex == 0) { t2 = res_getArrayItem(pResData, t1, indexR); } else { t2 = RES_BOGUS; /* have an array, but don't have a valid index */ diff --git a/icu4c/source/test/cintltst/cloctst.c b/icu4c/source/test/cintltst/cloctst.c index 9dd6d67f854..9263dfc1025 100644 --- a/icu4c/source/test/cintltst/cloctst.c +++ b/icu4c/source/test/cintltst/cloctst.c @@ -50,6 +50,7 @@ static void TestDisplayNameBrackets(void); static void TestUnicodeDefines(void); static void TestIsRightToLeft(void); +static void TestBadLocaleIDs(void); void PrintDataTable(); @@ -259,6 +260,7 @@ void addLocaleTest(TestNode** root) TESTCASE(TestToLegacyKey); TESTCASE(TestToUnicodeLocaleType); TESTCASE(TestToLegacyType); + TESTCASE(TestBadLocaleIDs); } @@ -6194,3 +6196,40 @@ static void TestIsRightToLeft() { log_err("uloc_isRightToLeft() failed"); } } + +typedef struct { + const char * badLocaleID; + const char * displayLocale; + const char * expectedName; + UErrorCode expectedStatus; +} BadLocaleItem; + +static const BadLocaleItem badLocaleItems[] = { + { "-9223372036854775808", "en", "9223372036854775808", U_USING_DEFAULT_WARNING }, + /* add more in the future */ + { NULL, NULL, NULL, U_ZERO_ERROR } /* terminator */ +}; + +enum { kUBufDispNameMax = 128, kBBufDispNameMax = 256 }; + +static void TestBadLocaleIDs() { + const BadLocaleItem* itemPtr; + for (itemPtr = badLocaleItems; itemPtr->badLocaleID != NULL; itemPtr++) { + UChar ubufExpect[kUBufDispNameMax], ubufGet[kUBufDispNameMax]; + UErrorCode status = U_ZERO_ERROR; + int32_t ulenExpect = u_unescape(itemPtr->expectedName, ubufExpect, kUBufDispNameMax); + int32_t ulenGet = uloc_getDisplayName(itemPtr->badLocaleID, itemPtr->displayLocale, ubufGet, kUBufDispNameMax, &status); + if (status != itemPtr->expectedStatus || + (U_SUCCESS(status) && (ulenGet != ulenExpect || u_strncmp(ubufGet, ubufExpect, ulenExpect) != 0))) { + char bbufExpect[kBBufDispNameMax], bbufGet[kBBufDispNameMax]; + u_austrncpy(bbufExpect, ubufExpect, ulenExpect); + u_austrncpy(bbufGet, ubufGet, ulenGet); + log_err("FAIL: For localeID %s, displayLocale %s, calling uloc_getDisplayName:\n" + " expected status %-26s, name (len %2d): %s\n" + " got status %-26s, name (len %2d): %s\n", + itemPtr->badLocaleID, itemPtr->displayLocale, + u_errorName(itemPtr->expectedStatus), ulenExpect, bbufExpect, + u_errorName(status), ulenGet, bbufGet ); + } + } +}