diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkRRect.cpp | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/src/core/SkRRect.cpp b/src/core/SkRRect.cpp index 730868a440..f1b85fbc28 100644 --- a/src/core/SkRRect.cpp +++ b/src/core/SkRRect.cpp @@ -465,7 +465,12 @@ size_t SkRRect::readFromMemory(const void* buffer, size_t length) { if (length < kSizeInMemory) { return 0; } - + // Note that the buffer may be smaller than SkRRect. It is important not to access + // bufferAsRRect->fType. + const SkRRect* bufferAsRRect = reinterpret_cast<const SkRRect*>(buffer); + if (!AreRectAndRadiiValid(bufferAsRRect->fRect, bufferAsRRect->fRadii)) { + return 0; + } // Deserialize rect and corners, then rederive the type tag. memcpy(this, buffer, kSizeInMemory); this->computeType(); @@ -505,6 +510,10 @@ static bool are_radius_check_predicates_valid(SkScalar rad, SkScalar min, SkScal } bool SkRRect::isValid() const { + if (!AreRectAndRadiiValid(fRect, fRadii)) { + return false; + } + bool allRadiiZero = (0 == fRadii[0].fX && 0 == fRadii[0].fY); bool allCornersSquare = (0 == fRadii[0].fX || 0 == fRadii[0].fY); bool allRadiiSame = true; @@ -570,14 +579,19 @@ bool SkRRect::isValid() const { break; } + return true; +} + +bool SkRRect::AreRectAndRadiiValid(const SkRect& rect, const SkVector radii[4]) { + if (!rect.isFinite()) { + return false; + } for (int i = 0; i < 4; ++i) { - if (!are_radius_check_predicates_valid(fRadii[i].fX, fRect.fLeft, fRect.fRight) || - !are_radius_check_predicates_valid(fRadii[i].fY, fRect.fTop, fRect.fBottom)) { + if (!are_radius_check_predicates_valid(radii[i].fX, rect.fLeft, rect.fRight) || + !are_radius_check_predicates_valid(radii[i].fY, rect.fTop, rect.fBottom)) { return false; } } - return true; } - /////////////////////////////////////////////////////////////////////////////// |