diff options
Diffstat (limited to 'deps/icu-small/source/common/ucnv_u8.cpp')
-rw-r--r-- | deps/icu-small/source/common/ucnv_u8.cpp | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/deps/icu-small/source/common/ucnv_u8.cpp b/deps/icu-small/source/common/ucnv_u8.cpp index 866cf81659..c7ef87fd50 100644 --- a/deps/icu-small/source/common/ucnv_u8.cpp +++ b/deps/icu-small/source/common/ucnv_u8.cpp @@ -28,6 +28,7 @@ #include "unicode/utf.h" #include "unicode/utf8.h" #include "unicode/utf16.h" +#include "uassert.h" #include "ucnv_bld.h" #include "ucnv_cnv.h" #include "cmemory.h" @@ -694,7 +695,9 @@ ucnv_UTF8FromUTF8(UConverterFromUnicodeArgs *pFromUArgs, // Use a single counter for source and target, counting the minimum of // the source length and the target capacity. // Let the standard converter handle edge cases. + const uint8_t *limit=sourceLimit; if(count>targetCapacity) { + limit-=(count-targetCapacity); count=targetCapacity; } @@ -707,11 +710,11 @@ ucnv_UTF8FromUTF8(UConverterFromUnicodeArgs *pFromUArgs, // sequence from the previous buffer. int32_t length=count-toULimit; if(length>0) { - uint8_t b1=*(sourceLimit-1); + uint8_t b1=*(limit-1); if(U8_IS_SINGLE(b1)) { // common ASCII character } else if(U8_IS_TRAIL(b1) && length>=2) { - uint8_t b2=*(sourceLimit-2); + uint8_t b2=*(limit-2); if(0xe0<=b2 && b2<0xf0 && U8_IS_VALID_LEAD3_AND_T1(b2, b1)) { // truncated 3-byte sequence count-=2; @@ -811,7 +814,7 @@ moreBytes: } /* copy the legal byte sequence to the target */ - { + if(count>=toULength) { int8_t i; for(i=0; i<oldToULength; ++i) { @@ -822,9 +825,18 @@ moreBytes: *target++=*source++; } count-=toULength; + } else { + // A supplementary character that does not fit into the target. + // Let the standard converter handle this. + source-=(toULength-oldToULength); + pToUArgs->source=(char *)source; + pFromUArgs->target=(char *)target; + *pErrorCode=U_USING_DEFAULT_WARNING; + return; } } } + U_ASSERT(count>=0); if(U_SUCCESS(*pErrorCode) && source<sourceLimit) { if(target==(const uint8_t *)pFromUArgs->targetLimit) { |