httpd: re-check the byte that breaks a partial boundary match

stream_upload() matches the closing multipart boundary byte by byte.
When a byte breaks a partial match, the matched prefix goes to flash as
data, and so does the breaking byte, without being compared against the
start of the boundary.

The boundary starts with "\r\n--", so an image whose last byte is '\r'
never completes: that '\r' starts a match, the '\r' of the boundary
breaks it and is written as data, and the rest of the boundary no
longer matches. The browser waits for a reply that never comes.

Flush the matched prefix and look at the breaking byte again from the
start of the boundary. A boundary may not contain CR, so no longer
suffix of the matched prefix can start a new match.
This commit is contained in:
DrDoof authored and d00f committed 2026-10-25 02:49:14 +02:00
1 parent f2c89fd75b
commit 714c9eb343
2 files changed
+69 -5

No files matched your search

+3 -3
View File
@@ -531,9 +531,10 @@ uint8_t stream_upload(void)
memcpy(flash_buf + write_len, boundary, bindex);
write_len += bindex;
bindex = 0;
} else {
crc16_bank1(upload_settings.p + upload_settings.bptr);
flash_buf[write_len++] = upload_settings.p[upload_settings.bptr++];
}
crc16_bank1(upload_settings.p + upload_settings.bptr);
flash_buf[write_len++] = upload_settings.p[upload_settings.bptr++];
if (write_len >= FLASH_PAGE_SIZE) {
/* The staged image spans FIRMWARE_UPLOAD_START to twice that,
* the span check_and_flash_update_image() reads back. Nothing
@@ -565,7 +566,6 @@ uint8_t stream_upload(void)
memcpy(flash_buf, flash_buf + FLASH_PAGE_SIZE, write_len);
}
}
bindex = 0;
}
} while(1);
}