diff --git a/source/common/ucnv.c b/source/common/ucnv.c index fb4bab88a78..57519279751 100644 --- a/source/common/ucnv.c +++ b/source/common/ucnv.c @@ -711,6 +711,7 @@ int32_t ucnv_fromUChars (const UConverter * converter, int32_t mySourceLength = 0; UConverter myConverter; char *myTarget = target; + char *myTarget_limit; int32_t targetCapacity = 0; if (U_FAILURE (*err)) @@ -741,6 +742,10 @@ int32_t ucnv_fromUChars (const UConverter * converter, } mySource_limit = mySource + mySourceLength; + myTarget_limit = target + targetSize; + + if(myTarget_limit < target) + myTarget_limit = U_MAX_PTR; /* ptr wrapped */ if (targetSize > 0) { @@ -771,6 +776,10 @@ int32_t ucnv_fromUChars (const UConverter * converter, char *target2_alias = target2; const char *target2_limit = target2 + CHUNK_SIZE; + + if(target2_limit < target2) + target2_limit = U_MAX_PTR; /* wrapped around */ + /*We use a stack allocated buffer around which we loop *(in case the output is greater than CHUNK_SIZE) */ @@ -812,6 +821,7 @@ int32_t ucnv_toUChars (const UConverter * converter, const char *mySource_limit = source + sourceSize; UConverter myConverter; UChar *myTarget = target; + UChar *myTarget_limit; int32_t targetCapacity; if (U_FAILURE (*err)) @@ -844,6 +854,11 @@ int32_t ucnv_toUChars (const UConverter * converter, /*Removes all state info on the UConverter */ ucnv_reset (&myConverter); + myTarget_limit = target + targetSize - 1; + + if(myTarget_limit < target) /* wrapped */ + myTarget_limit = U_MAX_PTR; + /*Not in pure pre-flight mode */ if (targetSize > 0) @@ -851,7 +866,7 @@ int32_t ucnv_toUChars (const UConverter * converter, ucnv_toUnicode (&myConverter, &myTarget, - target + targetSize - 1, /*Save a spot for the Null terminator */ + myTarget_limit, /*Save a spot for the Null terminator */ &mySource, mySource_limit, NULL, diff --git a/source/common/unistr.cpp b/source/common/unistr.cpp index d0490681887..b77cd7daacc 100644 --- a/source/common/unistr.cpp +++ b/source/common/unistr.cpp @@ -759,6 +759,7 @@ UnicodeString::extract(UTextOffset start, const UChar *mySource = getArrayStart() + start; const UChar *mySourceEnd = mySource + length; char *myTarget = dst; + char *myTargetLimit; UErrorCode status = U_ZERO_ERROR; int32_t arraySize = 0x0FFFFFFF; @@ -781,6 +782,11 @@ UnicodeString::extract(UTextOffset start, return 0; } + myTargetLimit = myTarget + arraySize; + + if(myTargetLimit < myTarget) /* ptr wrapped around: pin to U_MAX_PTR */ + myTargetLimit = U_MAX_PTR; + // perform the conversion // there is no loop here since we assume the buffer is large enough diff --git a/source/common/ustring.c b/source/common/ustring.c index eefbee9bc35..66c69f0a48f 100644 --- a/source/common/ustring.c +++ b/source/common/ustring.c @@ -27,7 +27,7 @@ static UConverter* _defaultConverter = NULL; static UErrorCode gErr = U_ZERO_ERROR; -#define MAX_STRLEN 0x00FFFFFF +#define MAX_STRLEN 0x0FFFFFFF /*Lazy evaluating macro for the default converter*/ #define defaultConverter (_defaultConverter==NULL)?_defaultConverter=ucnv_open(NULL, &gErr):_defaultConverter diff --git a/source/common/utypes.h b/source/common/utypes.h index 72412788022..010047edab5 100644 --- a/source/common/utypes.h +++ b/source/common/utypes.h @@ -135,6 +135,9 @@ typedef uint16_t UChar; #endif #endif +/* Maximum value of a (void*) - use to indicate the limit of + an 'infinite' buffer. */ +#define U_MAX_PTR ((void*)-1) /*===========================================================================*/ /* Calendar/TimeZone data types */