diff options
author | Mike Klein <mtklein@chromium.org> | 2018-04-19 10:34:08 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-04-19 16:45:45 +0000 |
commit | 12ee97c9910ee3419ce206b15b3948b2354857d2 (patch) | |
tree | 5ccb32bb3bbb95bd9654b3f217f1f054077d0c1d | |
parent | c4e384e5ad85250920cac6e8ee0e2a14b69d67e0 (diff) |
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>
-rw-r--r-- | include/private/SkTDArray.h | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/include/private/SkTDArray.h b/include/private/SkTDArray.h index 35ad40906a..b030dc5627 100644 --- a/include/private/SkTDArray.h +++ b/include/private/SkTDArray.h @@ -339,7 +339,14 @@ private: * 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 @@ private: */ 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)); } }; |