]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/common/uvectr32.cpp
ICU-57132.0.1.tar.gz
[apple/icu.git] / icuSources / common / uvectr32.cpp
index 2ccb90635256bce5fc745d1afa639c36e63f1957..f7a65250315c26868a1411115516edec462c7474 100644 (file)
@@ -1,7 +1,7 @@
 /*
 ******************************************************************************
 /*
 ******************************************************************************
-* Copyright (C) 1999-2008, International Business Machines Corporation and   *
-* others. All Rights Reserved.                                               *
+* Copyright (C) 1999-2015, International Business Machines Corporation and
+* others. All Rights Reserved.
 ******************************************************************************
 *   Date        Name        Description
 *   10/22/99    alan        Creation.
 ******************************************************************************
 *   Date        Name        Description
 *   10/22/99    alan        Creation.
 
 #include "uvectr32.h"
 #include "cmemory.h"
 
 #include "uvectr32.h"
 #include "cmemory.h"
+#include "putilimp.h"
 
 U_NAMESPACE_BEGIN
 
 
 U_NAMESPACE_BEGIN
 
-#define DEFUALT_CAPACITY 8
+#define DEFAULT_CAPACITY 8
 
 /*
  * Constants for hinting whether a key is an integer
 
 /*
  * Constants for hinting whether a key is an integer
@@ -29,7 +30,7 @@ UVector32::UVector32(UErrorCode &status) :
     maxCapacity(0),
     elements(NULL)
 {
     maxCapacity(0),
     elements(NULL)
 {
-    _init(DEFUALT_CAPACITY, status);
+    _init(DEFAULT_CAPACITY, status);
 }
 
 UVector32::UVector32(int32_t initialCapacity, UErrorCode &status) :
 }
 
 UVector32::UVector32(int32_t initialCapacity, UErrorCode &status) :
@@ -46,11 +47,14 @@ UVector32::UVector32(int32_t initialCapacity, UErrorCode &status) :
 void UVector32::_init(int32_t initialCapacity, UErrorCode &status) {
     // Fix bogus initialCapacity values; avoid malloc(0)
     if (initialCapacity < 1) {
 void UVector32::_init(int32_t initialCapacity, UErrorCode &status) {
     // Fix bogus initialCapacity values; avoid malloc(0)
     if (initialCapacity < 1) {
-        initialCapacity = DEFUALT_CAPACITY;
+        initialCapacity = DEFAULT_CAPACITY;
     }
     if (maxCapacity>0 && maxCapacity<initialCapacity) {
         initialCapacity = maxCapacity;
     }
     }
     if (maxCapacity>0 && maxCapacity<initialCapacity) {
         initialCapacity = maxCapacity;
     }
+    if (initialCapacity > (int32_t)(INT32_MAX / sizeof(int32_t))) {
+        initialCapacity = uprv_min(DEFAULT_CAPACITY, maxCapacity);
+    }
     elements = (int32_t *)uprv_malloc(sizeof(int32_t)*initialCapacity);
     if (elements == 0) {
         status = U_MEMORY_ALLOCATION_ERROR;
     elements = (int32_t *)uprv_malloc(sizeof(int32_t)*initialCapacity);
     if (elements == 0) {
         status = U_MEMORY_ALLOCATION_ERROR;
@@ -192,6 +196,13 @@ int32_t UVector32::indexOf(int32_t key, int32_t startIndex) const {
 
 
 UBool UVector32::expandCapacity(int32_t minimumCapacity, UErrorCode &status) {
 
 
 UBool UVector32::expandCapacity(int32_t minimumCapacity, UErrorCode &status) {
+    if (U_FAILURE(status)) {
+        return FALSE;
+    }
+    if (minimumCapacity < 0) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return FALSE;
+    }
     if (capacity >= minimumCapacity) {
         return TRUE;
     }
     if (capacity >= minimumCapacity) {
         return TRUE;
     }
@@ -199,6 +210,10 @@ UBool UVector32::expandCapacity(int32_t minimumCapacity, UErrorCode &status) {
         status = U_BUFFER_OVERFLOW_ERROR;
         return FALSE;
     }
         status = U_BUFFER_OVERFLOW_ERROR;
         return FALSE;
     }
+    if (capacity > (INT32_MAX - 1) / 2) {  // integer overflow check
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return FALSE;
+    }
     int32_t newCap = capacity * 2;
     if (newCap < minimumCapacity) {
         newCap = minimumCapacity;
     int32_t newCap = capacity * 2;
     if (newCap < minimumCapacity) {
         newCap = minimumCapacity;
@@ -206,6 +221,11 @@ UBool UVector32::expandCapacity(int32_t minimumCapacity, UErrorCode &status) {
     if (maxCapacity > 0 && newCap > maxCapacity) {
         newCap = maxCapacity;
     }
     if (maxCapacity > 0 && newCap > maxCapacity) {
         newCap = maxCapacity;
     }
+    if (newCap > (int32_t)(INT32_MAX / sizeof(int32_t))) {  // integer overflow check
+        // We keep the original memory contents on bad minimumCapacity/maxCapacity.
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return FALSE;
+    }
     int32_t* newElems = (int32_t *)uprv_realloc(elements, sizeof(int32_t)*newCap);
     if (newElems == NULL) {
         // We keep the original contents on the memory failure on realloc.
     int32_t* newElems = (int32_t *)uprv_realloc(elements, sizeof(int32_t)*newCap);
     if (newElems == NULL) {
         // We keep the original contents on the memory failure on realloc.
@@ -219,10 +239,14 @@ UBool UVector32::expandCapacity(int32_t minimumCapacity, UErrorCode &status) {
 
 void UVector32::setMaxCapacity(int32_t limit) {
     U_ASSERT(limit >= 0);
 
 void UVector32::setMaxCapacity(int32_t limit) {
     U_ASSERT(limit >= 0);
-    maxCapacity = limit;
-    if (maxCapacity < 0) {
-        maxCapacity = 0;
+    if (limit < 0) {
+        limit = 0;
     }
     }
+    if (limit > (int32_t)(INT32_MAX / sizeof(int32_t))) {  // integer overflow check for realloc
+        //  Something is very wrong, don't realloc, leave capacity and maxCapacity unchanged
+        return;
+    }
+    maxCapacity = limit;
     if (capacity <= maxCapacity || maxCapacity == 0) {
         // Current capacity is within the new limit.
         return;
     if (capacity <= maxCapacity || maxCapacity == 0) {
         // Current capacity is within the new limit.
         return;