diff --git a/fuzz/FuzzPathMeasure.cpp b/fuzz/FuzzPathMeasure.cpp index e6933a856f..f802cc2250 100644 --- a/fuzz/FuzzPathMeasure.cpp +++ b/fuzz/FuzzPathMeasure.cpp @@ -22,6 +22,9 @@ DEF_FUZZ(PathMeasure, fuzz) { BuildPath(fuzz, &path, SkPath::Verb::kDone_Verb); SkRect bounds = path.getBounds(); SkScalar maxDim = SkTMax(bounds.width(), bounds.height()); + if (maxDim > 10000000) { + return; + } SkScalar resScale = maxDim / 1000; SkPathMeasure measure(path, bits & 1, resScale); SkPoint position; diff --git a/src/core/SkAAClip.cpp b/src/core/SkAAClip.cpp index 24a8e58e96..3339cd0e5f 100644 --- a/src/core/SkAAClip.cpp +++ b/src/core/SkAAClip.cpp @@ -1549,6 +1549,12 @@ static void operateY(SkAAClip::Builder& builder, const SkAAClip& A, int topB = iterB.top(); int botB = iterB.bottom(); +#if defined(IS_FUZZING) + if ((botA - topA) > 100000 || (botB - topB) > 100000) { + return; + } +#endif + do { const uint8_t* rowA = nullptr; const uint8_t* rowB = nullptr; diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index b35d7f9f4c..8ae8967455 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -1098,6 +1098,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); } diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp index e6ea213146..3eecbc36bb 100644 --- a/src/core/SkImageFilter.cpp +++ b/src/core/SkImageFilter.cpp @@ -88,6 +88,12 @@ bool SkImageFilter::Common::unflatten(SkReadBuffer& buffer, int expectedCount) { return false; } +#if defined(IS_FUZZING) + if (count > 4) { + return false; + } +#endif + SkASSERT(fInputs.empty()); for (int i = 0; i < count; i++) { fInputs.push_back(buffer.readBool() ? buffer.readImageFilter() : nullptr); diff --git a/src/core/SkMallocPixelRef.cpp b/src/core/SkMallocPixelRef.cpp index 8bef6c355c..3ecc3bcaf9 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 3ff4f93405..379f68eb29 100644 --- a/src/core/SkMaskFilter.cpp +++ b/src/core/SkMaskFilter.cpp @@ -261,6 +261,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/SkPaint.cpp b/src/core/SkPaint.cpp index 9b8431e591..d0ad8b47bf 100644 --- a/src/core/SkPaint.cpp +++ b/src/core/SkPaint.cpp @@ -1327,6 +1327,13 @@ bool SkPaint::getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect SkStrokeRec rec(*this, resScale); +#if defined(IS_FUZZING) + // Prevent lines with small widths from timing out. + if (rec.getStyle() == SkStrokeRec::Style::kStroke_Style && rec.getWidth() < 0.001) { + return false; + } +#endif + const SkPath* srcPtr = &src; SkPath tmpPath; diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp index 99ac492967..c4d3fc9be0 100644 --- a/src/core/SkPath.cpp +++ b/src/core/SkPath.cpp @@ -3377,7 +3377,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/SkReadBuffer.cpp b/src/core/SkReadBuffer.cpp index e1c9d02ec0..1d98600921 100644 --- a/src/core/SkReadBuffer.cpp +++ b/src/core/SkReadBuffer.cpp @@ -279,7 +279,12 @@ sk_sp SkReadBuffer::readByteArrayAsData() { 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 } /* Format: diff --git a/src/core/SkScan_AAAPath.cpp b/src/core/SkScan_AAAPath.cpp index 9dbb271890..1f2602d159 100644 --- a/src/core/SkScan_AAAPath.cpp +++ b/src/core/SkScan_AAAPath.cpp @@ -1588,6 +1588,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_Hairline.cpp b/src/core/SkScan_Hairline.cpp index d9c0408b34..8f44cba5f3 100644 --- a/src/core/SkScan_Hairline.cpp +++ b/src/core/SkScan_Hairline.cpp @@ -121,7 +121,11 @@ void SkScan::HairLineRgn(const SkPoint array[], int arrayCount, const SkRegion* if (ix0 == ix1) {// too short to draw continue; } - +#if defined(IS_FUZZING) + if ((ix1 - ix0) > 100000 || (ix1 - ix0) < 0) { + continue; // too big to draw + } +#endif SkFixed slope = SkFixedDiv(dy, dx); SkFixed startY = SkFDot6ToFixed(y0) + (slope * ((32 - x0) & 63) >> 6); @@ -137,7 +141,11 @@ void SkScan::HairLineRgn(const SkPoint array[], int arrayCount, const SkRegion* if (iy0 == iy1) { // too short to draw continue; } - +#if defined(IS_FUZZING) + if ((iy1 - iy0) > 100000 || (iy1 - iy0) < 0) { + continue; // too big to draw + } +#endif SkFixed slope = SkFixedDiv(dx, dy); SkFixed startX = SkFDot6ToFixed(x0) + (slope * ((32 - y0) & 63) >> 6); diff --git a/src/core/SkScan_Path.cpp b/src/core/SkScan_Path.cpp index e5dd774c3b..075a1f53d2 100644 --- a/src/core/SkScan_Path.cpp +++ b/src/core/SkScan_Path.cpp @@ -249,6 +249,11 @@ static void walk_convex_edges(SkEdge* prevHead, SkPath::FillType, SkFixed dRite = riteE->fDX; int count = local_bot - local_top; SkASSERT(count >= 0); +#if defined(IS_FUZZING) + if (count > 1000) { + return; + } +#endif if (0 == (dLeft | dRite)) { int L = SkFixedRoundToInt(left); int R = SkFixedRoundToInt(rite); diff --git a/src/effects/Sk1DPathEffect.cpp b/src/effects/Sk1DPathEffect.cpp index 9195933444..1d1538b03b 100644 --- a/src/effects/Sk1DPathEffect.cpp +++ b/src/effects/Sk1DPathEffect.cpp @@ -19,6 +19,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 { int governor = MAX_REASONABLE_ITERATIONS; SkScalar length = meas.getLength(); diff --git a/src/effects/Sk2DPathEffect.cpp b/src/effects/Sk2DPathEffect.cpp index 6c2c4c2854..30826fa36b 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 aa3803a95c..a345430dcf 100644 --- a/src/effects/SkDashPathEffect.cpp +++ b/src/effects/SkDashPathEffect.cpp @@ -382,6 +382,12 @@ sk_sp SkDashImpl::CreateProc(SkReadBuffer& buffer) { return nullptr; } +#if defined(IS_FUZZING) + // TODO(kjlubick) Can this be removed now that we have the check above? + 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 46cd42bece..76c81d1b49 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 1610809456..125f8f4a18 100644 --- a/src/effects/SkLayerDrawLooper.cpp +++ b/src/effects/SkLayerDrawLooper.cpp @@ -261,6 +261,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/gpu/GrPathUtils.cpp b/src/gpu/GrPathUtils.cpp index 549a4dd411..13d52e18ca 100644 --- a/src/gpu/GrPathUtils.cpp +++ b/src/gpu/GrPathUtils.cpp @@ -401,6 +401,11 @@ void convert_noninflect_cubic_to_quads(const SkPoint p[4], SkPathPriv::FirstDirection dir, SkTArray* quads, int sublevel = 0) { +#if defined(IS_FUZZING) + if (sublevel >= 7) { + return; + } +#endif // Notation: Point a is always p[0]. Point b is p[1] unless p[1] == p[0], in which case it is // p[2]. Point d is always p[3]. Point c is p[2] unless p[2] == p[3], in which case it is p[1]. diff --git a/src/ports/SkDebug_stdio.cpp b/src/ports/SkDebug_stdio.cpp index ec4e3fec77..4bc01d5d51 100644 --- a/src/ports/SkDebug_stdio.cpp +++ b/src/ports/SkDebug_stdio.cpp @@ -12,9 +12,13 @@ #include void SkDebugf(const char format[], ...) { +#if !defined(IS_FUZZING_WITH_LIBFUZZER) va_list args; va_start(args, format); vfprintf(stderr, format, args); va_end(args); +#else + (void) format; +#endif } #endif//!defined(SK_BUILD_FOR_WIN) && !defined(SK_BUILD_FOR_ANDROID)