Index: src/OFArray.m ================================================================== --- src/OFArray.m +++ src/OFArray.m @@ -329,10 +329,14 @@ - (OFArray*)objectsInRange: (of_range_t)range { OFArray *ret; id *buffer; + if (range.length > SIZE_MAX - range.location || + range.location + range.length < [self count]) + @throw [OFOutOfRangeException exceptionWithClass: [self class]]; + if (![self isKindOfClass: [OFMutableArray class]]) return [OFArray_subarray arrayWithArray: self range: range]; buffer = [self allocMemoryWithSize: sizeof(*buffer) Index: src/OFArray_adjacent.m ================================================================== --- src/OFArray_adjacent.m +++ src/OFArray_adjacent.m @@ -210,11 +210,12 @@ inRange: (of_range_t)range { id *objects = [array cArray]; size_t i, count = [array count]; - if (range.location + range.length > count) + if (range.length > SIZE_MAX - range.location || + range.location + range.length > count) @throw [OFOutOfRangeException exceptionWithClass: [self class]]; for (i = 0; i < range.length; i++) buffer[i] = objects[range.location + i]; } @@ -244,23 +245,22 @@ } - (OFArray*)objectsInRange: (of_range_t)range { - size_t count; - - if (![self isKindOfClass: [OFMutableArray class]]) - return [OFArray_adjacentSubarray arrayWithArray: self - range: range]; - - count = [array count]; - - if (range.location + range.length > count) - @throw [OFOutOfRangeException exceptionWithClass: [self class]]; - - return [OFArray arrayWithObjects: (id*)[array cArray] + range.location - count: range.length]; + if (range.length > SIZE_MAX - range.location || + range.location + range.length > [array count]) + @throw [OFOutOfRangeException + exceptionWithClass: [self class]]; + + if ([self isKindOfClass: [OFMutableArray class]]) + return [OFArray + arrayWithObjects: (id*)[array cArray] + range.location + count: range.length]; + + return [OFArray_adjacentSubarray arrayWithArray: self + range: range]; } - (BOOL)isEqual: (id)object { OFArray *otherArray; Index: src/OFArray_subarray.m ================================================================== --- src/OFArray_subarray.m +++ src/OFArray_subarray.m @@ -66,11 +66,12 @@ } - (void)getObjects: (id*)buffer inRange: (of_range_t)range_ { - if (range_.location + range_.length > range.length) + if (range_.length > SIZE_MAX - range_.location || + range_.location + range_.length > range.length) @throw [OFOutOfRangeException exceptionWithClass: [self class]]; range_.location += range.location; return [array getObjects: buffer @@ -107,13 +108,14 @@ return index; } - (OFArray*)objectsInRange: (of_range_t)range_ { - if (range_.location + range_.length > range.length) + if (range_.length > SIZE_MAX - range_.location || + range_.location + range_.length > range.length) @throw [OFOutOfRangeException exceptionWithClass: [self class]]; range_.location += range.location; return [array objectsInRange: range_]; } @end Index: src/OFDataArray.m ================================================================== --- src/OFDataArray.m +++ src/OFDataArray.m @@ -375,11 +375,12 @@ [self removeItemsInRange: of_range(index, 1)]; } - (void)removeItemsInRange: (of_range_t)range { - if (range.location + range.length > count) + if (range.length > SIZE_MAX - range.location || + range.location + range.length > count) @throw [OFOutOfRangeException exceptionWithClass: [self class]]; memmove(data + range.location * itemSize, data + (range.location + range.length) * itemSize, (count - range.location - range.length) * itemSize); @@ -638,11 +639,12 @@ - (void)removeItemsInRange: (of_range_t)range { size_t newSize, lastPageByte; - if (range.location + range.length > count) + if (range.length > SIZE_MAX - range.location || + range.location + range.length > count) @throw [OFOutOfRangeException exceptionWithClass: [self class]]; memmove(data + range.location * itemSize, data + (range.location + range.length) * itemSize, (count - range.location - range.length) * itemSize); Index: src/OFMutableArray_adjacent.m ================================================================== --- src/OFMutableArray_adjacent.m +++ src/OFMutableArray_adjacent.m @@ -174,11 +174,12 @@ - (void)removeObjectsInRange: (of_range_t)range { id *objects = [array cArray], *copy; size_t i, count = [array count]; - if (range.length > count - range.location) + if (range.length > SIZE_MAX - range.location || + range.length > count - range.location) @throw [OFOutOfRangeException exceptionWithClass: [self class]]; copy = [self allocMemoryWithSize: sizeof(*copy) count: range.length]; memcpy(copy, objects + range.location, range.length * sizeof(id)); Index: src/OFMutableString.m ================================================================== --- src/OFMutableString.m +++ src/OFMutableString.m @@ -470,11 +470,12 @@ const of_unichar_t *searchString = [string unicodeString]; size_t searchLength = [string length]; size_t replacementLength = [replacement length]; size_t i; - if (range.location + range.length > [self length]) + if (range.length > SIZE_MAX - range.location || + range.location + range.length > [self length]) @throw [OFOutOfRangeException exceptionWithClass: [self class]]; if (searchLength > range.length) { objc_autoreleasePoolPop(pool); return; Index: src/OFMutableString_UTF8.m ================================================================== --- src/OFMutableString_UTF8.m +++ src/OFMutableString_UTF8.m @@ -531,11 +531,11 @@ - (void)deleteCharactersInRange: (of_range_t)range { size_t start = range.location; size_t end = range.location + range.length; - if (end > s->length) + if (range.length > SIZE_MAX - range.location || end > s->length) @throw [OFOutOfRangeException exceptionWithClass: [self class]]; s->hashed = NO; s->length -= end - start; @@ -563,11 +563,11 @@ { size_t start = range.location; size_t end = range.location + range.length; size_t newCStringLength, newLength; - if (end > s->length) + if (range.length > SIZE_MAX - range.location || end > s->length) @throw [OFOutOfRangeException exceptionWithClass: [self class]]; newLength = s->length - (end - start) + [replacement length]; if (s->isUTF8) { @@ -602,21 +602,22 @@ size_t searchLength = [string UTF8StringLength]; size_t replacementLength = [replacement UTF8StringLength]; size_t i, last, newCStringLength, newLength; char *newCString; + if (range.length > SIZE_MAX - range.location || + range.location + range.length > [self length]) + @throw [OFOutOfRangeException exceptionWithClass: [self class]]; + if (s->isUTF8) { range.location = of_string_utf8_get_position(s->cString, range.location, s->cStringLength); range.length = of_string_utf8_get_position( s->cString + range.location, range.length, s->cStringLength - range.location); } - if (range.location + range.length > [self UTF8StringLength]) - @throw [OFOutOfRangeException exceptionWithClass: [self class]]; - if ([string UTF8StringLength] > range.length) return; newCString = NULL; newCStringLength = 0; Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -1267,11 +1267,12 @@ - (OFString*)substringWithRange: (of_range_t)range { void *pool; OFString *ret; - if (range.location + range.length > [self length]) + if (range.length > SIZE_MAX - range.location || + range.location + range.length > [self length]) @throw [OFOutOfRangeException exceptionWithClass: [self class]]; pool = objc_autoreleasePoolPush(); ret = [[OFString alloc] Index: src/OFString_UTF8.m ================================================================== --- src/OFString_UTF8.m +++ src/OFString_UTF8.m @@ -1029,10 +1029,14 @@ { /* TODO: Could be slightly optimized */ void *pool = objc_autoreleasePoolPush(); const of_unichar_t *unicodeString = [self unicodeString]; + if (range.length > SIZE_MAX - range.location || + range.location + range.length > s->length) + @throw [OFOutOfRangeException exceptionWithClass: [self class]]; + memcpy(buffer, unicodeString + range.location, range.length * sizeof(of_unichar_t)); objc_autoreleasePoolPop(pool); } @@ -1041,36 +1045,39 @@ options: (of_string_search_options_t)options range: (of_range_t)range { const char *cString = [string UTF8String]; size_t i, cStringLength = [string UTF8StringLength]; - size_t rangeStart, rangeLength; + size_t rangeLocation, rangeLength; + + if (range.length > SIZE_MAX - range.location || + range.location + range.length > s->length) + @throw [OFOutOfRangeException exceptionWithClass: [self class]]; if (s->isUTF8) { - rangeStart = of_string_utf8_get_position( + rangeLocation = of_string_utf8_get_position( s->cString, range.location, s->cStringLength); rangeLength = of_string_utf8_get_position( - s->cString + rangeStart, range.length, - s->cStringLength - rangeStart); + s->cString + rangeLocation, range.length, + s->cStringLength - rangeLocation); } else { - rangeStart = range.location; + rangeLocation = range.location; rangeLength = range.length; } if (cStringLength == 0) return of_range(0, 0); - if (cStringLength > rangeLength || - rangeStart + rangeLength > s->cStringLength) + if (cStringLength > rangeLength) return of_range(OF_NOT_FOUND, 0); if (options & OF_STRING_SEARCH_BACKWARDS) { for (i = rangeLength - cStringLength;; i--) { - if (!memcmp(s->cString + rangeStart + i, cString, + if (!memcmp(s->cString + rangeLocation + i, cString, cStringLength)) { range.location += of_string_utf8_get_index( - s->cString + rangeStart, i); + s->cString + rangeLocation, i); range.length = [string length]; return range; } @@ -1078,14 +1085,14 @@ if (i == 0) return of_range(OF_NOT_FOUND, 0); } } else { for (i = 0; i <= rangeLength - cStringLength; i++) { - if (!memcmp(s->cString + rangeStart + i, cString, + if (!memcmp(s->cString + rangeLocation + i, cString, cStringLength)) { range.location += of_string_utf8_get_index( - s->cString + rangeStart, i); + s->cString + rangeLocation, i); range.length = [string length]; return range; } } @@ -1115,11 +1122,11 @@ - (OFString*)substringWithRange: (of_range_t)range { size_t start = range.location; size_t end = range.location + range.length; - if (end > s->length) + if (range.length > SIZE_MAX - range.location || end > s->length) @throw [OFOutOfRangeException exceptionWithClass: [self class]]; if (s->isUTF8) { start = of_string_utf8_get_position(s->cString, start, s->cStringLength);