Skip to content

Commit 86b0eea

Browse files
committed
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
1 parent e833b89 commit 86b0eea

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

wled00/FX_fcn.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,7 +1424,7 @@ void WS2812FX::enumerateLedmaps() {
14241424
ledmapMaxSize = 0;
14251425
ledMaps = 1;
14261426
for (int i=1; i<10; i++) {
1427-
char fileName[33];
1427+
char fileName[33] = {'\0'}; // WLEDMM ensure termination
14281428
snprintf_P(fileName, sizeof(fileName), PSTR("/ledmap%d.json"), i);
14291429
bool isFile = WLED_FS.exists(fileName);
14301430

@@ -2238,7 +2238,7 @@ void WS2812FX::loadCustomPalettes() {
22382238
bool WS2812FX::deserializeMap(uint8_t n) {
22392239
// 2D support creates its own ledmap (on the fly) if a ledmap.json exists it will overwrite built one.
22402240

2241-
char fileName[32];
2241+
char fileName[32] = {'\0'};
22422242
//WLEDMM: als support segment name ledmaps
22432243
bool isFile = false;;
22442244
if (n<10) {
@@ -2290,13 +2290,17 @@ bool WS2812FX::deserializeMap(uint8_t n) {
22902290

22912291
if (isMatrix) {
22922292
//WLEDMM: read width and height
2293+
memset(fileName, 0, sizeof(fileName)); // clear old buffer - readBytesUntil() does not terminate strings !!!
22932294
f.find("\"width\":");
22942295
f.readBytesUntil('\n', fileName, sizeof(fileName)); //hack: use fileName as we have this allocated already
2295-
uint16_t maxWidth = atoi(fileName);
2296+
uint16_t maxWidth = atoi(cleanUpName(fileName));
2297+
//DEBUG_PRINTF(" (\"width\": %s) ", fileName)
22962298

2299+
memset(fileName, 0, sizeof(fileName)); // clear old buffer
22972300
f.find("\"height\":");
22982301
f.readBytesUntil('\n', fileName, sizeof(fileName));
2299-
uint16_t maxHeight = atoi(fileName);
2302+
uint16_t maxHeight = atoi(cleanUpName(fileName));
2303+
//DEBUG_PRINTF(" (\"height\": %s) \n", fileName)
23002304

23012305
//WLEDMM: support ledmap file properties width and height: if found change segment
23022306
if (maxWidth * maxHeight > 0) {
@@ -2331,20 +2335,23 @@ bool WS2812FX::deserializeMap(uint8_t n) {
23312335

23322336
if (customMappingTable != nullptr) {
23332337
customMappingSize = Segment::maxWidth * Segment::maxHeight;
2338+
// WLEDMM reset mapping table before loading
2339+
//memset(customMappingTable, 0xFF, customMappingTableSize * sizeof(uint16_t)); // FFFF = no pixel
2340+
for (unsigned i=0; i<customMappingTableSize; i++) customMappingTable[i]=i; // "neutral" 1:1 mapping
23342341

23352342
//WLEDMM: find the map values
23362343
f.find("\"map\":[");
23372344
uint16_t i=0;
23382345
do { //for each element in the array
23392346
int mapi = f.readStringUntil(',').toInt();
2340-
// USER_PRINTF(", %d", mapi);
2341-
customMappingTable[i++] = (uint16_t) (mapi<0 ? 0xFFFFU : mapi);
2347+
// USER_PRINTF(", %d(%d)", mapi, i);
2348+
if (i < customMappingSize) customMappingTable[i++] = (uint16_t) (mapi<0 ? 0xFFFFU : mapi); // WLEDMM do not write past array bounds
23422349
} while (f.available());
23432350

23442351
loadedLedmap = n;
23452352
f.close();
23462353

2347-
USER_PRINTF("Custom ledmap: %d\n", loadedLedmap);
2354+
USER_PRINTF("Custom ledmap: %d size=%d\n", loadedLedmap, customMappingSize);
23482355
#ifdef WLED_DEBUG_MAPS
23492356
for (uint16_t j=0; j<customMappingSize; j++) { // fixing a minor warning: declaration of 'i' shadows a previous local
23502357
if (!(j%Segment::maxWidth)) DEBUG_PRINTLN();

0 commit comments

Comments
 (0)