diff options
author | Adrienne Walker <enne@chromium.org> | 2017-08-10 12:16:37 -0700 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-08-10 20:22:35 +0000 |
commit | ad8da8ea990d22fa717ec1ae7c3ad628d74682b8 (patch) | |
tree | 0381a40ea1c53889b52122abe3effb213ac7b052 /src/core/SkPathRef.cpp | |
parent | 6a653a5f7dd08ceb588d82f267e84ec6523194c2 (diff) |
Expose SkPath validation as boolean
As a part of serializing SkPaths, I want to be able to know (without
asserting) whether or not a path is valid so that I can discard
potentially malicious deserialized paths.
Currently, SkPath(Ref) both just have asserting validation functions
which can't be used externally. This patch adds accessors that don't
assert.
Bug: chromium:752755 skia:6955
Change-Id: I4d0ceb31ec660b87e3fda438392ad2b60a27a0da
Reviewed-on: https://skia-review.googlesource.com/31720
Commit-Queue: Mike Klein <mtklein@chromium.org>
Reviewed-by: Mike Reed <reed@google.com>
Diffstat (limited to 'src/core/SkPathRef.cpp')
-rw-r--r-- | src/core/SkPathRef.cpp | 68 |
1 files changed, 46 insertions, 22 deletions
diff --git a/src/core/SkPathRef.cpp b/src/core/SkPathRef.cpp index abe1f906a5..021733c5fa 100644 --- a/src/core/SkPathRef.cpp +++ b/src/core/SkPathRef.cpp @@ -6,6 +6,7 @@ */ #include "SkBuffer.h" +#include "SkNx.h" #include "SkOnce.h" #include "SkPath.h" #include "SkPathRef.h" @@ -742,28 +743,47 @@ uint8_t SkPathRef::Iter::peek() const { return next <= fVerbStop ? (uint8_t) SkPath::kDone_Verb : *next; } -#ifdef SK_DEBUG - -#include "SkNx.h" -void SkPathRef::validate() const { - SkASSERT(static_cast<ptrdiff_t>(fFreeSpace) >= 0); - SkASSERT(reinterpret_cast<intptr_t>(fVerbs) - reinterpret_cast<intptr_t>(fPoints) >= 0); - SkASSERT((nullptr == fPoints) == (nullptr == fVerbs)); - SkASSERT(!(nullptr == fPoints && 0 != fFreeSpace)); - SkASSERT(!(nullptr == fPoints && 0 != fFreeSpace)); - SkASSERT(!(nullptr == fPoints && fPointCnt)); - SkASSERT(!(nullptr == fVerbs && fVerbCnt)); - SkASSERT(this->currSize() == - fFreeSpace + sizeof(SkPoint) * fPointCnt + sizeof(uint8_t) * fVerbCnt); +bool SkPathRef::isValid() const { + if (static_cast<ptrdiff_t>(fFreeSpace) < 0) { + return false; + } + if (reinterpret_cast<intptr_t>(fVerbs) - reinterpret_cast<intptr_t>(fPoints) < 0) { + return false; + } + if ((nullptr == fPoints) != (nullptr == fVerbs)) { + return false; + } + if (nullptr == fPoints && 0 != fFreeSpace) { + return false; + } + if (nullptr == fPoints && 0 != fFreeSpace) { + return false; + } + if (nullptr == fPoints && fPointCnt) { + return false; + } + if (nullptr == fVerbs && fVerbCnt) { + return false; + } + if (this->currSize() != + fFreeSpace + sizeof(SkPoint) * fPointCnt + sizeof(uint8_t) * fVerbCnt) { + return false; + } if (fIsOval || fIsRRect) { - // Currently we don't allow both of these to be set, even though ovals are round rects. - SkASSERT(fIsOval != fIsRRect); + // Currently we don't allow both of these to be set, even though ovals are ro + if (fIsOval == fIsRRect) { + return false; + } if (fIsOval) { - SkASSERT(fRRectOrOvalStartIdx < 4); + if (fRRectOrOvalStartIdx >= 4) { + return false; + } } else { - SkASSERT(fRRectOrOvalStartIdx < 8); + if (fRRectOrOvalStartIdx >= 8) { + return false; + } } } @@ -787,13 +807,15 @@ void SkPathRef::validate() const { } #endif - SkASSERT(!fPoints[i].isFinite() || - (!(point < leftTop).anyTrue() && !(point > rightBot).anyTrue())); + if (fPoints[i].isFinite() && (point < leftTop).anyTrue() && !(point > rightBot).anyTrue()) + return false; if (!fPoints[i].isFinite()) { isFinite = false; } } - SkASSERT(SkToBool(fIsFinite) == isFinite); + if (SkToBool(fIsFinite) != isFinite) { + return false; + } } #ifdef SK_DEBUG_PATH @@ -824,7 +846,9 @@ void SkPathRef::validate() const { break; } } - SkASSERT(mask == fSegmentMask); + if (mask != fSegmentMask) { + return false; + } #endif // SK_DEBUG_PATH + return true; } -#endif |