ICU-96 fix for a sneaky bug in collation iterator

X-SVN-Rev: 4022
This commit is contained in:
Vladimir Weinstein 2001-03-12 08:58:37 +00:00
parent eb71df4aae
commit 13ee1e9a8d
3 changed files with 22 additions and 5 deletions

View File

@ -825,8 +825,13 @@ uint32_t ucol_getPrevUCA(UChar ch, collIterate *collationSource,
if (UTF_IS_SECOND_SURROGATE(ch))
{
UChar *temp = collationSource->pos;
if (((collationSource->string < temp) ||
(collationSource->writableBuffer < temp)) &&
/* This is where the s***t hits the fan */
/* it turns out, the first part of the if can be satisfied even if we're */
/* at the beggining of the string */
/* we have to make sure we know what is the situation we're in */
/* quick fix is by using isUsingWritable, as shown below */
if ((((collationSource->string < temp && collationSource->isUsingWritable == FALSE)) ||
((collationSource->writableBuffer < temp && collationSource->isUsingWritable == TRUE))) &&
(UTF_IS_FIRST_SURROGATE(prevChar = *(collationSource->pos - 1))))
{
uint32_t cp = ((prevChar << 10UL) + ch - ((0xd800 << 10UL) + 0xdc00));
@ -1067,6 +1072,7 @@ uint32_t getSpecialPrevCE(const UCollator *coll, uint32_t CE,
source->pos = targetCopy;
source->len = targetCopy;
source->CEpos = source->toReturn = source->CEs;
source->isUsingWritable = TRUE;
CE = UCOL_IGNORABLE;
}
else

View File

@ -76,6 +76,7 @@ struct collIterate {
uint32_t CEs[UCOL_EXPAND_CE_BUFFER_SIZE]; /* This is where we store CEs */
UBool isThai; /* Have we already encountered a Thai prevowel */
UBool isWritable; /* is the source buffer writable? */
UBool isUsingWritable; /* are we currently using writable buffer */
UChar stackWritableBuffer[UCOL_WRITABLE_BUFFER_SIZE]; /* A writable buffer. */
UChar *writableBuffer;
const UCollator *coll;
@ -222,6 +223,7 @@ struct incrementalContext {
(s)->isWritable = (isSourceWritable); \
(s)->writableBuffer = (s)->stackWritableBuffer; \
(s)->coll = (collator); \
(s)->isUsingWritable = FALSE; \
}
/* a macro that gets a simple CE */
@ -267,7 +269,10 @@ struct incrementalContext {
} \
} \
else { \
if ((data).pos == (data).string || (data).pos == (data).writableBuffer) {\
/* weiv tentatively */\
/*if ((data).pos == (data).string || (data).pos == (data).writableBuffer) {*/\
if (((data).pos <= (data).string && (data).isUsingWritable == FALSE) || \
((data).pos <= (data).writableBuffer && (data).isUsingWritable = TRUE)) {\
(order) = UCOL_NO_MORE_CES; \
} \
else { \

View File

@ -13,6 +13,7 @@
* instead of calling the equivalent c++ api (coleitr.h)
******************************************************************************/
#include <stdio.h>
#include "unicode/ucoleitr.h"
#include "unicode/ustring.h"
#include "unicode/sortkey.h"
@ -174,9 +175,14 @@ ucol_previous(UCollationElements *elems,
}
else
{
if (data->pos == data->string || data->pos == data->writableBuffer)
/* weiv tentatively changed */
/*if (data->pos == data->string || data->pos == data->writableBuffer)*/
if ((data->pos <= data->string && data->isUsingWritable == FALSE) || (data->pos <= data->writableBuffer && data->isUsingWritable == TRUE)) {
if ((data->pos < data->string && data->isUsingWritable == FALSE) || (data->pos < data->writableBuffer && data->isUsingWritable == TRUE)) {
fprintf(stderr, "less pos:%x string:%x writable:%x\n", data->pos, data->string, data->writableBuffer);
}
(result) = UCOL_NO_MORE_CES;
else
} else
{
data->pos --;