From ff017c992446c847887d3b22046b94bfa8490685 Mon Sep 17 00:00:00 2001 From: Andy Heninger Date: Fri, 25 Mar 2016 21:35:18 +0000 Subject: [PATCH] ICU-12393 better error checking for udata_getHashTable(). X-SVN-Rev: 38585 --- icu4c/source/common/udata.cpp | 57 ++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/icu4c/source/common/udata.cpp b/icu4c/source/common/udata.cpp index d32023b7f6d..f50be0dd862 100644 --- a/icu4c/source/common/udata.cpp +++ b/icu4c/source/common/udata.cpp @@ -1,7 +1,7 @@ /* ****************************************************************************** * -* Copyright (C) 1999-2015, International Business Machines +* Copyright (C) 1999-2016, International Business Machines * Corporation and others. All Rights Reserved. * ****************************************************************************** @@ -77,7 +77,7 @@ U_NAMESPACE_USE /* * Forward declarations */ -static UDataMemory *udata_findCachedData(const char *path); +static UDataMemory *udata_findCachedData(const char *path, UErrorCode &err); /*********************************************************************** * @@ -132,13 +132,13 @@ udata_cleanup(void) } static UBool U_CALLCONV -findCommonICUDataByName(const char *inBasename) +findCommonICUDataByName(const char *inBasename, UErrorCode &err) { UBool found = FALSE; int32_t i; - UDataMemory *pData = udata_findCachedData(inBasename); - if (pData == NULL) + UDataMemory *pData = udata_findCachedData(inBasename, err); + if (U_FAILURE(err) || pData == NULL) return FALSE; { @@ -268,40 +268,41 @@ static void U_CALLCONV DataCacheElement_deleter(void *pDCEl) { uprv_free(pDCEl); /* delete 'this' */ } -static void udata_initHashTable() { - UErrorCode err = U_ZERO_ERROR; +static void udata_initHashTable(UErrorCode &err) { U_ASSERT(gCommonDataCache == NULL); gCommonDataCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &err); if (U_FAILURE(err)) { - // TODO: handle errors better. - gCommonDataCache = NULL; - } - if (gCommonDataCache != NULL) { - uhash_setValueDeleter(gCommonDataCache, DataCacheElement_deleter); - ucln_common_registerCleanup(UCLN_COMMON_UDATA, udata_cleanup); + return; } + U_ASSERT(gCommonDataCache != NULL); + uhash_setValueDeleter(gCommonDataCache, DataCacheElement_deleter); + ucln_common_registerCleanup(UCLN_COMMON_UDATA, udata_cleanup); } /* udata_getCacheHashTable() * Get the hash table used to store the data cache entries. * Lazy create it if it doesn't yet exist. */ -static UHashtable *udata_getHashTable() { - umtx_initOnce(gCommonDataCacheInitOnce, &udata_initHashTable); +static UHashtable *udata_getHashTable(UErrorCode &err) { + umtx_initOnce(gCommonDataCacheInitOnce, &udata_initHashTable, err); return gCommonDataCache; } -static UDataMemory *udata_findCachedData(const char *path) +static UDataMemory *udata_findCachedData(const char *path, UErrorCode &err) { UHashtable *htable; UDataMemory *retVal = NULL; DataCacheElement *el; const char *baseName; + htable = udata_getHashTable(err); + if (U_FAILURE(err)) { + return NULL; + } + baseName = findBasename(path); /* Cache remembers only the base name, not the full path. */ - htable = udata_getHashTable(); umtx_lock(NULL); el = (DataCacheElement *)uhash_get(htable, baseName); umtx_unlock(NULL); @@ -323,6 +324,7 @@ static UDataMemory *udata_cacheDataItem(const char *path, UDataMemory *item, UEr DataCacheElement *oldValue = NULL; UErrorCode subErr = U_ZERO_ERROR; + htable = udata_getHashTable(*pErr); if (U_FAILURE(*pErr)) { return NULL; } @@ -355,7 +357,6 @@ static UDataMemory *udata_cacheDataItem(const char *path, UDataMemory *item, UEr /* Stick the new DataCacheElement into the hash table. */ - htable = udata_getHashTable(); umtx_lock(NULL); oldValue = (DataCacheElement *)uhash_get(htable, path); if (oldValue != NULL) { @@ -393,9 +394,6 @@ static UDataMemory *udata_cacheDataItem(const char *path, UDataMemory *item, UEr * * *----------------------------------------------------------------------*/ -#define U_DATA_PATHITER_BUFSIZ 128 /* Size of local buffer for paths */ - /* Overflow causes malloc of larger buf */ - U_NAMESPACE_BEGIN class UDataPathIterator @@ -717,18 +715,18 @@ openCommonData(const char *path, /* Path from OpenChoice? */ #ifdef UDATA_DEBUG fprintf(stderr, "ocd: no basename in %s, bailing.\n", path); #endif - *pErrorCode=U_FILE_ACCESS_ERROR; + if (U_SUCCESS(*pErrorCode)) { + *pErrorCode=U_FILE_ACCESS_ERROR; + } return NULL; } /* Is the requested common data file already open and cached? */ /* Note that the cache is keyed by the base name only. The rest of the path, */ /* if any, is not considered. */ - { - UDataMemory *dataToReturn = udata_findCachedData(inBasename); - if (dataToReturn != NULL) { - return dataToReturn; - } + UDataMemory *dataToReturn = udata_findCachedData(inBasename, *pErrorCode); + if (dataToReturn != NULL || U_FAILURE(*pErrorCode)) { + return dataToReturn; } /* Requested item is not in the cache. @@ -759,6 +757,9 @@ openCommonData(const char *path, /* Path from OpenChoice? */ } #endif + if (U_FAILURE(*pErrorCode)) { + return NULL; + } if (!UDataMemory_isLoaded(&tData)) { /* no common data */ *pErrorCode=U_FILE_ACCESS_ERROR; @@ -834,7 +835,7 @@ static UBool extendICUData(UErrorCode *pErr) umtx_storeRelease(gHaveTriedToLoadCommonData, 1); } - didUpdate = findCommonICUDataByName(U_ICUDATA_NAME); /* Return 'true' when a racing writes out the extended */ + didUpdate = findCommonICUDataByName(U_ICUDATA_NAME, *pErr); /* Return 'true' when a racing writes out the extended */ /* data after another thread has failed to see it (in openCommonData), so */ /* extended data can be examined. */ /* Also handles a race through here before gHaveTriedToLoadCommonData is set. */ -- 2.40.0