diff --git a/icu4c/source/common/uresbund.c b/icu4c/source/common/uresbund.c index 4013f2fe61d..821fe466b7b 100644 --- a/icu4c/source/common/uresbund.c +++ b/icu4c/source/common/uresbund.c @@ -144,7 +144,7 @@ free_entry(UResourceDataEntry *entry) { if(entry->fBogus == U_ZERO_ERROR) { res_unload(&(entry->fData)); } - if(entry->fName != NULL) { + if(entry->fName != NULL && entry->fName != entry->fNameBuffer) { uprv_free(entry->fName); } if(entry->fPath != NULL) { @@ -237,10 +237,16 @@ static void initCache(UErrorCode *status) { /** INTERNAL: sets the name (locale) of the resource bundle to given name */ static void setEntryName(UResourceDataEntry *res, char *name, UErrorCode *status) { - if(res->fName != NULL) { + int32_t len = uprv_strlen(name); + if(res->fName != NULL && res->fName != res->fNameBuffer) { uprv_free(res->fName); } - res->fName = (char *)uprv_malloc(sizeof(char)*uprv_strlen(name)+1); + if (len < (int32_t)sizeof(res->fNameBuffer)) { + res->fName = res->fNameBuffer; + } + else { + res->fName = (char *)uprv_malloc(len+1); + } if(res->fName == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; } else { @@ -367,12 +373,7 @@ static UResourceDataEntry *init_entry(const char *localeID, const char *path, UE } else { /* somebody have already inserted it while we were working, discard newly opened data */ /* Also, we could get here IF we opened an alias */ - uprv_free(r->fName); - if(r->fPath != NULL) { - uprv_free(r->fPath); - } - res_unload(&(r->fData)); - uprv_free(r); + free_entry(r); r = oldR; r->fCountExisting++; } diff --git a/icu4c/source/common/uresimp.h b/icu4c/source/common/uresimp.h index d779cca1ec5..4186200cfa9 100644 --- a/icu4c/source/common/uresimp.h +++ b/icu4c/source/common/uresimp.h @@ -48,6 +48,7 @@ struct UResourceDataEntry { char *fPath; /* path to bundle - used for distinguishing between resources with the same name */ UResourceDataEntry *fParent; /*next resource in fallback chain*/ ResourceData fData; /* data for low level access */ + char fNameBuffer[3]; /* A small buffer of free space for fName. The free space is due to struct padding. */ uint32_t fCountExisting; /* how much is this resource used */ UErrorCode fBogus; /* int32_t fHashKey;*/ /* for faster access in the hashtable */ diff --git a/icu4c/source/test/cintltst/cmsccoll.c b/icu4c/source/test/cintltst/cmsccoll.c index 741bcbbfcdb..f488d4a3bf4 100644 --- a/icu4c/source/test/cintltst/cmsccoll.c +++ b/icu4c/source/test/cintltst/cmsccoll.c @@ -1295,149 +1295,153 @@ static const char* rulesToTest[] = { static void TestCollations(void) { - int32_t noOfLoc = uloc_countAvailable(); - int32_t i = 0, j = 0; + int32_t noOfLoc = uloc_countAvailable(); + int32_t i = 0, j = 0; - UErrorCode status = U_ZERO_ERROR; - char cName[256]; - UChar name[256]; - int32_t nameSize; + UErrorCode status = U_ZERO_ERROR; + char cName[256]; + UChar name[256]; + int32_t nameSize; - const char *locName = NULL; - UCollator *coll = NULL; - UCollator *UCA = ucol_open("", &status); - UColAttributeValue oldStrength = ucol_getAttribute(UCA, UCOL_STRENGTH, &status); - ucol_setAttribute(UCA, UCOL_STRENGTH, UCOL_QUATERNARY, &status); - - for(i = 0; iimage->jamoSpecial == TRUE) { - log_err("%s has special JAMOs\n", locName); + for(i = 0; iimage->jamoSpecial == TRUE) { + log_err("%s has special JAMOs\n", locName); + } + ucol_setAttribute(coll, UCOL_CASE_FIRST, UCOL_OFF, &status); + testCollator(coll, &status); + testCEs(coll, &status); + ucol_close(coll); + } } - ucol_setAttribute(coll, UCOL_CASE_FIRST, UCOL_OFF, &status); - testCollator(coll, &status); - testCEs(coll, &status); - ucol_close(coll); - } } - } - for(i = 0; i