ICU-3794 UNormIterator bug in buffer contents moving

X-SVN-Rev: 15647
This commit is contained in:
Markus Scherer 2004-05-31 23:25:31 +00:00
parent 1c32f74262
commit a8e00a0bba
2 changed files with 30 additions and 17 deletions

View File

@ -1,7 +1,7 @@
/*
*******************************************************************************
*
* Copyright (C) 2003, International Business Machines
* Copyright (C) 2003-2004, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@ -137,7 +137,7 @@ moveContentsTowardStart(UCharIterator *api, UChar chars[], uint32_t states[], in
srcIndex=delta;
if(srcIndex>api->start) {
/* look for a position in the arrays with a known state */
while(srcIndex<limit && chars[srcIndex]==UITER_NO_STATE) {
while(srcIndex<limit && states[srcIndex]==UITER_NO_STATE) {
++srcIndex;
}
}
@ -165,7 +165,7 @@ moveContentsTowardEnd(UCharIterator *api, UChar chars[], uint32_t states[], int3
srcIndex=destIndex-delta;
if(srcIndex<api->limit) {
/* look for a position in the arrays with a known state */
while(srcIndex>start && chars[srcIndex]==UITER_NO_STATE) {
while(srcIndex>start && states[srcIndex]==UITER_NO_STATE) {
--srcIndex;
}
}
@ -191,16 +191,15 @@ readNext(UNormIterator *uni, UCharIterator *iter) {
UCharIterator *api=&uni->api;
/* make capacity/4 room at the end of the arrays */
int32_t limit, capacity, room, delta;
int32_t limit, capacity, room;
UErrorCode errorCode;
limit=api->limit;
capacity=uni->capacity;
room=capacity/4;
delta=room-(capacity-limit);
if(delta>0) {
if(room>(capacity-limit)) {
/* move array contents to make room */
moveContentsTowardStart(api, uni->chars, uni->states, delta);
moveContentsTowardStart(api, uni->chars, uni->states, room);
api->index=limit=api->limit;
uni->hasPrevious=TRUE;
}
@ -262,16 +261,15 @@ readPrevious(UNormIterator *uni, UCharIterator *iter) {
UCharIterator *api=&uni->api;
/* make capacity/4 room at the start of the arrays */
int32_t start, capacity, room, delta;
int32_t start, capacity, room;
UErrorCode errorCode;
start=api->start;
capacity=uni->capacity;
room=capacity/4;
delta=room-start;
if(delta>0) {
if(room>start) {
/* move array contents to make room */
moveContentsTowardEnd(api, uni->chars, uni->states, delta);
moveContentsTowardEnd(api, uni->chars, uni->states, room);
api->index=start=api->start;
uni->hasNext=TRUE;
}

View File

@ -1,7 +1,7 @@
/*
******************************************************************************
*
* Copyright (C) 2002-2003, International Business Machines
* Copyright (C) 2002-2004, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
@ -1618,6 +1618,16 @@ compareIterNoIndexes(UCharIterator *iter1, const char *n1,
return;
}
/* iterate backward */
do {
c1=iter1->previous(iter1);
c2=iter2->previous(iter2);
if(c1!=c2) {
log_err("%s->previous()=U+%04x != U+%04x=%s->previous() at %d\n", n1, c1, c2, n2, iter1->getIndex(iter1, UITER_CURRENT));
return;
}
} while(c1>=0);
/* back to the middle */
iter1->move(iter1, middle, UITER_ZERO);
iter2->move(iter2, middle, UITER_ZERO);
@ -1687,7 +1697,7 @@ compareIterNoIndexes(UCharIterator *iter1, const char *n1,
static void
testUNormIteratorWithText(const UChar *text, int32_t textLength, int32_t middle,
const char *name1, const char *n2) {
UChar buffer[300];
UChar buffer[600];
char name2[40];
UCharIterator iter1, iter2, *iter;
@ -1747,7 +1757,7 @@ TestUNormIterator() {
0x6e, 0xd900, 0x6a, 0xdc00, 0xd900, 0xdc00, 0x61
};
UChar longText[300];
UChar longText[600];
int32_t i, middle, length;
length=LENGTHOF(text);
@ -1761,13 +1771,18 @@ TestUNormIterator() {
longText[middle+i]=0x30a; /* insert many rings between 'A-ring' and cedilla */
}
memcpy(longText+middle+i, text+middle, (LENGTHOF(text)-middle)*U_SIZEOF_UCHAR);
length=LENGTHOF(text)+i;
testUNormIteratorWithText(longText, length, length/2, "UCharIterLong", "UNormIterLong1");
/* append another copy of this string for more overflows */
memcpy(longText+length, longText, length*U_SIZEOF_UCHAR);
length*=2;
/* the first test of the following two starts at length/4, inside the sea of combining rings */
testUNormIteratorWithText(longText, length, length/4, "UCharIterLong", "UNormIterLong1");
testUNormIteratorWithText(longText, length, length, "UCharIterLongEnd", "UNormIterLongEnd1");
length=LENGTHOF(surrogateText);
testUNormIteratorWithText(surrogateText, length, length/2, "UCharIterSurr", "UNormIterSurr1");
testUNormIteratorWithText(surrogateText, length, length/4, "UCharIterSurr", "UNormIterSurr1");
testUNormIteratorWithText(surrogateText, length, length, "UCharIterSurrEnd", "UNormIterSurrEnd1");
}