From 86b0eeafb74b8a4f36406c4c28f358f7eae7701a Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Tue, 20 Feb 2024 15:10:25 +0100 Subject: [PATCH] Ledmaps loading bugfix (wrong size, memory corruption) * File.readbytesuntil does not terminate strings. So the string buffer needs to be filled with zero's before reading. * fix crashes (mem corruption) when ledmap file has too many / too few entries. * initialize unused map places with "identity" (same led) mapping before fix: > Reading LED map from /ledmap1.json > ("width": 60edmap1.json) ("height": 90edmap1.json) > resetSegments 1 60x90 > allocLeds (0,0 to 60,90), 16200 from 0 > allocLeds (0,0 to 60,90), 16200 from 6 > deserializeMap 60 x 90 customMappingTable alloc 5400 from 0 after: > Reading LED map from /ledmap1.json > ("width": 60) ("height": 9) > resetSegments 1 60x9 > allocLeds (0,0 to 60,9), 1620 from 0 > allocLeds (0,0 to 60,9), 1620 from 6 > deserializeMap 60 x 9 > deserializemap customMappingTable alloc 540 from 0 --- wled00/FX_fcn.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index e4218ba2..4a25670e 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1424,7 +1424,7 @@ void WS2812FX::enumerateLedmaps() { ledmapMaxSize = 0; ledMaps = 1; for (int i=1; i<10; i++) { - char fileName[33]; + char fileName[33] = {'\0'}; // WLEDMM ensure termination snprintf_P(fileName, sizeof(fileName), PSTR("/ledmap%d.json"), i); bool isFile = WLED_FS.exists(fileName); @@ -2238,7 +2238,7 @@ void WS2812FX::loadCustomPalettes() { bool WS2812FX::deserializeMap(uint8_t n) { // 2D support creates its own ledmap (on the fly) if a ledmap.json exists it will overwrite built one. - char fileName[32]; + char fileName[32] = {'\0'}; //WLEDMM: als support segment name ledmaps bool isFile = false;; if (n<10) { @@ -2290,13 +2290,17 @@ bool WS2812FX::deserializeMap(uint8_t n) { if (isMatrix) { //WLEDMM: read width and height + memset(fileName, 0, sizeof(fileName)); // clear old buffer - readBytesUntil() does not terminate strings !!! f.find("\"width\":"); f.readBytesUntil('\n', fileName, sizeof(fileName)); //hack: use fileName as we have this allocated already - uint16_t maxWidth = atoi(fileName); + uint16_t maxWidth = atoi(cleanUpName(fileName)); + //DEBUG_PRINTF(" (\"width\": %s) ", fileName) + memset(fileName, 0, sizeof(fileName)); // clear old buffer f.find("\"height\":"); f.readBytesUntil('\n', fileName, sizeof(fileName)); - uint16_t maxHeight = atoi(fileName); + uint16_t maxHeight = atoi(cleanUpName(fileName)); + //DEBUG_PRINTF(" (\"height\": %s) \n", fileName) //WLEDMM: support ledmap file properties width and height: if found change segment if (maxWidth * maxHeight > 0) { @@ -2331,20 +2335,23 @@ bool WS2812FX::deserializeMap(uint8_t n) { if (customMappingTable != nullptr) { customMappingSize = Segment::maxWidth * Segment::maxHeight; + // WLEDMM reset mapping table before loading + //memset(customMappingTable, 0xFF, customMappingTableSize * sizeof(uint16_t)); // FFFF = no pixel + for (unsigned i=0; i