diff --git a/icu4c/source/common/ucasemap.cpp b/icu4c/source/common/ucasemap.cpp index 4d59f7d8f7b..0576a26ddd1 100644 --- a/icu4c/source/common/ucasemap.cpp +++ b/icu4c/source/common/ucasemap.cpp @@ -422,6 +422,9 @@ ucasemap_internalUTF8ToTitle(const UCaseMap *csm, src, &csc, titleLimit, idx, pErrorCode); + if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { + *pErrorCode=U_ZERO_ERROR; + } if(U_FAILURE(*pErrorCode)) { return destIndex; } diff --git a/icu4c/source/common/ustrcase.cpp b/icu4c/source/common/ustrcase.cpp index aee35361cb7..8f594ec2785 100644 --- a/icu4c/source/common/ustrcase.cpp +++ b/icu4c/source/common/ustrcase.cpp @@ -305,6 +305,9 @@ ustrcase_internalToTitle(const UCaseMap *csm, src, &csc, titleLimit, idx, pErrorCode); + if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { + *pErrorCode=U_ZERO_ERROR; + } if(U_FAILURE(*pErrorCode)) { return destIndex; } diff --git a/icu4c/source/test/intltest/strcase.cpp b/icu4c/source/test/intltest/strcase.cpp index 34f3e4ac22c..7054b7f1e7a 100644 --- a/icu4c/source/test/intltest/strcase.cpp +++ b/icu4c/source/test/intltest/strcase.cpp @@ -49,6 +49,7 @@ StringCaseTest::runIndexedTest(int32_t index, UBool exec, const char *&name, cha TESTCASE_AUTO(TestGreekUpper); TESTCASE_AUTO(TestLongUpper); TESTCASE_AUTO(TestMalformedUTF8); + TESTCASE_AUTO(TestBufferOverflow); TESTCASE_AUTO_END; } @@ -815,3 +816,35 @@ void StringCaseTest::TestMalformedUTF8() { errorCode.errorName(), (int)destLength, dest[0]); } } + +void StringCaseTest::TestBufferOverflow() { + // Ticket #12849, incorrect result from Title Case preflight operation, + // when buffer overflow error is expected. + IcuTestErrorCode errorCode(*this, "TestBufferOverflow"); + LocalUCaseMapPointer csm(ucasemap_open("en", 0, errorCode)); + if (errorCode.isFailure()) { + errln("ucasemap_open(English) failed - %s", errorCode.errorName()); + return; + } + + UnicodeString data("hello world"); + int32_t result = ucasemap_toTitle(csm.getAlias(), NULL, 0, data.getBuffer(), data.length(), errorCode); + if (errorCode.get() != U_BUFFER_OVERFLOW_ERROR || result != data.length()) { + errln("%s:%d ucasemap_toTitle(\"hello world\") failed: " + "expected (U_BUFFER_OVERFLOW_ERROR, %d), got (%s, %d)", + __FILE__, __LINE__, data.length(), errorCode.errorName(), result); + } + errorCode.reset(); + +#if U_HAVE_STD_STRING + std::string data_utf8; + data.toUTF8String(data_utf8); + result = ucasemap_utf8ToTitle(csm.getAlias(), NULL, 0, data_utf8.c_str(), data_utf8.length(), errorCode); + if (errorCode.get() != U_BUFFER_OVERFLOW_ERROR || result != (int32_t)data_utf8.length()) { + errln("%s:%d ucasemap_toTitle(\"hello world\") failed: " + "expected (U_BUFFER_OVERFLOW_ERROR, %d), got (%s, %d)", + __FILE__, __LINE__, data_utf8.length(), errorCode.errorName(), result); + } + errorCode.reset(); +#endif // U_HAVE_STD_STRING +} diff --git a/icu4c/source/test/intltest/ustrtest.h b/icu4c/source/test/intltest/ustrtest.h index ef3f6cff8ac..37b3a88ea95 100644 --- a/icu4c/source/test/intltest/ustrtest.h +++ b/icu4c/source/test/intltest/ustrtest.h @@ -112,6 +112,7 @@ public: void TestGreekUpper(); void TestLongUpper(); void TestMalformedUTF8(); + void TestBufferOverflow(); private: void assertGreekUpper(const char *s, const char *expected);