]> granicus.if.org Git - icu/commitdiff
ICU-21778 UnicodeString::clone error handling fix
authorAndy Heninger <andy.heninger@gmail.com>
Sat, 30 Oct 2021 00:17:41 +0000 (17:17 -0700)
committerAndy Heninger <andy.heninger@gmail.com>
Fri, 5 Nov 2021 20:48:08 +0000 (13:48 -0700)
Change UnicodeString::clone() to return a nullptr if the underlying copy
constructor produces a bogus string. This can happen if the copy constructor
encounters a memory allocation failure in allocating the copy's internal string
buffer, or if the string being copied was already bogus.

The change is consistent with other ICU clone functions, which are generally
defined to return nullptr in case of errors.

icu4c/source/common/unistr.cpp
icu4c/source/test/intltest/ustrtest.cpp

index 077b4d6ef20811d1e67da55dfd3531f22f99a46f..918693898d1585900f708e42aec90945d5264b17 100644 (file)
@@ -334,7 +334,8 @@ Replaceable::clone() const {
 // UnicodeString overrides clone() with a real implementation
 UnicodeString *
 UnicodeString::clone() const {
-  return new UnicodeString(*this);
+  LocalPointer<UnicodeString> clonedString(new UnicodeString(*this));
+  return clonedString.isValid() && !clonedString->isBogus() ? clonedString.orphan() : nullptr;
 }
 
 //========================================
index cd9751d761b9b26e719688772f30292245a1ee87..11bbb6e27af58272f8bfcfe6aa7d190166c5bd8b 100644 (file)
@@ -1653,6 +1653,16 @@ UnicodeStringTest::TestBogus() {
     if(test1>=test2 || !(test2>test1) || test1.compare(test2)>=0 || !(test2.compare(test1)>0)) {
         errln("bogus<empty failed");
     }
+
+    // test that copy constructor of bogus is bogus & clone of bogus is nullptr
+    {
+        test3.setToBogus();
+        UnicodeString test3Copy(test3);
+        UnicodeString *test3Clone = test3.clone();
+        assertTrue(WHERE, test3.isBogus());
+        assertTrue(WHERE, test3Copy.isBogus());
+        assertTrue(WHERE, test3Clone == nullptr);
+    }
 }
 
 // StringEnumeration ------------------------------------------------------- ***