Fixed3232 overflow in LinearGradientContext::shadeSpan()
Speculative fix for TAP ubsan failures.
Change-Id: Id3a78adbfab04ba3404a23059cbd8c162d812c2e
Reviewed-on: https://skia-review.googlesource.com/8315
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/include/private/SkFixed.h b/include/private/SkFixed.h
index 2ef8fff..b2eea5f 100644
--- a/include/private/SkFixed.h
+++ b/include/private/SkFixed.h
@@ -145,11 +145,15 @@
typedef int64_t SkFixed3232; // 32.32
+#define SkFixed3232Max (0x7FFFFFFFFFFFFFFFLL)
+#define SkFixed3232Min (-SkFixed3232Max)
+
#define SkIntToFixed3232(x) (SkLeftShift((SkFixed3232)(x), 32))
#define SkFixed3232ToInt(x) ((int)((x) >> 32))
#define SkFixedToFixed3232(x) (SkLeftShift((SkFixed3232)(x), 16))
#define SkFixed3232ToFixed(x) ((SkFixed)((x) >> 16))
#define SkFloatToFixed3232(x) ((SkFixed3232)((x) * (65536.0f * 65536.0f)))
+#define SkFixed3232ToFloat(x) (x * (1 / (65536.0f * 65536.0f)))
#define SkScalarToFixed3232(x) SkFloatToFixed3232(x)
diff --git a/src/effects/gradients/SkClampRange.h b/src/effects/gradients/SkClampRange.h
index d3d2d08..91c259a 100644
--- a/src/effects/gradients/SkClampRange.h
+++ b/src/effects/gradients/SkClampRange.h
@@ -11,11 +11,13 @@
#include "SkFixed.h"
#include "SkScalar.h"
-#define SkGradFixed SkFixed3232
-#define SkScalarToGradFixed(x) SkScalarToFixed3232(x)
-#define SkFixedToGradFixed(x) SkFixedToFixed3232(x)
-#define SkGradFixedToFixed(x) (SkFixed)((x) >> 16)
-#define kFracMax_SkGradFixed 0xFFFFFFFFLL
+#define SkGradFixed SkFixed3232
+#define SkScalarPinToGradFixed(x) SkScalarToFixed3232(SkTPin(x, \
+ SkFixed3232ToFloat(SkFixed3232Min),\
+ SkFixed3232ToFloat(SkFixed3232Max)))
+#define SkFixedToGradFixed(x) SkFixedToFixed3232(x)
+#define SkGradFixedToFixed(x) (SkFixed)((x) >> 16)
+#define kFracMax_SkGradFixed 0xFFFFFFFFLL
/**
* Iteration fixed fx by dx, clamping as you go to [0..kFracMax_SkGradFixed], this class
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index 73247cb..1dbe2e7 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -359,15 +359,15 @@
if (fDstToIndexClass != kPerspective_MatrixClass) {
dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
- SkGradFixed dx, fx = SkScalarToGradFixed(srcPt.fX);
+ SkGradFixed dx, fx = SkScalarPinToGradFixed(srcPt.fX);
if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
const auto step = fDstToIndex.fixedStepInX(SkIntToScalar(y));
// todo: do we need a real/high-precision value for dx here?
- dx = SkScalarToGradFixed(step.fX);
+ dx = SkScalarPinToGradFixed(step.fX);
} else {
SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
- dx = SkScalarToGradFixed(fDstToIndex.getScaleX());
+ dx = SkScalarPinToGradFixed(fDstToIndex.getScaleX());
}
LinearShadeProc shadeProc = shadeSpan_linear_repeat;