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:
parent
eed1a93ad3
commit
389c986a20
@ -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 */
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user