diff options
-rw-r--r-- | include/private/SkSafe32.h | 3 | ||||
-rw-r--r-- | src/core/SkScan_Path.cpp | 9 |
2 files changed, 10 insertions, 2 deletions
diff --git a/include/private/SkSafe32.h b/include/private/SkSafe32.h index 40d4121b52..25058d2c76 100644 --- a/include/private/SkSafe32.h +++ b/include/private/SkSafe32.h @@ -22,6 +22,9 @@ static constexpr int32_t Sk32_sat_sub(int32_t a, int32_t b) { // To avoid UBSAN complaints about 2's compliment overflows // +static constexpr int32_t Sk32_can_overflow_add(int32_t a, int32_t b) { + return (int32_t)((uint32_t)a + (uint32_t)b); +} static constexpr int32_t Sk32_can_overflow_sub(int32_t a, int32_t b) { return (int32_t)((uint32_t)a - (uint32_t)b); } diff --git a/src/core/SkScan_Path.cpp b/src/core/SkScan_Path.cpp index 6234afe873..9c20527fbc 100644 --- a/src/core/SkScan_Path.cpp +++ b/src/core/SkScan_Path.cpp @@ -15,6 +15,7 @@ #include "SkRasterClip.h" #include "SkRectPriv.h" #include "SkRegion.h" +#include "SkSafe32.h" #include "SkTemplates.h" #include "SkTSort.h" @@ -259,8 +260,12 @@ static void walk_convex_edges(SkEdge* prevHead, SkPath::FillType, if (L < R) { blitter->blitH(L, local_top, R - L); } - left += dLeft; - rite += dRite; + // Either/both of these might overflow, since we perform this step even if + // (later) we determine that we are done with the edge, and so the computed + // left or rite edge will not be used (see update_edge). Use this helper to + // silence UBSAN when we perform the add. + left = Sk32_can_overflow_add(left, dLeft); + rite = Sk32_can_overflow_add(rite, dRite); local_top += 1; } while (--count >= 0); } |