diff options
author | Mike Reed <reed@google.com> | 2018-01-30 16:01:33 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-01-30 21:50:30 +0000 |
commit | 1c5906f5623cc6b019281b35ba387f620f13f969 (patch) | |
tree | e201ddee1e23358511484fbb9ce8ee9883972ae4 | |
parent | ce243ba1099127faf6367ae66e32b9e83c8ecc76 (diff) |
saturate some irect ops for fuzzers
Bug: skia:
Change-Id: I1c4f879a455048652abb619814841cd687a0474a
Reviewed-on: https://skia-review.googlesource.com/101881
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Mike Reed <reed@google.com>
-rw-r--r-- | include/core/SkRect.h | 65 | ||||
-rw-r--r-- | include/private/SkPedanticMath.h | 17 | ||||
-rw-r--r-- | include/private/SkSafe32.h | 29 | ||||
-rw-r--r-- | src/effects/SkOffsetImageFilter.cpp | 4 |
4 files changed, 69 insertions, 46 deletions
diff --git a/include/core/SkRect.h b/include/core/SkRect.h index b09e53997b..0153d8ceb6 100644 --- a/include/core/SkRect.h +++ b/include/core/SkRect.h @@ -10,7 +10,7 @@ #include "SkPoint.h" #include "SkSize.h" -#include "../private/SkPedanticMath.h" +#include "../private/SkSafe32.h" #include "../private/SkTFitsIn.h" struct SkRect; @@ -96,7 +96,8 @@ struct SK_API SkIRect { @param b integer stored in fBottom @return bounds (l, t, r, b) */ - static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b) { + static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeLTRB(int32_t l, int32_t t, + int32_t r, int32_t b) { return SkIRect{l, t, r, b}; } @@ -109,8 +110,9 @@ struct SK_API SkIRect { @param h added to y and stored in fBottom @return bounds at (x, y) with width w and height h */ - static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h) { - return SkIRect{x, y, x + w, y + h}; + static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeXYWH(int32_t x, int32_t y, + int32_t w, int32_t h) { + return { x, y, Sk32_sat_add(x, w), Sk32_sat_add(y, h) }; } /** Returns left edge of SkIRect, if sorted. @@ -160,14 +162,14 @@ struct SK_API SkIRect { @return fRight minus fLeft */ - int32_t width() const { return SkSub32(fRight, fLeft); } + int32_t width() const { return Sk32_can_overflow_sub(fRight, fLeft); } /** Returns span on the y-axis. This does not check if SkIRect is sorted, or if result fits in 32-bit signed integer; result may be negative. @return fBottom minus fTop */ - int32_t height() const { return SkSub32(fBottom, fTop); } + int32_t height() const { return Sk32_can_overflow_sub(fBottom, fTop); } /** Returns spans on the x-axis and y-axis. This does not check if SkIRect is sorted, or if result fits in 32-bit signed integer; result may be negative. @@ -183,7 +185,7 @@ struct SK_API SkIRect { @return midpoint in x */ - int32_t centerX() const { return (fRight + fLeft) >> 1; } + int32_t centerX() const { return SkToS32(((int64_t)fRight + fLeft) >> 1); } /** Returns average of top edge and bottom edge. Result does not change if SkRect is sorted. Result may be incorrect if SkRect is far from the origin. @@ -192,7 +194,7 @@ struct SK_API SkIRect { @return midpoint in y */ - int32_t centerY() const { return (fBottom + fTop) >> 1; } + int32_t centerY() const { return SkToS32(((int64_t)fBottom + fTop) >> 1); } int64_t width64() const { return (int64_t)fRight - (int64_t)fLeft; } int64_t height64() const { return (int64_t)fBottom - (int64_t)fTop; } @@ -294,10 +296,10 @@ struct SK_API SkIRect { @param height added to y and stored in fBottom */ void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height) { - fLeft = x; - fTop = y; - fRight = x + width; - fBottom = y + height; + fLeft = x; + fTop = y; + fRight = Sk32_sat_add(x, width); + fBottom = Sk32_sat_add(y, height); } /** Returns SkIRect offset by (dx, dy). @@ -312,7 +314,10 @@ struct SK_API SkIRect { @return SkRect offset in x or y, with original width and height */ SkIRect makeOffset(int32_t dx, int32_t dy) const { - return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy); + return { + Sk32_sat_add(fLeft, dx), Sk32_sat_add(fTop, dy), + Sk32_sat_add(fRight, dx), Sk32_sat_add(fBottom, dy), + }; } /** Returns SkIRect, inset by (dx, dy). @@ -327,7 +332,10 @@ struct SK_API SkIRect { @return SkRect inset symmetrically left and right, top and bottom */ SkIRect makeInset(int32_t dx, int32_t dy) const { - return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy); + return { + Sk32_sat_add(fLeft, dx), Sk32_sat_add(fTop, dy), + Sk32_sat_sub(fRight, dx), Sk32_sat_sub(fBottom, dy), + }; } /** Returns SkIRect, outset by (dx, dy). @@ -342,7 +350,10 @@ struct SK_API SkIRect { @return SkRect outset symmetrically left and right, top and bottom */ SkIRect makeOutset(int32_t dx, int32_t dy) const { - return MakeLTRB(fLeft - dx, fTop - dy, fRight + dx, fBottom + dy); + return { + Sk32_sat_sub(fLeft, dx), Sk32_sat_sub(fTop, dy), + Sk32_sat_add(fRight, dx), Sk32_sat_add(fBottom, dy), + }; } /** Offsets SkIRect by adding dx to fLeft, fRight; and by adding dy to fTop, fBottom. @@ -356,10 +367,10 @@ struct SK_API SkIRect { @param dy offset added to fTop and fBottom */ void offset(int32_t dx, int32_t dy) { - fLeft += dx; - fTop += dy; - fRight += dx; - fBottom += dy; + fLeft = Sk32_sat_add(fLeft, dx); + fTop = Sk32_sat_add(fTop, dy); + fRight = Sk32_sat_add(fRight, dx); + fBottom = Sk32_sat_add(fBottom, dy); } /** Offsets SkIRect by adding delta.fX to fLeft, fRight; and by adding delta.fY to @@ -383,10 +394,10 @@ struct SK_API SkIRect { @param newY stored in fTop, preserving height() */ void offsetTo(int32_t newX, int32_t newY) { - fRight += newX - fLeft; - fBottom += newY - fTop; - fLeft = newX; - fTop = newY; + fRight = Sk64_pin_to_s32((int64_t)fRight + newX - fLeft); + fBottom = Sk64_pin_to_s32((int64_t)fBottom + newY - fTop); + fLeft = newX; + fTop = newY; } /** Insets SkIRect by (dx,dy). @@ -400,10 +411,10 @@ struct SK_API SkIRect { @param dy offset added to fTop and subtracted from fBottom */ void inset(int32_t dx, int32_t dy) { - fLeft += dx; - fTop += dy; - fRight -= dx; - fBottom -= dy; + fLeft = Sk32_sat_add(fLeft, dx); + fTop = Sk32_sat_add(fTop, dy); + fRight = Sk32_sat_sub(fRight, dx); + fBottom = Sk32_sat_sub(fBottom, dy); } /** Outsets SkIRect by (dx, dy). diff --git a/include/private/SkPedanticMath.h b/include/private/SkPedanticMath.h deleted file mode 100644 index 6d9c8a18be..0000000000 --- a/include/private/SkPedanticMath.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2018 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkPedanticMath_DEFINED -#define SkPedanticMath_DEFINED - -// To avoid UBSAN complaints about 2's compliment overflows -// -static inline int32_t SkSub32(int32_t a, int32_t b) { - return (int32_t)((uint32_t)a - (uint32_t)b); -} - -#endif diff --git a/include/private/SkSafe32.h b/include/private/SkSafe32.h new file mode 100644 index 0000000000..40d4121b52 --- /dev/null +++ b/include/private/SkSafe32.h @@ -0,0 +1,29 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSafe32_DEFINED +#define SkSafe32_DEFINED + +static constexpr int32_t Sk64_pin_to_s32(int64_t x) { + return x < SK_MinS32 ? SK_MinS32 : (x > SK_MaxS32 ? SK_MaxS32 : x); +} + +static constexpr int32_t Sk32_sat_add(int32_t a, int32_t b) { + return Sk64_pin_to_s32((int64_t)a + (int64_t)b); +} + +static constexpr int32_t Sk32_sat_sub(int32_t a, int32_t b) { + return Sk64_pin_to_s32((int64_t)a - (int64_t)b); +} + +// To avoid UBSAN complaints about 2's compliment overflows +// +static constexpr int32_t Sk32_can_overflow_sub(int32_t a, int32_t b) { + return (int32_t)((uint32_t)a - (uint32_t)b); +} + +#endif diff --git a/src/effects/SkOffsetImageFilter.cpp b/src/effects/SkOffsetImageFilter.cpp index a833987185..1141bfa281 100644 --- a/src/effects/SkOffsetImageFilter.cpp +++ b/src/effects/SkOffsetImageFilter.cpp @@ -44,8 +44,8 @@ sk_sp<SkSpecialImage> SkOffsetImageFilter::onFilterImage(SkSpecialImage* source, SkIPoint vec = map_offset_vector(ctx.ctm(), fOffset); if (!this->cropRectIsSet()) { - offset->fX = srcOffset.fX + vec.fX; - offset->fY = srcOffset.fY + vec.fY; + offset->fX = Sk32_sat_add(srcOffset.fX, vec.fX); + offset->fY = Sk32_sat_add(srcOffset.fY, vec.fY); return input; } else { SkIRect bounds; |