diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index 478617f828..f4ead536aa 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -1120,6 +1120,12 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint, // transform the path into device space pathPtr->transform(*matrix, devPathPtr); +#if defined(IS_FUZZING) + if (devPathPtr->countPoints() > 1000) { + return; + } +#endif + this->drawDevPath(*devPathPtr, *paint, drawCoverage, customBlitter, doFill, iData); } diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp index b2220a7651..9fa0b153ef 100644 --- a/src/core/SkImageFilter.cpp +++ b/src/core/SkImageFilter.cpp @@ -122,6 +122,12 @@ bool SkImageFilter::Common::unflatten(SkReadBuffer& buffer, int expectedCount) { return false; } +#if defined(IS_FUZZING) + if (count > 4) { + return false; + } +#endif + this->allocInputs(count); for (int i = 0; i < count; i++) { if (buffer.readBool()) { diff --git a/src/core/SkMallocPixelRef.cpp b/src/core/SkMallocPixelRef.cpp index 2933e48cc4..1ae9dd0404 100644 --- a/src/core/SkMallocPixelRef.cpp +++ b/src/core/SkMallocPixelRef.cpp @@ -73,6 +73,11 @@ sk_sp SkMallocPixelRef::MakeUsing(void*(*allocProc)(size_t), return nullptr; } } +#if defined(IS_FUZZING) + if (size > 100000) { + return nullptr; + } +#endif void* addr = allocProc(size); if (nullptr == addr) { return nullptr; diff --git a/src/core/SkMaskFilter.cpp b/src/core/SkMaskFilter.cpp index 347e828d0e..dd16dd81a4 100644 --- a/src/core/SkMaskFilter.cpp +++ b/src/core/SkMaskFilter.cpp @@ -264,6 +264,11 @@ bool SkMaskFilterBase::filterPath(const SkPath& devPath, const SkMatrix& matrix, SkMask srcM, dstM; +#if defined(IS_FUZZING) + if (devPath.countVerbs() > 1000 || devPath.countPoints() > 1000) { + return false; + } +#endif if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), this, &matrix, &srcM, SkMask::kComputeBoundsAndRenderImage_CreateMode, style)) { diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp index ab8bf2e1fc..975a849f5d 100644 --- a/src/core/SkPath.cpp +++ b/src/core/SkPath.cpp @@ -3484,7 +3484,11 @@ void SkPathPriv::CreateDrawArcPath(SkPath* path, const SkRect& oval, SkScalar st SkScalar sweepAngle, bool useCenter, bool isFillNoPathEffect) { SkASSERT(!oval.isEmpty()); SkASSERT(sweepAngle); - +#if defined(IS_FUZZING) + if (sweepAngle > 3600.0f || sweepAngle < 3600.0f) { + return; + } +#endif path->reset(); path->setIsVolatile(true); path->setFillType(SkPath::kWinding_FillType); diff --git a/src/core/SkPictureData.cpp b/src/core/SkPictureData.cpp index 2ca88ae841..3fc4ecf6bd 100644 --- a/src/core/SkPictureData.cpp +++ b/src/core/SkPictureData.cpp @@ -495,6 +495,11 @@ bool new_array_from_buffer(SkReadBuffer& buffer, uint32_t inCount, } void SkPictureData::parseBufferTag(SkReadBuffer& buffer, uint32_t tag, uint32_t size) { +#if defined(IS_FUZZING) + if (size > 1000) { + return; + } +#endif switch (tag) { case SK_PICT_PAINT_BUFFER_TAG: { if (!buffer.validate(SkTFitsIn(size))) { @@ -514,6 +519,11 @@ void SkPictureData::parseBufferTag(SkReadBuffer& buffer, uint32_t tag, uint32_t if (!buffer.validate(count >= 0)) { return; } +#if defined(IS_FUZZING) + if (count > 20) { + return; + } +#endif fPaths.reset(count); for (int i = 0; i < count; i++) { buffer.readPath(&fPaths[i]); diff --git a/src/core/SkReadBuffer.cpp b/src/core/SkReadBuffer.cpp index 73e7af0fd7..1f2c87e0bb 100644 --- a/src/core/SkReadBuffer.cpp +++ b/src/core/SkReadBuffer.cpp @@ -263,7 +263,12 @@ bool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) { uint32_t SkReadBuffer::getArrayCount() { const size_t inc = sizeof(uint32_t); fError = fError || !IsPtrAlign4(fReader.peek()) || !fReader.isAvailable(inc); +#if defined(IS_FUZZING) + uint32_t retVal = fError ? 0 : *(uint32_t*)fReader.peek(); + return retVal < 1000 ? retVal: 1000; +#else return fError ? 0 : *(uint32_t*)fReader.peek(); +#endif } sk_sp SkReadBuffer::readImage() { @@ -298,6 +303,12 @@ sk_sp SkReadBuffer::readImage() { } size_t size = SkAbs32(encoded_size); +#if defined(IS_FUZZING) + if (size > 100000) { + this->validate(false); + return nullptr; + } +#endif sk_sp data = SkData::MakeUninitialized(size); if (!this->readPad32(data->writable_data(), size)) { this->validate(false); diff --git a/src/core/SkScan_AAAPath.cpp b/src/core/SkScan_AAAPath.cpp index e4e6701cea..c180f417c7 100644 --- a/src/core/SkScan_AAAPath.cpp +++ b/src/core/SkScan_AAAPath.cpp @@ -1595,6 +1595,11 @@ static SK_ALWAYS_INLINE void aaa_fill_path(const SkPath& path, const SkIRect& cl SkASSERT(blitter); SkEdgeBuilder builder; +#if defined(IS_FUZZING) + if (path.countPoints() > 1000) { + return; + } +#endif int count = builder.build_edges(path, &clipRect, 0, pathContainedInClip, SkEdgeBuilder::kAnalyticEdge); SkAnalyticEdge** list = builder.analyticEdgeList(); diff --git a/src/core/SkScan_Path.cpp b/src/core/SkScan_Path.cpp index 6234afe873..54457da0ff 100644 --- a/src/core/SkScan_Path.cpp +++ b/src/core/SkScan_Path.cpp @@ -253,6 +253,11 @@ static void walk_convex_edges(SkEdge* prevHead, SkPath::FillType, } local_top = local_bot + 1; } else { +#if defined(IS_FUZZING) + if (count > 1000) { + count = 1000; + } +#endif do { int L = SkFixedRoundToInt(left); int R = SkFixedRoundToInt(rite); diff --git a/src/core/SkTextBlob.cpp b/src/core/SkTextBlob.cpp index 6d89e6f135..680534d384 100644 --- a/src/core/SkTextBlob.cpp +++ b/src/core/SkTextBlob.cpp @@ -800,7 +800,11 @@ sk_sp SkTextBlob::MakeFromBuffer(SkReadBuffer& reader) { // End-of-runs marker. break; } - +#if defined(IS_FUZZING) + if (glyphCount > 1000) { + return nullptr; + } +#endif PositioningAndExtended pe; pe.intValue = reader.read32(); GlyphPositioning pos = pe.positioning; @@ -811,7 +815,11 @@ sk_sp SkTextBlob::MakeFromBuffer(SkReadBuffer& reader) { if (textSize < 0) { return nullptr; } - +#if defined(IS_FUZZING) + if (textSize > 1000) { + return nullptr; + } +#endif SkPoint offset; reader.readPoint(&offset); SkPaint font; diff --git a/src/effects/Sk1DPathEffect.cpp b/src/effects/Sk1DPathEffect.cpp index 8a74c16cda..f6a5557914 100644 --- a/src/effects/Sk1DPathEffect.cpp +++ b/src/effects/Sk1DPathEffect.cpp @@ -15,6 +15,11 @@ bool Sk1DPathEffect::filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const { SkPathMeasure meas(src, false); +#if defined(IS_FUZZING) + if (meas.getLength() < 0 || meas.getLength() > 100) { + return false; + } +#endif do { SkScalar length = meas.getLength(); SkScalar distance = this->begin(length); @@ -23,6 +28,11 @@ bool Sk1DPathEffect::filterPath(SkPath* dst, const SkPath& src, if (delta <= 0) { break; } +#if defined(IS_FUZZING) + if (delta <= SK_ScalarNearlyZero) { + return false; + } +#endif distance += delta; } } while (meas.nextContour()); @@ -65,6 +75,11 @@ SkPath1DPathEffect::SkPath1DPathEffect(const SkPath& path, SkScalar advance, bool SkPath1DPathEffect::filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec, const SkRect* cullRect) const { +#if defined(IS_FUZZING) + if (dst->countVerbs() > 100 || dst->countPoints() > 100) { + return false; + } +#endif if (fAdvance > 0) { rec->setFillStyle(); return this->INHERITED::filterPath(dst, src, rec, cullRect); diff --git a/src/effects/Sk2DPathEffect.cpp b/src/effects/Sk2DPathEffect.cpp index e7ef54b6f7..727aa5221f 100644 --- a/src/effects/Sk2DPathEffect.cpp +++ b/src/effects/Sk2DPathEffect.cpp @@ -51,6 +51,11 @@ void Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path) const { if (!fMatrixIsInvertible) { return; } +#if defined(IS_FUZZING) + if (count > 100) { + return; + } +#endif const SkMatrix& mat = this->getMatrix(); SkPoint src, dst; diff --git a/src/effects/SkDashPathEffect.cpp b/src/effects/SkDashPathEffect.cpp index 04f9e9e85f..e6976d62d1 100644 --- a/src/effects/SkDashPathEffect.cpp +++ b/src/effects/SkDashPathEffect.cpp @@ -367,6 +367,11 @@ void SkDashImpl::flatten(SkWriteBuffer& buffer) const { sk_sp SkDashImpl::CreateProc(SkReadBuffer& buffer) { const SkScalar phase = buffer.readScalar(); uint32_t count = buffer.getArrayCount(); +#if defined(IS_FUZZING) + if (count > 20) { + return nullptr; + } +#endif SkAutoSTArray<32, SkScalar> intervals(count); if (buffer.readScalarArray(intervals.get(), count)) { return SkDashPathEffect::Make(intervals.get(), SkToInt(count), phase); diff --git a/src/effects/SkDiscretePathEffect.cpp b/src/effects/SkDiscretePathEffect.cpp index f188bfa818..44270f1675 100644 --- a/src/effects/SkDiscretePathEffect.cpp +++ b/src/effects/SkDiscretePathEffect.cpp @@ -97,6 +97,11 @@ bool SkDiscretePathEffect::filterPath(SkPath* dst, const SkPath& src, do { SkScalar length = meas.getLength(); +#if defined(IS_FUZZING) + if (length > 1000) { + return false; + } +#endif if (fSegLength * (2 + doFill) > length) { meas.getSegment(0, length, dst, true); // to short for us to mangle diff --git a/src/effects/SkLayerDrawLooper.cpp b/src/effects/SkLayerDrawLooper.cpp index 17aa7a123d..091a4bf9c7 100644 --- a/src/effects/SkLayerDrawLooper.cpp +++ b/src/effects/SkLayerDrawLooper.cpp @@ -262,6 +262,11 @@ void SkLayerDrawLooper::flatten(SkWriteBuffer& buffer) const { sk_sp SkLayerDrawLooper::CreateProc(SkReadBuffer& buffer) { int count = buffer.readInt(); +#if defined(IS_FUZZING) + if (count > 100) { + count = 100; + } +#endif Builder builder; for (int i = 0; i < count; i++) { LayerInfo info; diff --git a/src/utils/SkInsetConvexPolygon.cpp b/src/utils/SkInsetConvexPolygon.cpp index 8a55b13390..e3c78b4e1f 100755 --- a/src/utils/SkInsetConvexPolygon.cpp +++ b/src/utils/SkInsetConvexPolygon.cpp @@ -180,6 +180,11 @@ bool SkInsetConvexPolygon(const SkPoint* inputPolygonVerts, int inputPolygonSize if (inputPolygonSize < 3) { return false; } +#if defined(IS_FUZZING) + if (inputPolygonSize > 500) { + return false; + } +#endif int winding = get_winding(inputPolygonVerts, inputPolygonSize); if (0 == winding) { diff --git a/src/utils/SkShadowTessellator.cpp b/src/utils/SkShadowTessellator.cpp index 11e8f2d5c6..60963ef288 100755 --- a/src/utils/SkShadowTessellator.cpp +++ b/src/utils/SkShadowTessellator.cpp @@ -245,6 +245,11 @@ bool SkBaseShadowTessellator::addArc(const SkVector& nextNormal, bool finishArc) SkScalar rotSin, rotCos; int numSteps; compute_radial_steps(fPrevOutset, nextNormal, fRadius, &rotSin, &rotCos, &numSteps); +#if defined(IS_FUZZING) + if (numSteps > 50 || numSteps < 0) { + return false; + } +#endif SkVector prevNormal = fPrevOutset; for (int i = 0; i < numSteps-1; ++i) { SkVector currNormal;