diff options
author | senorblanco <senorblanco@chromium.org> | 2014-09-29 07:57:20 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-29 07:57:20 -0700 |
commit | 3a49520696b2eca69e57884657d23fd2402ccfd1 (patch) | |
tree | dbfb5f5c4cdfa32fde5de9435f941ae6b86c3645 /src/effects | |
parent | 9f58dd047c4acd49baa54f9357b7519d5e69e6dc (diff) |
Sanitize SkMatrixConvolutionImageFilter creation params.
Apply the same memory limit in the Create() function that we do when
deserializing.
R=reed@google.com
Author: senorblanco@chromium.org
Review URL: https://codereview.chromium.org/610723002
Diffstat (limited to 'src/effects')
-rw-r--r-- | src/effects/SkMatrixConvolutionImageFilter.cpp | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp index 75e3f7a903..ae29bcb01b 100644 --- a/src/effects/SkMatrixConvolutionImageFilter.cpp +++ b/src/effects/SkMatrixConvolutionImageFilter.cpp @@ -17,6 +17,10 @@ #include "effects/GrMatrixConvolutionEffect.h" #endif +// We need to be able to read at most SK_MaxS32 bytes, so divide that +// by the size of a scalar to know how many scalars we can read. +static const int32_t gMaxKernelSize = SK_MaxS32 / sizeof(SkScalar); + SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter( const SkISize& kernelSize, const SkScalar* kernel, @@ -35,7 +39,7 @@ SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter( fKernelOffset(kernelOffset), fTileMode(tileMode), fConvolveAlpha(convolveAlpha) { - uint32_t size = fKernelSize.fWidth * fKernelSize.fHeight; + size_t size = (size_t) sk_64_mul(fKernelSize.width(), fKernelSize.height()); fKernel = SkNEW_ARRAY(SkScalar, size); memcpy(fKernel, kernel, size * sizeof(SkScalar)); SkASSERT(kernelSize.fWidth >= 1 && kernelSize.fHeight >= 1); @@ -43,6 +47,31 @@ SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter( SkASSERT(kernelOffset.fY >= 0 && kernelOffset.fY < kernelSize.fHeight); } +SkMatrixConvolutionImageFilter* SkMatrixConvolutionImageFilter::Create( + const SkISize& kernelSize, + const SkScalar* kernel, + SkScalar gain, + SkScalar bias, + const SkIPoint& kernelOffset, + TileMode tileMode, + bool convolveAlpha, + SkImageFilter* input, + const CropRect* cropRect, + uint32_t uniqueID) { + if (kernelSize.width() < 1 || kernelSize.height() < 1) { + return NULL; + } + if (gMaxKernelSize / kernelSize.fWidth < kernelSize.fHeight) { + return NULL; + } + if (!kernel) { + return NULL; + } + return SkNEW_ARGS(SkMatrixConvolutionImageFilter, (kernelSize, kernel, gain, bias, + kernelOffset, tileMode, convolveAlpha, + input, cropRect, uniqueID)); +} + #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING static bool tile_mode_is_valid(SkMatrixConvolutionImageFilter::TileMode tileMode) { switch (tileMode) { @@ -58,16 +87,13 @@ static bool tile_mode_is_valid(SkMatrixConvolutionImageFilter::TileMode tileMode SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter(SkReadBuffer& buffer) : INHERITED(1, buffer) { - // We need to be able to read at most SK_MaxS32 bytes, so divide that - // by the size of a scalar to know how many scalars we can read. - static const int32_t kMaxSize = SK_MaxS32 / sizeof(SkScalar); fKernelSize.fWidth = buffer.readInt(); fKernelSize.fHeight = buffer.readInt(); if ((fKernelSize.fWidth >= 1) && (fKernelSize.fHeight >= 1) && // Make sure size won't be larger than a signed int, // which would still be extremely large for a kernel, // but we don't impose a hard limit for kernel size - (kMaxSize / fKernelSize.fWidth >= fKernelSize.fHeight)) { + (gMaxKernelSize / fKernelSize.fWidth >= fKernelSize.fHeight)) { size_t size = fKernelSize.fWidth * fKernelSize.fHeight; fKernel = SkNEW_ARRAY(SkScalar, size); SkDEBUGCODE(bool success =) buffer.readScalarArray(fKernel, size); |