From 7da337780345d9b299294dc6cfe8bc1a4132cde8 Mon Sep 17 00:00:00 2001 From: "Ryan M. Lederman" Date: Tue, 12 Dec 2023 03:07:49 -0700 Subject: [PATCH 1/3] prevent null pointer access in canvases --- Adafruit_GFX.cpp | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/Adafruit_GFX.cpp b/Adafruit_GFX.cpp index af989002..5713dbe4 100644 --- a/Adafruit_GFX.cpp +++ b/Adafruit_GFX.cpp @@ -2015,6 +2015,10 @@ void GFXcanvas1::drawFastHLine(int16_t x, int16_t y, int16_t w, void GFXcanvas1::drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { // x & y already in raw (rotation 0) coordinates, no need to transform. + if (!buffer) { + return; + } + int16_t row_bytes = ((WIDTH + 7) / 8); uint8_t *ptr = &buffer[(x / 8) + y * row_bytes]; @@ -2053,6 +2057,10 @@ void GFXcanvas1::drawFastRawVLine(int16_t x, int16_t y, int16_t h, void GFXcanvas1::drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { // x & y already in raw (rotation 0) coordinates, no need to transform. + if (!buffer) { + return; + } + int16_t rowBytes = ((WIDTH + 7) / 8); uint8_t *ptr = &buffer[(x / 8) + y * rowBytes]; size_t remainingWidthBits = w; @@ -2351,10 +2359,12 @@ void GFXcanvas8::drawFastHLine(int16_t x, int16_t y, int16_t w, void GFXcanvas8::drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { // x & y already in raw (rotation 0) coordinates, no need to transform. - uint8_t *buffer_ptr = buffer + y * WIDTH + x; - for (int16_t i = 0; i < h; i++) { - (*buffer_ptr) = color; - buffer_ptr += WIDTH; + if (buffer) { + uint8_t *buffer_ptr = buffer + y * WIDTH + x; + for (int16_t i = 0; i < h; i++) { + (*buffer_ptr) = color; + buffer_ptr += WIDTH; + } } } @@ -2371,7 +2381,9 @@ void GFXcanvas8::drawFastRawVLine(int16_t x, int16_t y, int16_t h, void GFXcanvas8::drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { // x & y already in raw (rotation 0) coordinates, no need to transform. - memset(buffer + y * WIDTH + x, color, w); + if (buffer) { + memset(buffer + y * WIDTH + x, color, w); + } } /**************************************************************************/ @@ -2643,10 +2655,12 @@ void GFXcanvas16::drawFastHLine(int16_t x, int16_t y, int16_t w, void GFXcanvas16::drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { // x & y already in raw (rotation 0) coordinates, no need to transform. - uint16_t *buffer_ptr = buffer + y * WIDTH + x; - for (int16_t i = 0; i < h; i++) { - (*buffer_ptr) = color; - buffer_ptr += WIDTH; + if (buffer) { + uint16_t *buffer_ptr = buffer + y * WIDTH + x; + for (int16_t i = 0; i < h; i++) { + (*buffer_ptr) = color; + buffer_ptr += WIDTH; + } } } @@ -2662,8 +2676,10 @@ void GFXcanvas16::drawFastRawVLine(int16_t x, int16_t y, int16_t h, void GFXcanvas16::drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { // x & y already in raw (rotation 0) coordinates, no need to transform. - uint32_t buffer_index = y * WIDTH + x; - for (uint32_t i = buffer_index; i < buffer_index + w; i++) { - buffer[i] = color; + if (buffer) { + uint32_t buffer_index = y * WIDTH + x; + for (uint32_t i = buffer_index; i < buffer_index + w; i++) { + buffer[i] = color; + } } } From 620b617bbca7c5aa40d9c3a7aca97d628f36f3be Mon Sep 17 00:00:00 2001 From: "Ryan M. Lederman" Date: Tue, 12 Dec 2023 04:11:38 -0700 Subject: [PATCH 2/3] add virtual bool isValid() const --- Adafruit_GFX.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Adafruit_GFX.h b/Adafruit_GFX.h index 63c6ab68..ba5e58da 100644 --- a/Adafruit_GFX.h +++ b/Adafruit_GFX.h @@ -66,6 +66,16 @@ class Adafruit_GFX : public Print { virtual void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); + /************************************************************************/ + /*! + @brief Query whether the object is fully constructed and ready to use. + Subclasses that manage a memory buffer or other properties that may + fail to be initialized should override this method. + @returns true if the object is ready to use, false otherwise. + */ + /************************************************************************/ + virtual bool isValid() const { return true; } + // These exist only with Adafruit_GFX (no subclass overrides) void drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color); void drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, @@ -315,6 +325,7 @@ class GFXcanvas1 : public Adafruit_GFX { void fillScreen(uint16_t color); void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); + bool isValid() const { return buffer != NULL; } bool getPixel(int16_t x, int16_t y) const; /**********************************************************************/ /*! @@ -346,6 +357,7 @@ class GFXcanvas8 : public Adafruit_GFX { void fillScreen(uint16_t color); void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); + bool isValid() const { return buffer != NULL; } uint8_t getPixel(int16_t x, int16_t y) const; /**********************************************************************/ /*! @@ -372,6 +384,7 @@ class GFXcanvas16 : public Adafruit_GFX { void byteSwap(void); void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); + bool isValid() const { return buffer != NULL; } uint16_t getPixel(int16_t x, int16_t y) const; /**********************************************************************/ /*! From 8bd140f688245038e3a4b095689ae9e4b80c9a8a Mon Sep 17 00:00:00 2001 From: "Ryan M. Lederman" Date: Tue, 12 Dec 2023 04:14:22 -0700 Subject: [PATCH 3/3] add void to match existing style --- Adafruit_GFX.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Adafruit_GFX.h b/Adafruit_GFX.h index ba5e58da..6e6c0b3d 100644 --- a/Adafruit_GFX.h +++ b/Adafruit_GFX.h @@ -74,7 +74,7 @@ class Adafruit_GFX : public Print { @returns true if the object is ready to use, false otherwise. */ /************************************************************************/ - virtual bool isValid() const { return true; } + virtual bool isValid(void) const { return true; } // These exist only with Adafruit_GFX (no subclass overrides) void drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color); @@ -325,7 +325,7 @@ class GFXcanvas1 : public Adafruit_GFX { void fillScreen(uint16_t color); void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); - bool isValid() const { return buffer != NULL; } + bool isValid(void) const { return buffer != NULL; } bool getPixel(int16_t x, int16_t y) const; /**********************************************************************/ /*! @@ -357,7 +357,7 @@ class GFXcanvas8 : public Adafruit_GFX { void fillScreen(uint16_t color); void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); - bool isValid() const { return buffer != NULL; } + bool isValid(void) const { return buffer != NULL; } uint8_t getPixel(int16_t x, int16_t y) const; /**********************************************************************/ /*! @@ -384,7 +384,7 @@ class GFXcanvas16 : public Adafruit_GFX { void byteSwap(void); void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); - bool isValid() const { return buffer != NULL; } + bool isValid(void) const { return buffer != NULL; } uint16_t getPixel(int16_t x, int16_t y) const; /**********************************************************************/ /*!