crash rather than overflow in SkTDArray
This adds explicit overflow checks to the two likeliest
places where non-buggy code could overflow SkTDArray.
We have an #ifdef'd out PathMeasure_explosion GM that
overflows before this CL and aborts with it.
Bug: skia:7674
Change-Id: Ia0c430f4a8bb9bad687d13c875f604fd7da45aab
Reviewed-on: https://skia-review.googlesource.com/122342
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
diff --git a/include/private/SkTDArray.h b/include/private/SkTDArray.h
index 35ad409..b030dc5 100644
--- a/include/private/SkTDArray.h
+++ b/include/private/SkTDArray.h
@@ -339,7 +339,14 @@
* This is the same as calling setCount(count() + delta).
*/
void adjustCount(int delta) {
- this->setCount(fCount + delta);
+ SkASSERT(delta > 0);
+
+ // We take care to avoid overflow here.
+ // The sum of fCount and delta is at most 4294967294, which fits fine in uint32_t.
+ uint32_t count = (uint32_t)fCount + (uint32_t)delta;
+ SkASSERT_RELEASE( SkTFitsIn<int>(count) );
+
+ this->setCount(SkTo<int>(count));
}
/**
@@ -352,8 +359,14 @@
*/
void resizeStorageToAtLeast(int count) {
SkASSERT(count > fReserve);
- fReserve = count + 4;
- fReserve += fReserve / 4;
+
+ // We take care to avoid overflow here.
+ // The maximum value we can get for reserve here is 2684354563, which fits in uint32_t.
+ uint32_t reserve = (uint32_t)count + 4;
+ reserve += reserve / 4;
+ SkASSERT_RELEASE( SkTFitsIn<int>(reserve) );
+
+ fReserve = SkTo<int>(reserve);
fArray = (T*)sk_realloc_throw(fArray, fReserve * sizeof(T));
}
};