ICU-8445 Fix size of UCOL_CASE_MAX_BUFFER w.r.t UCOL_MAX_BUFFER; fix warning about collResult

X-SVN-Rev: 29756
This commit is contained in:
Peter Edberg 2011-04-07 18:33:27 +00:00
parent eed1a93ad3
commit 389c986a20
2 changed files with 115 additions and 3 deletions

View File

@ -205,7 +205,17 @@
#define UCOL_PRIMARY_MAX_BUFFER 8*UCOL_MAX_BUFFER
#define UCOL_SECONDARY_MAX_BUFFER UCOL_MAX_BUFFER
#define UCOL_TERTIARY_MAX_BUFFER UCOL_MAX_BUFFER
/*
#define UCOL_CASE_MAX_BUFFER UCOL_MAX_BUFFER/4
UCOL_CASE_MAX_BUFFER as previously defined above was too small. A single collation element can
generate two caseShift values, and UCOL_CASE_SHIFT_START (=7) caseShift values are compressed into
one byte. UCOL_MAX_BUFFER should effectively be multipled by 2/UCOL_CASE_SHIFT_START (2/7), not 1/4.
Perhaps UCOL_CASE_SHIFT_START used to be 8; then this would have been correct. We should dynamically
define UCOL_CASE_MAX_BUFFER in terms of both UCOL_MAX_BUFFER and UCOL_CASE_SHIFT_START. Since
UCOL_CASE_SHIFT_START is defined lower down, we move the real definition of UCOL_CASE_MAX_BUFFER
after it, further down.
*/
#define UCOL_QUAD_MAX_BUFFER 2*UCOL_MAX_BUFFER
#define UCOL_NORMALIZATION_GROWTH 2
@ -410,6 +420,15 @@ uprv_init_pce(const struct UCollationElements *elems);
#define UCOL_CASE_BYTE_START 0x80
#define UCOL_CASE_SHIFT_START 7
/*
The definition of UCOL_CASE_MAX_BUFFER is moved down here so it can use UCOL_CASE_SHIFT_START.
A single collation element can generate two caseShift values, and UCOL_CASE_SHIFT_START caseShift
values are compressed into one byte. The UCOL_CASE_MAX_BUFFER should effectively be UCOL_MAX_BUFFER
multipled by 2/UCOL_CASE_SHIFT_START, with suitable rounding up.
*/
#define UCOL_CASE_MAX_BUFFER (((2*UCOL_MAX_BUFFER) + UCOL_CASE_SHIFT_START - 1)/UCOL_CASE_SHIFT_START)
#define UCOL_IGNORABLE 0
/* get weights from a CE */

View File

@ -5912,7 +5912,6 @@ static void TestNonLeadBytesDuringCollationReordering(void)
UErrorCode status = U_ZERO_ERROR;
UCollator *myCollation;
int32_t reorderCodes[1] = {USCRIPT_GREEK};
UCollationResult collResult;
uint8_t baseKey[256];
uint32_t baseKeyLength;
@ -5943,7 +5942,7 @@ static void TestNonLeadBytesDuringCollationReordering(void)
reorderKeyLength = ucol_getSortKey(myCollation, testString, LEN(testString), reorderKey, 256);
if (baseKeyLength != reorderKeyLength) {
log_err("Key lengths not the same during reordering.\n", collResult);
log_err("Key lengths not the same during reordering.\n");
return;
}
@ -5972,7 +5971,7 @@ static void TestNonLeadBytesDuringCollationReordering(void)
reorderKeyLength = ucol_getSortKey(myCollation, testString, LEN(testString), reorderKey, 256);
if (baseKeyLength != reorderKeyLength) {
log_err("Key lengths not the same during reordering.\n", collResult);
log_err("Key lengths not the same during reordering.\n");
return;
}
@ -6648,6 +6647,99 @@ static void TestImportWithType(void)
}
/* 'IV INTERNATIONAL SCIENTIFIC - PRACTICAL CONFERENCE "GEOPOLITICS, GEOECONOMICS AND INTERNATIONAL RELATIONS PROBLEMS" 22-23 June 2010, St. Petersburg, Russia' */
static const UChar longUpperStr1[]= { /* 155 chars */
0x49, 0x56, 0x20, 0x49, 0x4E, 0x54, 0x45, 0x52, 0x4E, 0x41, 0x54, 0x49, 0x4F, 0x4E, 0x41, 0x4C,
0x20, 0x53, 0x43, 0x49, 0x45, 0x4E, 0x54, 0x49, 0x46, 0x49, 0x43, 0x20, 0x2D, 0x20, 0x50, 0x52,
0x41, 0x43, 0x54, 0x49, 0x43, 0x41, 0x4C, 0x20, 0x43, 0x4F, 0x4E, 0x46, 0x45, 0x52, 0x45, 0x4E,
0x43, 0x45, 0x20, 0x22, 0x47, 0x45, 0x4F, 0x50, 0x4F, 0x4C, 0x49, 0x54, 0x49, 0x43, 0x53, 0x2C,
0x20, 0x47, 0x45, 0x4F, 0x45, 0x43, 0x4F, 0x4E, 0x4F, 0x4D, 0x49, 0x43, 0x53, 0x20, 0x41, 0x4E,
0x44, 0x20, 0x49, 0x4E, 0x54, 0x45, 0x52, 0x4E, 0x41, 0x54, 0x49, 0x4F, 0x4E, 0x41, 0x4C, 0x20,
0x52, 0x45, 0x4C, 0x41, 0x54, 0x49, 0x4F, 0x4E, 0x53, 0x20, 0x50, 0x52, 0x4F, 0x42, 0x4C, 0x45,
0x4D, 0x53, 0x22, 0x20, 0x32, 0x32, 0x2D, 0x32, 0x33, 0x20, 0x4A, 0x75, 0x6E, 0x65, 0x20, 0x32,
0x30, 0x31, 0x30, 0x2C, 0x20, 0x53, 0x74, 0x2E, 0x20, 0x50, 0x65, 0x74, 0x65, 0x72, 0x73, 0x62,
0x75, 0x72, 0x67, 0x2C, 0x20, 0x52, 0x75, 0x73, 0x73, 0x69, 0x61
};
/* 'BACEDIFOGUHAJEKILOMUNAPE ' with diacritics on vowels, repeated 5 times */
static const UChar longUpperStr2[]= { /* 125 chars, > 128 collation elements */
0x42,0xC1,0x43,0xC9,0x44,0xCD,0x46,0xD3,0x47,0xDA,0x48,0xC0,0x4A,0xC8,0x4B,0xCC,0x4C,0xD2,0x4D,0xD9,0x4E,0xC2,0x50,0xCA,0x20,
0x42,0xC1,0x43,0xC9,0x44,0xCD,0x46,0xD3,0x47,0xDA,0x48,0xC0,0x4A,0xC8,0x4B,0xCC,0x4C,0xD2,0x4D,0xD9,0x4E,0xC2,0x50,0xCA,0x20,
0x42,0xC1,0x43,0xC9,0x44,0xCD,0x46,0xD3,0x47,0xDA,0x48,0xC0,0x4A,0xC8,0x4B,0xCC,0x4C,0xD2,0x4D,0xD9,0x4E,0xC2,0x50,0xCA,0x20,
0x42,0xC1,0x43,0xC9,0x44,0xCD,0x46,0xD3,0x47,0xDA,0x48,0xC0,0x4A,0xC8,0x4B,0xCC,0x4C,0xD2,0x4D,0xD9,0x4E,0xC2,0x50,0xCA,0x20,
0x42,0xC1,0x43,0xC9,0x44,0xCD,0x46,0xD3,0x47,0xDA,0x48,0xC0,0x4A,0xC8,0x4B,0xCC,0x4C,0xD2,0x4D,0xD9,0x4E,0xC2,0x50,0xCA,0x20
};
/* 'ABCDEFGHIJKLMNOPQRSTUVWXYZ ' repeated 12 times */
static const UChar longUpperStr3[]= { /* 324 chars */
0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x20,
0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x20,
0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x20,
0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x20,
0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x20,
0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x20,
0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x20,
0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x20,
0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x20,
0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x20,
0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x20,
0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x20
};
#define MY_ARRAY_LEN(array) (sizeof(array)/sizeof(array[0]))
typedef struct {
const UChar * longUpperStrPtr;
int32_t longUpperStrLen;
} LongUpperStrItem;
/* String pointers must be in reverse collation order of the corresponding strings */
static const LongUpperStrItem longUpperStrItems[] = {
{ longUpperStr1, MY_ARRAY_LEN(longUpperStr1) },
{ longUpperStr2, MY_ARRAY_LEN(longUpperStr2) },
{ longUpperStr3, MY_ARRAY_LEN(longUpperStr3) },
{ NULL, 0 }
};
enum { kCollKeyLenMax = 800 }; /* longest expected is 749, but may change with collation changes */
/* Text fix for #8445; without fix, could have crash due to stack or heap corruption */
static void TestCaseLevelBufferOverflow(void)
{
UErrorCode status = U_ZERO_ERROR;
UCollator * ucol = ucol_open("root", &status);
if ( U_SUCCESS(status) ) {
ucol_setAttribute(ucol, UCOL_CASE_LEVEL, UCOL_ON, &status);
if ( U_SUCCESS(status) ) {
const LongUpperStrItem * itemPtr;
uint8_t sortKeyA[kCollKeyLenMax], sortKeyB[kCollKeyLenMax];
for ( itemPtr = longUpperStrItems; itemPtr->longUpperStrPtr != NULL; itemPtr++ ) {
int32_t sortKeyLen;
if (itemPtr > longUpperStrItems) {
uprv_strcpy((char *)sortKeyB, (char *)sortKeyA);
}
sortKeyLen = ucol_getSortKey(ucol, itemPtr->longUpperStrPtr, itemPtr->longUpperStrLen, sortKeyA, kCollKeyLenMax);
if (sortKeyLen <= 0 || sortKeyLen > kCollKeyLenMax) {
log_err("ERROR sort key length from ucol_getSortKey is %d\n", sortKeyLen);
break;
}
if ( itemPtr > longUpperStrItems ) {
int compareResult = uprv_strcmp((char *)sortKeyA, (char *)sortKeyB);
if (compareResult >= 0) {
log_err("ERROR in sort key comparison result, expected -1, got %d\n", compareResult);
}
}
}
} else {
log_err_status(status, "ERROR in ucol_setAttribute UCOL_CASE_LEVEL on: %s\n", myErrorName(status));
}
ucol_close(ucol);
} else {
log_err_status(status, "ERROR in ucol_open for root: %s\n", myErrorName(status));
}
}
#define TEST(x) addTest(root, &x, "tscoll/cmsccoll/" # x)
void addMiscCollTest(TestNode** root)
@ -6749,6 +6841,7 @@ void addMiscCollTest(TestNode** root)
TEST(TestNonScriptReorder);
TEST(TestHaniReorder);
TEST(TestMultipleReorder);
TEST(TestCaseLevelBufferOverflow);
}
#endif /* #if !UCONFIG_NO_COLLATION */