diff options
author | msarett <msarett@google.com> | 2016-06-09 06:33:18 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-06-09 06:33:19 -0700 |
commit | 8c5424cb77f842113213c52854b17f14f7f3881d (patch) | |
tree | 0caab4524b7ffec81c842ac4eb8c8578155db40c | |
parent | a058786ae3cd9402194de94f6658a19efe3f34ef (diff) |
SkColorSpace::NewICC fix integer overflow caught by fuzzer
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2053683002
Review-Url: https://codereview.chromium.org/2053683002
-rw-r--r-- | src/core/SkColorSpace.cpp | 37 |
1 files changed, 20 insertions, 17 deletions
diff --git a/src/core/SkColorSpace.cpp b/src/core/SkColorSpace.cpp index 6bc897c8a9..69fada23df 100644 --- a/src/core/SkColorSpace.cpp +++ b/src/core/SkColorSpace.cpp @@ -314,6 +314,20 @@ struct ICCProfileHeader { } }; +template <class T> +static bool safe_add(T arg1, T arg2, size_t* result) { + SkASSERT(arg1 >= 0); + SkASSERT(arg2 >= 0); + if (arg1 >= 0 && arg2 <= std::numeric_limits<T>::max() - arg1) { + T sum = arg1 + arg2; + if (sum <= std::numeric_limits<size_t>::max()) { + *result = static_cast<size_t>(sum); + return true; + } + } + return false; +} + struct ICCTag { uint32_t fSignature; uint32_t fOffset; @@ -327,7 +341,10 @@ struct ICCTag { } bool valid(size_t len) { - return_if_false(fOffset + fLength <= len, "Tag too large for ICC profile"); + size_t tagEnd; + return_if_false(safe_add(fOffset, fLength, &tagEnd), + "Tag too large, overflows integer addition"); + return_if_false(tagEnd <= len, "Tag too large for ICC profile"); return true; } @@ -366,20 +383,6 @@ bool load_xyz(float dst[3], const uint8_t* src, size_t len) { return true; } -template <class T> -static bool safe_add(T arg1, T arg2, size_t* result) { - SkASSERT(arg1 >= 0); - SkASSERT(arg2 >= 0); - if (arg1 >= 0 && arg2 <= std::numeric_limits<T>::max() - arg1) { - T sum = arg1 + arg2; - if (sum <= std::numeric_limits<size_t>::max()) { - *result = static_cast<size_t>(sum); - return true; - } - } - return false; -} - static constexpr uint32_t kTAG_CurveType = SkSetFourByteTag('c', 'u', 'r', 'v'); static constexpr uint32_t kTAG_ParaCurveType = SkSetFourByteTag('p', 'a', 'r', 'a'); @@ -808,8 +811,8 @@ bool load_a2b0(SkColorLookUpTable* colorLUT, SkGammaCurve* gammas, SkMatrix44* t } sk_sp<SkColorSpace> SkColorSpace::NewICC(const void* input, size_t len) { - if (len < kICCHeaderSize) { - return_null("Data is not large enough to contain an ICC profile"); + if (!input || len < kICCHeaderSize) { + return_null("Data is null or not large enough to contain an ICC profile"); } // Create our own copy of the input. |