]> granicus.if.org Git - icu/commitdiff
ICU-20804 OOM not handled in selectForMask
authorJeff Genovy <29107334+jefgen@users.noreply.github.com>
Sat, 31 Aug 2019 08:40:35 +0000 (01:40 -0700)
committerJeff Genovy <29107334+jefgen@users.noreply.github.com>
Thu, 12 Sep 2019 01:15:39 +0000 (18:15 -0700)
icu4c/source/common/ucnvsel.cpp

index 79be8c31f2da5eca83dd585c341ddb8b4d855a19..2dff5ac1bc8388bb36fbc51337c191f9801c1e60 100644 (file)
@@ -691,36 +691,36 @@ static int16_t countOnes(uint32_t* mask, int32_t len) {
 
 /* internal function! */
 static UEnumeration *selectForMask(const UConverterSelector* sel,
-                                   uint32_t *mask, UErrorCode *status) {
+                                   uint32_t *theMask, UErrorCode *status) {
+  LocalMemory<uint32_t> mask(theMask);
   // this is the context we will use. Store a table of indices to which
   // encodings are legit.
-  struct Enumerator* result = (Enumerator*)uprv_malloc(sizeof(Enumerator));
-  if (result == NULL) {
-    uprv_free(mask);
+  LocalMemory<Enumerator> result(static_cast<Enumerator *>(uprv_malloc(sizeof(Enumerator))));
+  if (result.isNull()) {
     *status = U_MEMORY_ALLOCATION_ERROR;
-    return NULL;
+    return nullptr;
   }
-  result->index = NULL;  // this will be allocated later!
+  result->index = nullptr;  // this will be allocated later!
   result->length = result->cur = 0;
   result->sel = sel;
 
-  UEnumeration *en = (UEnumeration *)uprv_malloc(sizeof(UEnumeration));
-  if (en == NULL) {
+  LocalMemory<UEnumeration> en(static_cast<UEnumeration *>(uprv_malloc(sizeof(UEnumeration))));
+  if (en.isNull()) {
     // TODO(markus): Combine Enumerator and UEnumeration into one struct.
-    uprv_free(mask);
-    uprv_free(result);
     *status = U_MEMORY_ALLOCATION_ERROR;
-    return NULL;
+    return nullptr;
   }
-  memcpy(en, &defaultEncodings, sizeof(UEnumeration));
-  en->context = result;
-
+  memcpy(en.getAlias(), &defaultEncodings, sizeof(UEnumeration));
+  
   int32_t columns = (sel->encodingsCount+31)/32;
-  int16_t numOnes = countOnes(mask, columns);
+  int16_t numOnes = countOnes(mask.getAlias(), columns);
   // now, we know the exact space we need for index
   if (numOnes > 0) {
-    result->index = (int16_t*) uprv_malloc(numOnes * sizeof(int16_t));
-
+    result->index = static_cast<int16_t*>(uprv_malloc(numOnes * sizeof(int16_t)));
+    if (result->index == nullptr) {
+      *status = U_MEMORY_ALLOCATION_ERROR;
+      return nullptr;
+    }
     int32_t i, j;
     int16_t k = 0;
     for (j = 0 ; j < columns; j++) {
@@ -734,8 +734,8 @@ static UEnumeration *selectForMask(const UConverterSelector* sel,
     }
   } //otherwise, index will remain NULL (and will never be touched by
     //the enumerator code anyway)
-  uprv_free(mask);
-  return en;
+  en->context = result.orphan();
+  return en.orphan();
 }
 
 /* check a string against the selector - UTF16 version */