| Index: src/core/SkColorSpace.cpp
|
| diff --git a/src/core/SkColorSpace.cpp b/src/core/SkColorSpace.cpp
|
| index 6bc897c8a990af014bde34df7a684cb78ffe46d4..69fada23dfe8ba0a171b7c29ab870c9ae2ed6167 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.
|
|
|