From 0b88b1c754473abbb19327da621df16d1e1306ba Mon Sep 17 00:00:00 2001 From: Frank Tang Date: Tue, 25 Feb 2025 21:02:23 +0000 Subject: [PATCH] ICU-23060 Fix heap-buffer-overflow when UnicodeString size too large See #3416 --- icu4c/source/common/unistr.cpp | 5 +++++ icu4c/source/test/intltest/ustrtest.cpp | 13 +++++++++++++ icu4c/source/test/intltest/ustrtest.h | 1 + 3 files changed, 19 insertions(+) diff --git a/icu4c/source/common/unistr.cpp b/icu4c/source/common/unistr.cpp index a720245772e..7b48addbe85 100644 --- a/icu4c/source/common/unistr.cpp +++ b/icu4c/source/common/unistr.cpp @@ -1945,6 +1945,11 @@ UnicodeString::cloneArrayIfNeeded(int32_t newCapacity, growCapacity = newCapacity; } else if(newCapacity <= US_STACKBUF_SIZE && growCapacity > US_STACKBUF_SIZE) { growCapacity = US_STACKBUF_SIZE; + } else if(newCapacity > growCapacity) { + return false; // bad inputs + } + if(growCapacity > kMaxCapacity) { + return false; } // save old values diff --git a/icu4c/source/test/intltest/ustrtest.cpp b/icu4c/source/test/intltest/ustrtest.cpp index 5df9d8e1fd4..31cb6519051 100644 --- a/icu4c/source/test/intltest/ustrtest.cpp +++ b/icu4c/source/test/intltest/ustrtest.cpp @@ -77,6 +77,7 @@ void UnicodeStringTest::runIndexedTest( int32_t index, UBool exec, const char* & TESTCASE_AUTO(TestNullPointers); TESTCASE_AUTO(TestUnicodeStringInsertAppendToSelf); TESTCASE_AUTO(TestLargeAppend); + TESTCASE_AUTO(TestLargeMemory); TESTCASE_AUTO(TestU16StringView); TESTCASE_AUTO(TestWStringView); TESTCASE_AUTO_END; @@ -2351,6 +2352,18 @@ void UnicodeStringTest::TestUnicodeStringInsertAppendToSelf() { assertEquals("", u"abbcdcde", str); } +void UnicodeStringTest::TestLargeMemory() { +#if U_PLATFORM_IS_LINUX_BASED || U_PLATFORM_IS_DARWIN_BASED + if(quick) { return; } + IcuTestErrorCode status(*this, "TestLargeMemory"); + constexpr uint32_t len = 2147483643; + char16_t *buf = new char16_t[len]; + if (buf == nullptr) { return; } + uprv_memset(buf, 0x4e, len * 2); + icu::UnicodeString test(buf, len); + delete [] buf; +#endif +} void UnicodeStringTest::TestLargeAppend() { if(quick) return; diff --git a/icu4c/source/test/intltest/ustrtest.h b/icu4c/source/test/intltest/ustrtest.h index 47d4a8acc82..074d4b8bc06 100644 --- a/icu4c/source/test/intltest/ustrtest.h +++ b/icu4c/source/test/intltest/ustrtest.h @@ -92,6 +92,7 @@ public: void TestUnicodeStringImplementsAppendable(); void TestSizeofUnicodeString(); void TestMoveSwap(); + void TestLargeMemory(); void TestUInt16Pointers(); void TestWCharPointers();