SkPDF: SkPDFMakeShader handles pathological inputs better.

Also add a unit test that crashes before this change.

Change-Id: I94e441a57a9c28e7c12bc2b214a65b41446ffab8
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/230754
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
This commit is contained in:
Hal Canary 2019-07-30 12:23:10 -04:00 committed by Skia Commit-Bot
parent 1cec69ae5c
commit d7cf0be186
2 changed files with 32 additions and 6 deletions

View File

@ -280,19 +280,21 @@ static SkPDFIndirectReference make_fallback_shader(SkPDFDocument* doc,
return SkPDFIndirectReference();
}
// Clamp the bitmap size to about 1M pixels
static const SkScalar kMaxBitmapArea = 1024 * 1024;
SkScalar bitmapArea = surfaceBBox.width() * surfaceBBox.height();
static const int kMaxBitmapArea = 1024 * 1024;
SkScalar bitmapArea = (float)surfaceBBox.width() * (float)surfaceBBox.height();
SkScalar rasterScale = 1.0f;
if (bitmapArea > kMaxBitmapArea) {
rasterScale *= SkScalarSqrt(kMaxBitmapArea / bitmapArea);
if (bitmapArea > (float)kMaxBitmapArea) {
rasterScale *= SkScalarSqrt((float)kMaxBitmapArea / bitmapArea);
}
SkISize size = {SkScalarRoundToInt(rasterScale * surfaceBBox.width()),
SkScalarRoundToInt(rasterScale * surfaceBBox.height())};
SkISize size = {
SkTClamp(SkScalarCeilToInt(rasterScale * surfaceBBox.width()), 1, kMaxBitmapArea),
SkTClamp(SkScalarCeilToInt(rasterScale * surfaceBBox.height()), 1, kMaxBitmapArea)};
SkSize scale = {SkIntToScalar(size.width()) / shaderRect.width(),
SkIntToScalar(size.height()) / shaderRect.height()};
auto surface = SkSurface::MakeRasterN32Premul(size.width(), size.height());
SkASSERT(surface);
SkCanvas* canvas = surface->getCanvas();
canvas->clear(SK_ColorTRANSPARENT);

View File

@ -17,6 +17,8 @@
#include "include/core/SkScalar.h"
#include "include/core/SkStream.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkMorphologyImageFilter.h"
#include "include/effects/SkPerlinNoiseShader.h"
#include "include/private/SkTo.h"
#include "src/core/SkGlyphRun.h"
#include "src/core/SkImageFilterPriv.h"
@ -436,4 +438,26 @@ DEF_TEST(SkPDF_Clusterator, reporter) {
}
}
DEF_TEST(fuzz875632f0, reporter) {
SkNullWStream stream;
auto doc = SkPDF::MakeDocument(&stream);
REPORTER_ASSERT(reporter, doc);
SkCanvas* canvas = doc->beginPage(128, 160);
SkAutoCanvasRestore autoCanvasRestore(canvas, false);
SkPaint layerPaint({0, 0, 0, 0});
layerPaint.setImageFilter(SkDilateImageFilter::Make(536870912, 0, nullptr, nullptr));
layerPaint.setBlendMode(SkBlendMode::kClear);
canvas->saveLayer(nullptr, &layerPaint);
canvas->saveLayer(nullptr, nullptr);
SkPaint paint;
paint.setBlendMode(SkBlendMode::kDarken);
paint.setShader(SkPerlinNoiseShader::MakeFractalNoise(0, 0, 2, 0, nullptr));
paint.setColor4f(SkColor4f{0, 0, 0 ,0});
canvas->drawPath(SkPath(), paint);
}
#endif