mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-18 11:14:22 +00:00
ICU-6188 Improve error handling for ucol_getSortKey when memory allocation fails.
X-SVN-Rev: 23464
This commit is contained in:
parent
6520f1df57
commit
ba02cd8038
3 changed files with 87 additions and 44 deletions
|
@ -4558,6 +4558,8 @@ inline uint8_t *packFrench(uint8_t *primaries, uint8_t *primEnd, uint8_t *second
|
|||
return primaries;
|
||||
}
|
||||
|
||||
#define DEFAULT_ERROR_SIZE_FOR_CALCSORTKEY -1
|
||||
|
||||
/* This is the sortkey work horse function */
|
||||
U_CFUNC int32_t U_CALLCONV
|
||||
ucol_calcSortKey(const UCollator *coll,
|
||||
|
@ -4956,11 +4958,8 @@ ucol_calcSortKey(const UCollator *coll,
|
|||
primarySafeEnd--;
|
||||
}
|
||||
} else {
|
||||
IInit_collIterate(coll, (UChar *)source, len, &s);
|
||||
if(source == normSource) {
|
||||
s.flags &= ~UCOL_ITER_NORM;
|
||||
}
|
||||
sortKeySize = ucol_getSortKeySize(coll, &s, sortKeySize, strength, len);
|
||||
/* We ran out of memory!? We can't recover. */
|
||||
sortKeySize = DEFAULT_ERROR_SIZE_FOR_CALCSORTKEY;
|
||||
finished = TRUE;
|
||||
break;
|
||||
}
|
||||
|
@ -4978,23 +4977,19 @@ ucol_calcSortKey(const UCollator *coll,
|
|||
frenchEndOffset = frenchEndPtr - secStart;
|
||||
}
|
||||
secStart = reallocateBuffer(&secondaries, secStart, second, &secSize, 2*secSize, status);
|
||||
terStart = reallocateBuffer(&tertiaries, terStart, tert, &terSize, 2*terSize, status);
|
||||
caseStart = reallocateBuffer(&cases, caseStart, caseB, &caseSize, 2*caseSize, status);
|
||||
quadStart = reallocateBuffer(&quads, quadStart, quad, &quadSize, 2*quadSize, status);
|
||||
if(U_FAILURE(*status)) {
|
||||
/* We ran out of memory!? We can't recover. */
|
||||
sortKeySize = DEFAULT_ERROR_SIZE_FOR_CALCSORTKEY;
|
||||
break;
|
||||
}
|
||||
if (frenchStartPtr != NULL) {
|
||||
frenchStartPtr = secStart + frenchStartOffset;
|
||||
frenchEndPtr = secStart + frenchEndOffset;
|
||||
}
|
||||
|
||||
terStart = reallocateBuffer(&tertiaries, terStart, tert, &terSize, 2*terSize, status);
|
||||
caseStart = reallocateBuffer(&cases, caseStart, caseB, &caseSize, 2*caseSize, status);
|
||||
quadStart = reallocateBuffer(&quads, quadStart, quad, &quadSize, 2*quadSize, status);
|
||||
minBufferSize *= 2;
|
||||
if(U_FAILURE(*status)) { // if we cannot reallocate buffers, we can at least give the sortkey size
|
||||
IInit_collIterate(coll, (UChar *)source, len, &s);
|
||||
if(source == normSource) {
|
||||
s.flags &= ~UCOL_ITER_NORM;
|
||||
}
|
||||
sortKeySize = ucol_getSortKeySize(coll, &s, sortKeySize, strength, len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5028,6 +5023,11 @@ ucol_calcSortKey(const UCollator *coll,
|
|||
uprv_memcpy(primaries, secStart, secsize);
|
||||
primaries += secsize;
|
||||
}
|
||||
else {
|
||||
/* We ran out of memory!? We can't recover. */
|
||||
sortKeySize = DEFAULT_ERROR_SIZE_FOR_CALCSORTKEY;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
*status = U_BUFFER_OVERFLOW_ERROR;
|
||||
}
|
||||
|
@ -5043,6 +5043,11 @@ ucol_calcSortKey(const UCollator *coll,
|
|||
if(U_SUCCESS(*status)) {
|
||||
primaries = packFrench(primaries, primStart+resultLength, secondaries, &secsize, frenchStartPtr, frenchEndPtr);
|
||||
}
|
||||
else {
|
||||
/* We ran out of memory!? We can't recover. */
|
||||
sortKeySize = DEFAULT_ERROR_SIZE_FOR_CALCSORTKEY;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
*status = U_BUFFER_OVERFLOW_ERROR;
|
||||
}
|
||||
|
@ -5065,6 +5070,11 @@ ucol_calcSortKey(const UCollator *coll,
|
|||
*(primaries++) = UCOL_LEVELTERMINATOR;
|
||||
uprv_memcpy(primaries, caseStart, casesize);
|
||||
}
|
||||
else {
|
||||
/* We ran out of memory!? We can't recover. */
|
||||
sortKeySize = DEFAULT_ERROR_SIZE_FOR_CALCSORTKEY;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
*status = U_BUFFER_OVERFLOW_ERROR;
|
||||
}
|
||||
|
@ -5101,6 +5111,11 @@ ucol_calcSortKey(const UCollator *coll,
|
|||
*(primaries++) = UCOL_LEVELTERMINATOR;
|
||||
uprv_memcpy(primaries, terStart, tersize);
|
||||
}
|
||||
else {
|
||||
/* We ran out of memory!? We can't recover. */
|
||||
sortKeySize = DEFAULT_ERROR_SIZE_FOR_CALCSORTKEY;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
*status = U_BUFFER_OVERFLOW_ERROR;
|
||||
}
|
||||
|
@ -5128,6 +5143,11 @@ ucol_calcSortKey(const UCollator *coll,
|
|||
*(primaries++) = UCOL_LEVELTERMINATOR;
|
||||
uprv_memcpy(primaries, quadStart, quadsize);
|
||||
}
|
||||
else {
|
||||
/* We ran out of memory!? We can't recover. */
|
||||
sortKeySize = DEFAULT_ERROR_SIZE_FOR_CALCSORTKEY;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
*status = U_BUFFER_OVERFLOW_ERROR;
|
||||
}
|
||||
|
@ -5147,6 +5167,11 @@ ucol_calcSortKey(const UCollator *coll,
|
|||
*(primaries++) = UCOL_LEVELTERMINATOR;
|
||||
u_writeIdenticalLevelRun(s.string, len, primaries);
|
||||
}
|
||||
else {
|
||||
/* We ran out of memory!? We can't recover. */
|
||||
sortKeySize = DEFAULT_ERROR_SIZE_FOR_CALCSORTKEY;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
*status = U_BUFFER_OVERFLOW_ERROR;
|
||||
}
|
||||
|
@ -5170,6 +5195,10 @@ ucol_calcSortKey(const UCollator *coll,
|
|||
}
|
||||
|
||||
cleanup:
|
||||
if (allocateSKBuffer == FALSE && resultLength > 0 && U_FAILURE(*status) && *status != U_BUFFER_OVERFLOW_ERROR) {
|
||||
/* NULL terminate for safety */
|
||||
**result = 0;
|
||||
}
|
||||
if(terStart != tert) {
|
||||
uprv_free(terStart);
|
||||
uprv_free(secStart);
|
||||
|
@ -5436,11 +5465,8 @@ ucol_calcSortKeySimpleTertiary(const UCollator *coll,
|
|||
*result = primStart;
|
||||
primarySafeEnd = primStart + resultLength - 2;
|
||||
} else {
|
||||
IInit_collIterate(coll, (UChar *)source, len, &s);
|
||||
if(source == normSource) {
|
||||
s.flags &= ~UCOL_ITER_NORM;
|
||||
}
|
||||
sortKeySize = ucol_getSortKeySize(coll, &s, sortKeySize, coll->strength, len);
|
||||
/* We ran out of memory!? We can't recover. */
|
||||
sortKeySize = DEFAULT_ERROR_SIZE_FOR_CALCSORTKEY;
|
||||
finished = TRUE;
|
||||
break;
|
||||
}
|
||||
|
@ -5455,11 +5481,8 @@ ucol_calcSortKeySimpleTertiary(const UCollator *coll,
|
|||
terStart = reallocateBuffer(&tertiaries, terStart, tert, &terSize, 2*terSize, status);
|
||||
minBufferSize *= 2;
|
||||
if(U_FAILURE(*status)) { // if we cannot reallocate buffers, we can at least give the sortkey size
|
||||
IInit_collIterate(coll, (UChar *)source, len, &s);
|
||||
if(source == normSource) {
|
||||
s.flags &= ~UCOL_ITER_NORM;
|
||||
}
|
||||
sortKeySize = ucol_getSortKeySize(coll, &s, sortKeySize, coll->strength, len);
|
||||
/* We ran out of memory!? We can't recover. */
|
||||
sortKeySize = DEFAULT_ERROR_SIZE_FOR_CALCSORTKEY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -5489,6 +5512,11 @@ ucol_calcSortKeySimpleTertiary(const UCollator *coll,
|
|||
*result = primStart;
|
||||
uprv_memcpy(primaries, secStart, secsize);
|
||||
}
|
||||
else {
|
||||
/* We ran out of memory!? We can't recover. */
|
||||
sortKeySize = DEFAULT_ERROR_SIZE_FOR_CALCSORTKEY;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
*status = U_BUFFER_OVERFLOW_ERROR;
|
||||
}
|
||||
|
@ -5523,6 +5551,11 @@ ucol_calcSortKeySimpleTertiary(const UCollator *coll,
|
|||
*(primaries++) = UCOL_LEVELTERMINATOR;
|
||||
uprv_memcpy(primaries, terStart, tersize);
|
||||
}
|
||||
else {
|
||||
/* We ran out of memory!? We can't recover. */
|
||||
sortKeySize = DEFAULT_ERROR_SIZE_FOR_CALCSORTKEY;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
*status = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
@ -5531,6 +5564,24 @@ ucol_calcSortKeySimpleTertiary(const UCollator *coll,
|
|||
*(primaries++) = '\0';
|
||||
}
|
||||
|
||||
if(allocateSKBuffer == TRUE) {
|
||||
*result = (uint8_t*)uprv_malloc(sortKeySize);
|
||||
/* test for NULL */
|
||||
if (*result == NULL) {
|
||||
*status = U_MEMORY_ALLOCATION_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
uprv_memcpy(*result, primStart, sortKeySize);
|
||||
if(primStart != prim) {
|
||||
uprv_free(primStart);
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (allocateSKBuffer == FALSE && resultLength > 0 && U_FAILURE(*status) && *status != U_BUFFER_OVERFLOW_ERROR) {
|
||||
/* NULL terminate for safety */
|
||||
**result = 0;
|
||||
}
|
||||
if(terStart != tert) {
|
||||
uprv_free(terStart);
|
||||
uprv_free(secStart);
|
||||
|
@ -5540,19 +5591,6 @@ ucol_calcSortKeySimpleTertiary(const UCollator *coll,
|
|||
uprv_free(normSource);
|
||||
}
|
||||
|
||||
if(allocateSKBuffer == TRUE) {
|
||||
*result = (uint8_t*)uprv_malloc(sortKeySize);
|
||||
/* test for NULL */
|
||||
if (*result == NULL) {
|
||||
*status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return sortKeySize;
|
||||
}
|
||||
uprv_memcpy(*result, primStart, sortKeySize);
|
||||
if(primStart != prim) {
|
||||
uprv_free(primStart);
|
||||
}
|
||||
}
|
||||
|
||||
return sortKeySize;
|
||||
}
|
||||
|
||||
|
@ -6571,8 +6609,7 @@ ucol_setUpLatinOne(UCollator *coll, UErrorCode *status) {
|
|||
UChar ch = 0;
|
||||
UCollationElements *it = ucol_openElements(coll, &ch, 1, status);
|
||||
// Check for null pointer
|
||||
if (it == NULL) {
|
||||
*status = U_MEMORY_ALLOCATION_ERROR;
|
||||
if (U_FAILURE(*status)) {
|
||||
return FALSE;
|
||||
}
|
||||
uprv_memset(coll->latinOneCEs, 0, sizeof(uint32_t)*coll->latinOneTableLen*3);
|
||||
|
|
|
@ -678,7 +678,7 @@ ucol_normalizeShortDefinitionString(const char *source,
|
|||
int32_t capacity,
|
||||
UParseError *parseError,
|
||||
UErrorCode *status);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get a sort key for a string from a UCollator.
|
||||
|
@ -688,7 +688,9 @@ ucol_normalizeShortDefinitionString(const char *source,
|
|||
* @param sourceLength The length of source, or -1 if null-terminated.
|
||||
* @param result A pointer to a buffer to receive the attribute.
|
||||
* @param resultLength The maximum size of result.
|
||||
* @return The size needed to fully store the sort key..
|
||||
* @return The size needed to fully store the sort key.
|
||||
* If there was an internal error generating the sort key,
|
||||
* a negative value is returned.
|
||||
* @see ucol_keyHashCode
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
|
|
|
@ -3838,6 +3838,10 @@ static void TestHebrewUCA(void) {
|
|||
int32_t sizeUTF16[3];
|
||||
|
||||
UCollator *coll = ucol_open("", &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("Could not open UCA collation %s\n", u_errorName(status));
|
||||
return;
|
||||
}
|
||||
/*ucol_setAttribute(coll, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);*/
|
||||
|
||||
for(i = 0; i < sizeof(first)/sizeof(first[0]); i++) {
|
||||
|
|
Loading…
Add table
Reference in a new issue