aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Kevin Lubick <kjlubick@google.com>2018-05-15 13:59:54 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-16 12:40:44 +0000
commit6ee268de1238a95cd2448798ba7517ee9863a7c1 (patch)
tree5b9f958603fb3ef3ec00f2faeb07d9252618fb2e
parent37aea440fdb0257a4cffb0b41ab9745a9fc4d4fa (diff)
Fix UBSAN warnings in SkPerlinNoiseShaderImpl
Also update the docs in places. Bug: oss-fuzz:6138, oss-fuzz:6275, oss-fuzz:6118 Change-Id: Idfef4118dd6e58f8aa528365895f7d7b8ebc50e5 Reviewed-on: https://skia-review.googlesource.com/128300 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Kevin Lubick <kjlubick@google.com>
-rw-r--r--include/effects/SkPerlinNoiseShader.h4
-rw-r--r--src/shaders/SkPerlinNoiseShader.cpp11
2 files changed, 11 insertions, 4 deletions
diff --git a/include/effects/SkPerlinNoiseShader.h b/include/effects/SkPerlinNoiseShader.h
index 5bf3847ae3..6b9bcd86d1 100644
--- a/include/effects/SkPerlinNoiseShader.h
+++ b/include/effects/SkPerlinNoiseShader.h
@@ -27,9 +27,9 @@ public:
/**
* This will construct Perlin noise of the given type (Fractal Noise or Turbulence).
*
- * Both base frequencies (X and Y) have a usual range of (0..1).
+ * Both base frequencies (X and Y) have a usual range of (0..1) and must be non-negative.
*
- * The number of octaves provided should be fairly small, although no limit is enforced.
+ * The number of octaves provided should be fairly small, with a limit of 255 enforced.
* Each octave doubles the frequency, so 10 octaves would produce noise from
* baseFrequency * 1, * 2, * 4, ..., * 512, which quickly yields insignificantly small
* periods and resembles regular unstructured noise rather than Perlin noise.
diff --git a/src/shaders/SkPerlinNoiseShader.cpp b/src/shaders/SkPerlinNoiseShader.cpp
index 8f6c85a494..4895683527 100644
--- a/src/shaders/SkPerlinNoiseShader.cpp
+++ b/src/shaders/SkPerlinNoiseShader.cpp
@@ -270,7 +270,8 @@ public:
SkScalar highFrequencx =
SkScalarCeilToScalar(tileWidth * fBaseFrequency.fX) / tileWidth;
// BaseFrequency should be non-negative according to the standard.
- if (fBaseFrequency.fX / lowFrequencx < highFrequencx / fBaseFrequency.fX) {
+ // lowFrequencx can be 0 if fBaseFrequency.fX is very small.
+ if (sk_ieee_float_divide(fBaseFrequency.fX, lowFrequencx) < highFrequencx / fBaseFrequency.fX) {
fBaseFrequency.fX = lowFrequencx;
} else {
fBaseFrequency.fX = highFrequencx;
@@ -281,7 +282,8 @@ public:
SkScalarFloorToScalar(tileHeight * fBaseFrequency.fY) / tileHeight;
SkScalar highFrequency =
SkScalarCeilToScalar(tileHeight * fBaseFrequency.fY) / tileHeight;
- if (fBaseFrequency.fY / lowFrequency < highFrequency / fBaseFrequency.fY) {
+ // lowFrequency can be 0 if fBaseFrequency.fY is very small.
+ if (sk_ieee_float_divide(fBaseFrequency.fY, lowFrequency) < highFrequency / fBaseFrequency.fY) {
fBaseFrequency.fY = lowFrequency;
} else {
fBaseFrequency.fY = highFrequency;
@@ -419,6 +421,8 @@ SkPerlinNoiseShaderImpl::SkPerlinNoiseShaderImpl(SkPerlinNoiseShaderImpl::Type t
, fStitchTiles(!fTileSize.isEmpty())
{
SkASSERT(numOctaves >= 0 && numOctaves <= kMaxOctaves);
+ SkASSERT(fBaseFrequencyX >= 0);
+ SkASSERT(fBaseFrequencyY >= 0);
}
sk_sp<SkFlattenable> SkPerlinNoiseShaderImpl::CreateProc(SkReadBuffer& buffer) {
@@ -426,6 +430,9 @@ sk_sp<SkFlattenable> SkPerlinNoiseShaderImpl::CreateProc(SkReadBuffer& buffer) {
SkScalar freqX = buffer.readScalar();
SkScalar freqY = buffer.readScalar();
+ if (!buffer.validate(freqX >= 0 && freqY >= 0)) {
+ return nullptr;
+ }
int octaves = buffer.read32LE<int>(kMaxOctaves);