diff --git a/icu4c/source/common/uniset.cpp b/icu4c/source/common/uniset.cpp index 3227447848b..a09ed34ef61 100644 --- a/icu4c/source/common/uniset.cpp +++ b/icu4c/source/common/uniset.cpp @@ -242,7 +242,11 @@ UnicodeSet& UnicodeSet::operator=(const UnicodeSet& o) { if (isFrozen()) { return *this; } - ensureCapacity(o.len); + UErrorCode ec = U_ZERO_ERROR; + ensureCapacity(o.len, ec); + if (U_FAILURE(ec)) { + return *this; // There is no way to report this error :-( + } len = o.len; uprv_memcpy(list, o.list, len*sizeof(UChar32)); if (o.bmpSet == NULL) { @@ -250,7 +254,6 @@ UnicodeSet& UnicodeSet::operator=(const UnicodeSet& o) { } else { bmpSet = new BMPSet(*o.bmpSet, list, len); } - UErrorCode ec = U_ZERO_ERROR; strings->assign(*o.strings, cloneUnicodeString, ec); if (o.stringSpan == NULL) { stringSpan = NULL; @@ -853,7 +856,11 @@ UnicodeSet& UnicodeSet::add(UChar32 c) { list[i] = c; // if we touched the HIGH mark, then add a new one if (c == (UNICODESET_HIGH - 1)) { - ensureCapacity(len+1); + UErrorCode status = U_ZERO_ERROR; + ensureCapacity(len+1, status); + if (U_FAILURE(status)) { + return *this; // There is no way to report this error :-( + } list[len++] = UNICODESET_HIGH; } if (i > 0 && c == list[i-1]) { @@ -894,7 +901,11 @@ UnicodeSet& UnicodeSet::add(UChar32 c) { // ^ // list[i] - ensureCapacity(len+2); + UErrorCode status = U_ZERO_ERROR; + ensureCapacity(len+2, status); + if (U_FAILURE(status)) { + return *this; // There is no way to report this error :-( + } //for (int32_t k=len-1; k>=i; --k) { // list[k+2] = list[k]; @@ -1173,12 +1184,19 @@ UnicodeSet& UnicodeSet::complement(void) { if (isFrozen()) { return *this; } + UErrorCode status = U_ZERO_ERROR; if (list[0] == UNICODESET_LOW) { - ensureBufferCapacity(len-1); + ensureBufferCapacity(len-1, status); + if (U_FAILURE(status)) { + return *this; + } uprv_memcpy(buffer, list + 1, (len-1)*sizeof(UChar32)); --len; } else { - ensureBufferCapacity(len+1); + ensureBufferCapacity(len+1, status); + if (U_FAILURE(status)) { + return *this; + } uprv_memcpy(buffer + 1, list, len*sizeof(UChar32)); buffer[0] = UNICODESET_LOW; ++len; @@ -1471,24 +1489,30 @@ UBool UnicodeSet::allocateStrings(UErrorCode &status) { return TRUE; } -void UnicodeSet::ensureCapacity(int32_t newLen) { +void UnicodeSet::ensureCapacity(int32_t newLen, UErrorCode& ec) { if (newLen <= capacity) return; - capacity = newLen + GROW_EXTRA; - UChar32* temp = (UChar32*) uprv_malloc(sizeof(UChar32) * capacity); - uprv_memcpy(temp, list, len*sizeof(UChar32)); - uprv_free(list); + UChar32* temp = (UChar32*) uprv_realloc(list, sizeof(UChar32) * (newLen + GROW_EXTRA)); + if (temp == NULL) { + ec = U_MEMORY_ALLOCATION_ERROR; + return; // TODO: We should probably set a bogus flag. + } list = temp; + capacity = newLen + GROW_EXTRA; + // else we keep the original contents on the memory failure. } -void UnicodeSet::ensureBufferCapacity(int32_t newLen) { +void UnicodeSet::ensureBufferCapacity(int32_t newLen, UErrorCode& ec) { if (buffer != NULL && newLen <= bufferCapacity) return; - if (buffer) { - uprv_free(buffer); + UChar32* temp = (UChar32*) uprv_realloc(buffer, sizeof(UChar32) * (newLen + GROW_EXTRA)); + if (temp == NULL) { + ec = U_MEMORY_ALLOCATION_ERROR; + return; // TODO: We should probably set a bogus flag. } + buffer = temp; bufferCapacity = newLen + GROW_EXTRA; - buffer = (UChar32*) uprv_malloc(sizeof(UChar32) * bufferCapacity); + // else we keep the original contents on the memory failure. } /** @@ -1520,7 +1544,12 @@ void UnicodeSet::exclusiveOr(const UChar32* other, int32_t otherLen, int8_t pola if (isFrozen()) { return; } - ensureBufferCapacity(len + otherLen); + UErrorCode status = U_ZERO_ERROR; + ensureBufferCapacity(len + otherLen, status); + if (U_FAILURE(status)) { + return; + } + int32_t i = 0, j = 0, k = 0; UChar32 a = list[i++]; UChar32 b; @@ -1565,7 +1594,12 @@ void UnicodeSet::add(const UChar32* other, int32_t otherLen, int8_t polarity) { if (isFrozen()) { return; } - ensureBufferCapacity(len + otherLen); + UErrorCode status = U_ZERO_ERROR; + ensureBufferCapacity(len + otherLen, status); + if (U_FAILURE(status)) { + return; + } + int32_t i = 0, j = 0, k = 0; UChar32 a = list[i++]; UChar32 b = other[j++]; @@ -1673,7 +1707,12 @@ void UnicodeSet::retain(const UChar32* other, int32_t otherLen, int8_t polarity) if (isFrozen()) { return; } - ensureBufferCapacity(len + otherLen); + UErrorCode status = U_ZERO_ERROR; + ensureBufferCapacity(len + otherLen, status); + if (U_FAILURE(status)) { + return; + } + int32_t i = 0, j = 0, k = 0; UChar32 a = list[i++]; UChar32 b = other[j++]; diff --git a/icu4c/source/common/uvector.cpp b/icu4c/source/common/uvector.cpp index 028ef39f3b4..2e9a37147f5 100644 --- a/icu4c/source/common/uvector.cpp +++ b/icu4c/source/common/uvector.cpp @@ -323,24 +323,21 @@ int32_t UVector::indexOf(UHashTok key, int32_t startIndex, int8_t hint) const { } UBool UVector::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) { - if (capacity >= minimumCapacity) { - return TRUE; - } else { + if (capacity < minimumCapacity) { int32_t newCap = capacity * 2; if (newCap < minimumCapacity) { newCap = minimumCapacity; } - UHashTok* newElems = (UHashTok *)uprv_malloc(sizeof(UHashTok)*newCap); - if (newElems == 0) { + UHashTok* newElems = (UHashTok *)uprv_realloc(elements, sizeof(UHashTok)*newCap); + if (newElems == NULL) { + // We keep the original contents on the memory failure on realloc. status = U_MEMORY_ALLOCATION_ERROR; return FALSE; } - uprv_memcpy(newElems, elements, sizeof(elements[0]) * count); - uprv_free(elements); elements = newElems; capacity = newCap; - return TRUE; } + return TRUE; } /** diff --git a/icu4c/source/common/uvectr32.cpp b/icu4c/source/common/uvectr32.cpp index e0dd4cbb325..b9c0f751bb4 100644 --- a/icu4c/source/common/uvectr32.cpp +++ b/icu4c/source/common/uvectr32.cpp @@ -187,24 +187,21 @@ int32_t UVector32::indexOf(int32_t key, int32_t startIndex) const { UBool UVector32::expandCapacity(int32_t minimumCapacity, UErrorCode &status) { - if (capacity >= minimumCapacity) { - return TRUE; - } else { + if (capacity < minimumCapacity) { int32_t newCap = capacity * 2; if (newCap < minimumCapacity) { newCap = minimumCapacity; } - int32_t* newElems = (int32_t *)uprv_malloc(sizeof(int32_t)*newCap); - if (newElems == 0) { + int32_t* newElems = (int32_t *)uprv_realloc(elements, sizeof(int32_t)*newCap); + if (newElems == NULL) { + // We keep the original contents on the memory failure on realloc. status = U_MEMORY_ALLOCATION_ERROR; return FALSE; } - uprv_memcpy(newElems, elements, sizeof(elements[0]) * count); - uprv_free(elements); elements = newElems; capacity = newCap; - return TRUE; } + return TRUE; } /** diff --git a/icu4c/source/i18n/ucol.cpp b/icu4c/source/i18n/ucol.cpp index 609d0e243d3..4bbc72dd610 100644 --- a/icu4c/source/i18n/ucol.cpp +++ b/icu4c/source/i18n/ucol.cpp @@ -2996,7 +2996,14 @@ uint32_t ucol_prv_getSpecialCE(const UCollator *coll, UChar ch, uint32_t CE, col numTempBuf = (uint8_t *)uprv_malloc(sizeof(uint8_t) * numTempBufSize); uprv_memcpy(numTempBuf, stackNumTempBuf, UCOL_MAX_BUFFER); } else { - uprv_realloc(numTempBuf, numTempBufSize); + uint8_t *temp = (uint8_t *)uprv_realloc(numTempBuf, numTempBufSize); + if (temp == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + /* The original contents weren't freed. */ + uprv_free(temp); + return 0; + } + numTempBuf = temp; } } @@ -3575,16 +3582,24 @@ uint32_t ucol_prv_getSpecialPrevCE(const UCollator *coll, UChar ch, uint32_t CE, digVal = u_charDigitValue(char32); for(;;){ - // Make sure we have enough space. - if (digIndx >= ((numTempBufSize - 2) * 2) + 1) - { - numTempBufSize *= 2; - if (numTempBuf == stackNumTempBuf){ - numTempBuf = (uint8_t *)uprv_malloc(sizeof(uint8_t) * numTempBufSize); - uprv_memcpy(numTempBuf, stackNumTempBuf, UCOL_MAX_BUFFER); - }else - uprv_realloc(numTempBuf, numTempBufSize); - } + // Make sure we have enough space. + if (digIndx >= ((numTempBufSize - 2) * 2) + 1) + { + numTempBufSize *= 2; + if (numTempBuf == stackNumTempBuf){ + numTempBuf = (uint8_t *)uprv_malloc(sizeof(uint8_t) * numTempBufSize); + uprv_memcpy(numTempBuf, stackNumTempBuf, UCOL_MAX_BUFFER); + }else { + uint8_t *temp = (uint8_t *)uprv_realloc(numTempBuf, numTempBufSize); + if (temp == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + /* The original contents weren't freed. */ + uprv_free(temp); + return 0; + } + numTempBuf = temp; + } + } // Skip over trailing zeroes, and keep a count of them. if (digVal != 0) diff --git a/icu4c/source/test/intltest/v32test.cpp b/icu4c/source/test/intltest/v32test.cpp index c668a38ce64..cf00b45b5fa 100644 --- a/icu4c/source/test/intltest/v32test.cpp +++ b/icu4c/source/test/intltest/v32test.cpp @@ -1,6 +1,6 @@ /******************************************************************** * COPYRIGHT: - * Copyright (c) 2002-2003, International Business Machines Corporation and + * Copyright (c) 2002-2007, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ @@ -63,7 +63,7 @@ void UVector32Test::runIndexedTest( int32_t index, UBool exec, const char* &name #define TEST_ASSERT(expr) \ if ((expr)==FALSE) {\ - errln("RegexTest failure at line %d.\n", __LINE__);\ + errln("UVector32Test failure at line %d.\n", __LINE__);\ } //--------------------------------------------------------------------------- @@ -405,7 +405,7 @@ void UVector32Test::UVector32_API() { a->setSize(20000); int32_t *resizedBuf; resizedBuf = a->getBuffer(); - TEST_ASSERT(buf != resizedBuf); + //TEST_ASSERT(buf != resizedBuf); // The buffer might have been realloc'd TEST_ASSERT(resizedBuf[0] == 10); TEST_ASSERT(resizedBuf[1] == 20); diff --git a/icu4c/source/tools/ctestfw/ctest.c b/icu4c/source/tools/ctestfw/ctest.c index 44e66ab1768..bcfa4afab9f 100644 --- a/icu4c/source/tools/ctestfw/ctest.c +++ b/icu4c/source/tools/ctestfw/ctest.c @@ -571,7 +571,7 @@ static void *U_CALLCONV ctest_libRealloc(const void *context, void *mem, size_t printf("Reallocated %ld\n", (long)size); }*/ if (size >= MAX_MEMORY_ALLOCATION) { - free(mem); + /*free(mem);*/ /* Realloc doesn't free on failure. */ return NULL; } if (mem == NULL) {