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); canvas->translate(10, 10);
SkPaint paint; 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 w = SkIntToScalar(fSize.width());
const SkScalar h = SkIntToScalar(fSize.height()); const SkScalar h = SkIntToScalar(fSize.height());

View File

@ -18,6 +18,9 @@ public:
/*!< This re-weights the filter so samples outside have no effect */ /*!< This re-weights the filter so samples outside have no effect */
kRepeat_TileMode, /*!< Wrap around to the image's opposite edge. */ kRepeat_TileMode, /*!< Wrap around to the image's opposite edge. */
kClampToBlack_TileMode, /*!< Fill with transparent black. */ 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 kMax_TileMode = kClampToBlack_TileMode
}; };

View File

@ -28,6 +28,9 @@ public:
kClamp_TileMode = 0, /*!< Clamp to the image's edge pixels. */ kClamp_TileMode = 0, /*!< Clamp to the image's edge pixels. */
kRepeat_TileMode, /*!< Wrap around to the image's opposite edge. */ kRepeat_TileMode, /*!< Wrap around to the image's opposite edge. */
kClampToBlack_TileMode, /*!< Fill with transparent black. */ 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 kMax_TileMode = kClampToBlack_TileMode
}; };

View File

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

View File

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