From: Markus Scherer Date: Mon, 7 Nov 2016 23:15:47 +0000 (+0000) Subject: ICU-12832 UTF-8 case mapping appendUChar() write a character even if it fills destCap... X-Git-Tag: milestone-59-0-1~53 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fad9b489315e5b9b49795a35227d08c410bcb1f8;p=icu ICU-12832 UTF-8 case mapping appendUChar() write a character even if it fills destCapacity exactly X-SVN-Rev: 39500 --- diff --git a/icu4c/source/common/ucasemap.cpp b/icu4c/source/common/ucasemap.cpp index c0d56c28731..4d59f7d8f7b 100644 --- a/icu4c/source/common/ucasemap.cpp +++ b/icu4c/source/common/ucasemap.cpp @@ -200,7 +200,7 @@ appendUChar(uint8_t *dest, int32_t destIndex, int32_t destCapacity, UChar c) { return -1; // integer overflow } int32_t limit=destIndex+length; - if(limit= expected16.length()) { + assertEquals(msg + cap, expected16, result16); + } + } + #if U_HAVE_STD_STRING UErrorCode errorCode = U_ZERO_ERROR; LocalUCaseMapPointer csm(ucasemap_open("el", 0, &errorCode)); @@ -596,13 +625,42 @@ StringCaseTest::assertGreekUpper(const char *s, const char *expected) { std::string s8; s16.toUTF8String(s8); msg = UnicodeString("ucasemap_utf8ToUpper/Greek(\"") + s16 + "\")"; - char dest[1000]; - int32_t length = ucasemap_utf8ToUpper(csm.getAlias(), dest, UPRV_LENGTHOF(dest), - s8.data(), s8.length(), &errorCode); + char dest8[1000]; + length = ucasemap_utf8ToUpper(csm.getAlias(), dest8, UPRV_LENGTHOF(dest8), + s8.data(), s8.length(), &errorCode); assertSuccess("ucasemap_utf8ToUpper", errorCode); - StringPiece result8(dest, length); + StringPiece result8(dest8, length); UnicodeString result16From8 = UnicodeString::fromUTF8(result8); assertEquals(msg, expected16, result16From8); + + msg += " cap="; + capacities[1] = length / 2; + capacities[2] = length - 1; + capacities[3] = length; + capacities[4] = length + 1; + char dest8b[1000]; + int32_t expected8Length = length; // Assuming the previous call worked. + for (int32_t i = 0; i < UPRV_LENGTHOF(capacities); ++i) { + int32_t cap = capacities[i]; + memset(dest8b, 0x5A, UPRV_LENGTHOF(dest8b)); + UErrorCode errorCode = U_ZERO_ERROR; + length = ucasemap_utf8ToUpper(csm.getAlias(), dest8b, cap, + s8.data(), s8.length(), &errorCode); + assertEquals(msg + cap, expected8Length, length); + UErrorCode expectedErrorCode; + if (cap < expected8Length) { + expectedErrorCode = U_BUFFER_OVERFLOW_ERROR; + } else if (cap == expected8Length) { + expectedErrorCode = U_STRING_NOT_TERMINATED_WARNING; + } else { + expectedErrorCode = U_ZERO_ERROR; + assertEquals(msg + cap + " NUL", 0, dest8b[length]); + } + assertEquals(msg + cap + " errorCode", expectedErrorCode, errorCode); + if (cap >= expected8Length) { + assertEquals(msg + cap + " (memcmp)", 0, memcmp(dest8, dest8b, expected8Length)); + } + } #endif }