From 406a254523680ce18dfaf0928ec4282fc85ffc4a Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Mon, 3 Jul 2023 15:43:47 +0200 Subject: [PATCH] inactive segments robustness improvement * Avoid uint16 underflow in width() and height(): stop > start is possible, and means "inactive segment". Without these checks, it was possible that width() and height() produce VERY large values due to underflow. --- wled00/FX.h | 6 +++--- wled00/FX_2Dfcn.cpp | 1 + wled00/FX_fcn.cpp | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/wled00/FX.h b/wled00/FX.h index 19b1fc4a..f0c26cd2 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -507,9 +507,9 @@ typedef struct Segment { inline bool hasRGB(void) const { return _isRGB; } inline bool hasWhite(void) const { return _hasW; } inline bool isCCT(void) const { return _isCCT; } - inline uint16_t width(void) const { return stop - start; } // segment width in physical pixels (length if 1D) - inline uint16_t height(void) const { return stopY - startY; } // segment height (if 2D) in physical pixels - inline uint16_t length(void) const { return width() * height(); } // segment length (count) in physical pixels + inline uint16_t width(void) const { return (stop > start) ? (stop - start) : 0; } // segment width in physical pixels (length if 1D) + inline uint16_t height(void) const { return (stopY > startY) ? (stopY - startY) : 0; } // segment height (if 2D) in physical pixels // softhack007: make sure its always > 0 + inline uint16_t length(void) const { return width() * height(); } // segment length (count) in physical pixels inline uint16_t groupLength(void) const { return grouping + spacing; } inline uint8_t getLightCapabilities(void) const { return _capabilities; } diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index f4dac68d..c9653e10 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -191,6 +191,7 @@ uint32_t WS2812FX::getPixelColorXY(uint16_t x, uint16_t y) { uint16_t /*IRAM_ATTR*/ Segment::XY(uint16_t x, uint16_t y) { uint16_t width = virtualWidth(); // segment width in logical pixels uint16_t height = virtualHeight(); // segment height in logical pixels + if ((width == 0) || (height == 0)) return 0; // softhack007 avoid div/0 return (x%width) + (y%height) * width; } diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 23f860de..2550853c 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -729,7 +729,7 @@ uint32_t Segment::getPixelColor(int i) i += start; /* offset/phase */ i += offset; - if (i >= stop) i -= length(); + if ((i >= stop) && (stop>0)) i -= length(); // avoids negative pixel index (stop = 0 is a possible value) return strip.getPixelColor(i); }