From 36de9791be1e880056ad983ffeaf66fa8077d436 Mon Sep 17 00:00:00 2001 From: d00f <8052722+DrDoof@users.noreply.github.com> Date: Tue, 8 Sep 2026 00:52:24 +0200 Subject: [PATCH] fileadder: track the data length instead of measuring it with strlen replaceCalls() ended with strlen(&buffer[pos]), so the length recorded for a file was the distance to its first 0x00 byte rather than the file size. The byte just past the content happens to be zero today, which is the only reason the numbers come out right. Nothing in html/ contains a 0x00 today, so this is latent, but it is a trap waiting for the first gzipped or binary asset: gzip puts a zero in the fourth byte of its header. A gzipped style.css lands in the index as 3 bytes, and since addr advances by that same value the next file is placed 3 bytes in and overwrites what came before it. Two gzipped files in html/ are enough to see it: both come out as 3 bytes and the second sits 1356 bytes inside the first. Pass the length in and return the adjusted one. The substitution shortens #{function} to #{NNN}, so the delta is known without measuring. The loops are bounded by the length as well, which also covers -n, where nothing had put a terminator in the buffer for strlen to find in the first place. No output change: the image built from an unmodified html/ is byte for byte the same before and after, and html_data.h is identical. --- tools/fileadder.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tools/fileadder.c b/tools/fileadder.c index 71d862b3..d76ea0ea 100644 --- a/tools/fileadder.c +++ b/tools/fileadder.c @@ -173,17 +173,17 @@ int addidx(const char *name, int addr, int len) /* * Replaces calls of the type #{function} in .html files being added * It is assumed that the possibly expanded string will fit into the buffer - * Returns the new length of the string + * Takes the length of the data and returns its new length */ -int replaceCalls(int pos) +int replaceCalls(int pos, int len) { int i = 0; char function_buf[256]; - while (buffer[pos + i]) { - if ((buffer[pos + i]) == '#' && (buffer[pos + i + 1] == '{')) { + while (i < len) { + if (buffer[pos + i] == '#' && i + 1 < len && buffer[pos + i + 1] == '{') { int j = 2; - while (buffer[pos + i + j]) { + while (i + j < len) { if (buffer[pos + i + j] == '}') break; function_buf[j - 2] = buffer[pos + i + j]; @@ -196,12 +196,13 @@ int replaceCalls(int pos) } function_buf[j - 2] = '\0'; - if (!buffer[pos + i + j]) - return i + j; + if (i + j >= len) + return len; // Because the buffers overlap we cannot use strcpy - memmove(&buffer[pos + i + 5], &buffer[pos + i + j], strlen(&buffer[pos + i + j]) + 1); + memmove(&buffer[pos + i + 5], &buffer[pos + i + j], len - (i + j)); sprintf(&buffer[pos + i + 2], "%03d", callNum); buffer[pos + i + 5] = '}'; + len -= j - 5; i += 6; fbuf_p += snprintf(&fbuf[fbuf_p], DEF_SIZE - fbuf_p, " %s,\n", function_buf); xbuf_p += snprintf(&xbuf[xbuf_p], DEF_SIZE - xbuf_p, "extern uint16_t %s(void);\n", function_buf); @@ -210,7 +211,7 @@ int replaceCalls(int pos) i++; } - return strlen(&buffer[pos]); + return len; } @@ -308,6 +309,7 @@ int main(int argc, char **argv) continue; size_t data_read = addfile(pathbuffer, addr); + size_t file_len = data_read; if (data_read) { if (arguments.add_zero) { buffer[addr + data_read + 1] = '\0'; @@ -316,7 +318,7 @@ int main(int argc, char **argv) printf("Data inserted from %s at 0x%x, size: %ld\n", pathbuffer, addr, data_read); } int old_len = data_read; - data_read = replaceCalls(addr); + data_read = replaceCalls(addr, file_len); if (old_len > data_read) memset(buffer + addr + data_read, 0, old_len - data_read); addidx(in_file->d_name, addr, data_read);