Fix some fuzzer bugs from Skia's image filter fuzzer

Change-Id: I432b3a351eecca0d36635e37f91d32c0e281b7d9
Reviewed-on: https://skia-review.googlesource.com/98384
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
This commit is contained in:
Robert Phillips 2018-01-23 09:58:18 -05:00 committed by Skia Commit-Bot
parent 8d4a9f01f6
commit bee273291f
5 changed files with 43 additions and 17 deletions

View File

@ -132,7 +132,7 @@ protected:
canvas->translate(10, 10);
SkPaint paint;
install(&paint, Type::kFractalNoise, 0.1f, 0.1f, 2, 0, false);
this->install(&paint, Type::kFractalNoise, 0.1f, 0.1f, 2, 0, false);
const SkScalar w = SkIntToScalar(fSize.width());
const SkScalar h = SkIntToScalar(fSize.height());

View File

@ -18,6 +18,9 @@ public:
/*!< This re-weights the filter so samples outside have no effect */
kRepeat_TileMode, /*!< Wrap around to the image's opposite edge. */
kClampToBlack_TileMode, /*!< Fill with transparent black. */
kLast_TileMode = kClampToBlack_TileMode,
// TODO: remove kMax - it is non-standard but Chromium uses it
kMax_TileMode = kClampToBlack_TileMode
};

View File

@ -28,6 +28,9 @@ public:
kClamp_TileMode = 0, /*!< Clamp to the image's edge pixels. */
kRepeat_TileMode, /*!< Wrap around to the image's opposite edge. */
kClampToBlack_TileMode, /*!< Fill with transparent black. */
kLast_TileMode = kClampToBlack_TileMode,
// TODO: remove kMax - it is non-standard but used by Chromium!
kMax_TileMode = kClampToBlack_TileMode
};

View File

@ -15,6 +15,7 @@
#include "SkColorData.h"
#include "SkColorSpaceXformer.h"
#include "SkImageFilterPriv.h"
#include "SkSafeRange.h"
#include "SkTFitsIn.h"
#include "SkGpuBlurUtils.h"
#include "SkNx.h"
@ -106,6 +107,8 @@ SkBlurImageFilterImpl::SkBlurImageFilterImpl(SkScalar sigmaX,
: INHERITED(&input, 1, cropRect), fSigma{sigmaX, sigmaY}, fTileMode(tileMode) {}
sk_sp<SkFlattenable> SkBlurImageFilterImpl::CreateProc(SkReadBuffer& buffer) {
SkSafeRange safe;
SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
SkScalar sigmaX = buffer.readScalar();
SkScalar sigmaY = buffer.readScalar();
@ -113,11 +116,15 @@ sk_sp<SkFlattenable> SkBlurImageFilterImpl::CreateProc(SkReadBuffer& buffer) {
if (buffer.isVersionLT(SkReadBuffer::kTileModeInBlurImageFilter_Version)) {
tileMode = SkBlurImageFilter::kClampToBlack_TileMode;
} else {
tileMode = static_cast<SkBlurImageFilter::TileMode>(buffer.readInt());
tileMode = safe.checkLE<SkBlurImageFilter::TileMode>(buffer.readInt(),
SkBlurImageFilter::kLast_TileMode);
}
static_assert(SkBlurImageFilter::kMax_TileMode == 2, "CreateProc");
SkASSERT(tileMode <= SkBlurImageFilter::kMax_TileMode);
static_assert(SkBlurImageFilter::kLast_TileMode == 2, "CreateProc");
if (!buffer.validate(safe)) {
return nullptr;
}
return SkBlurImageFilter::Make(
sigmaX, sigmaY, common.getInput(0), &common.cropRect(), tileMode);
@ -128,8 +135,8 @@ void SkBlurImageFilterImpl::flatten(SkWriteBuffer& buffer) const {
buffer.writeScalar(fSigma.fWidth);
buffer.writeScalar(fSigma.fHeight);
static_assert(SkBlurImageFilter::kMax_TileMode == 2, "flatten");
SkASSERT(fTileMode <= SkBlurImageFilter::kMax_TileMode);
static_assert(SkBlurImageFilter::kLast_TileMode == 2, "flatten");
SkASSERT(fTileMode <= SkBlurImageFilter::kLast_TileMode);
buffer.writeInt(static_cast<int>(fTileMode));
}

View File

@ -12,6 +12,7 @@
#include "SkColorFilter.h"
#include "SkMakeUnique.h"
#include "SkReadBuffer.h"
#include "SkSafeRange.h"
#include "SkWriteBuffer.h"
#include "SkShader.h"
#include "SkUnPreMultiply.h"
@ -321,10 +322,11 @@ public:
kFractalNoise_Type,
kTurbulence_Type,
kImprovedNoise_Type,
kFirstType = kFractalNoise_Type,
kLastType = kImprovedNoise_Type
kLast_Type = kImprovedNoise_Type
};
static const int kMaxOctaves = 255; // numOctaves must be <= 0 and <= kMaxOctaves
SkPerlinNoiseShaderImpl(SkPerlinNoiseShaderImpl::Type type, SkScalar baseFrequencyX,
SkScalar baseFrequencyY, int numOctaves, SkScalar seed,
const SkISize* tileSize);
@ -397,32 +399,41 @@ inline SkScalar smoothCurve(SkScalar t) {
} // end namespace
SkPerlinNoiseShaderImpl::SkPerlinNoiseShaderImpl(SkPerlinNoiseShaderImpl::Type type,
SkScalar baseFrequencyX,
SkScalar baseFrequencyY,
int numOctaves,
SkScalar seed,
const SkISize* tileSize)
SkScalar baseFrequencyX,
SkScalar baseFrequencyY,
int numOctaves,
SkScalar seed,
const SkISize* tileSize)
: fType(type)
, fBaseFrequencyX(baseFrequencyX)
, fBaseFrequencyY(baseFrequencyY)
, fNumOctaves(numOctaves > 255 ? 255 : numOctaves/*[0,255] octaves allowed*/)
, fNumOctaves(numOctaves > kMaxOctaves ? kMaxOctaves : numOctaves/*[0,255] octaves allowed*/)
, fSeed(seed)
, fTileSize(nullptr == tileSize ? SkISize::Make(0, 0) : *tileSize)
, fStitchTiles(!fTileSize.isEmpty())
{
SkASSERT(numOctaves >= 0 && numOctaves < 256);
SkASSERT(numOctaves >= 0 && numOctaves <= kMaxOctaves);
}
sk_sp<SkFlattenable> SkPerlinNoiseShaderImpl::CreateProc(SkReadBuffer& buffer) {
Type type = (Type)buffer.readInt();
SkSafeRange safe;
Type type = safe.checkLE<Type>(buffer.readInt(), kLast_Type);
SkScalar freqX = buffer.readScalar();
SkScalar freqY = buffer.readScalar();
int octaves = buffer.readInt();
int octaves = safe.checkLE<int>(buffer.readInt(), kMaxOctaves);
SkScalar seed = buffer.readScalar();
SkISize tileSize;
tileSize.fWidth = buffer.readInt();
tileSize.fHeight = buffer.readInt();
if (!buffer.validate(safe)) {
return nullptr;
}
switch (type) {
case kFractalNoise_Type:
return SkPerlinNoiseShader::MakeFractalNoise(freqX, freqY, octaves, seed, &tileSize);
@ -431,6 +442,8 @@ sk_sp<SkFlattenable> SkPerlinNoiseShaderImpl::CreateProc(SkReadBuffer& buffer) {
case kImprovedNoise_Type:
return SkPerlinNoiseShader::MakeImprovedNoise(freqX, freqY, octaves, seed);
default:
// Really shouldn't get here b.c. of earlier checkLE on type
buffer.validate(false);
return nullptr;
}
}