ICU-6076 Fix some realloc issues.

X-SVN-Rev: 23086
This commit is contained in:
George Rhoten 2007-12-14 09:23:07 +00:00
parent a1eb6975ae
commit 6112b5685d
6 changed files with 97 additions and 49 deletions

View File

@ -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++];

View File

@ -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;
}
/**

View File

@ -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;
}
/**

View File

@ -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)

View File

@ -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);

View File

@ -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) {