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>
This commit is contained in:
parent
ce243ba109
commit
1c5906f562
@ -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).
|
||||
|
@ -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
|
29
include/private/SkSafe32.h
Normal file
29
include/private/SkSafe32.h
Normal file
@ -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
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user