X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/46f4442e9a5a4f3b98b7c1083586332f6a8a99a4..ef6cf650f4a75c3f97de06b51fa104f2069b9ea2:/icuSources/common/uvectr32.cpp diff --git a/icuSources/common/uvectr32.cpp b/icuSources/common/uvectr32.cpp index 2ccb9063..f7a65250 100644 --- a/icuSources/common/uvectr32.cpp +++ b/icuSources/common/uvectr32.cpp @@ -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. @@ -10,10 +10,11 @@ #include "uvectr32.h" #include "cmemory.h" +#include "putilimp.h" U_NAMESPACE_BEGIN -#define DEFUALT_CAPACITY 8 +#define DEFAULT_CAPACITY 8 /* * Constants for hinting whether a key is an integer @@ -29,7 +30,7 @@ UVector32::UVector32(UErrorCode &status) : maxCapacity(0), elements(NULL) { - _init(DEFUALT_CAPACITY, status); + _init(DEFAULT_CAPACITY, 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) { - initialCapacity = DEFUALT_CAPACITY; + initialCapacity = DEFAULT_CAPACITY; } if (maxCapacity>0 && maxCapacity (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; @@ -192,6 +196,13 @@ int32_t UVector32::indexOf(int32_t key, int32_t startIndex) const { 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; } @@ -199,6 +210,10 @@ UBool UVector32::expandCapacity(int32_t minimumCapacity, UErrorCode &status) { 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; @@ -206,6 +221,11 @@ UBool UVector32::expandCapacity(int32_t minimumCapacity, UErrorCode &status) { 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. @@ -219,10 +239,14 @@ UBool UVector32::expandCapacity(int32_t minimumCapacity, UErrorCode &status) { 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;