@@ -426,12 +426,12 @@ void initServer()
426426 }
427427 if (!correctPIN || otaLock) return ;
428428
429- // Static variables to track release check status across chunks
429+ // Static variables to track release check status across chunks
430430 static bool releaseCheckPassed = false ;
431431 static bool releaseCheckPending = true ;
432432 static size_t totalBytesReceived = 0 ;
433433 static uint8_t * metadataBuffer = nullptr ;
434- static size_t metadataBufferSize = 0 ;
434+ static size_t metadataBufferUsed = 0 ;
435435
436436 if (!index){
437437 DEBUG_PRINTLN (F (" OTA Update Start" ));
@@ -445,7 +445,7 @@ void initServer()
445445 if (metadataBuffer) {
446446 free (metadataBuffer);
447447 metadataBuffer = nullptr ;
448- metadataBufferSize = 0 ;
448+ metadataBufferUsed = 0 ;
449449 }
450450
451451 // Check if user wants to skip validation
@@ -493,28 +493,21 @@ void initServer()
493493 }
494494
495495 // Track total bytes received across all chunks
496+ size_t chunkStartOffset = totalBytesReceived;
496497 totalBytesReceived += len;
497498
498- // Check if we need to perform validation now
499- if (releaseCheckPending) {
500- // Calculate how much data we have after the metadata offset
501- size_t dataAfterOffset = (totalBytesReceived > METADATA_OFFSET) ?
502- (totalBytesReceived - METADATA_OFFSET) : 0 ;
499+ // Perform validation if we haven't done it yet and we have reached the metadata offset
500+ if (releaseCheckPending && totalBytesReceived > METADATA_OFFSET) {
503501
504- if (dataAfterOffset > 0 ) {
505- // We have data after the metadata offset, check if we can validate now
506- size_t currentChunkStart = totalBytesReceived - len;
507- size_t currentChunkAfterOffset = (currentChunkStart >= METADATA_OFFSET) ?
508- 0 : (METADATA_OFFSET - currentChunkStart);
502+ if (chunkStartOffset <= METADATA_OFFSET) {
503+ // Current chunk contains the metadata offset
504+ size_t offsetInChunk = METADATA_OFFSET - chunkStartOffset;
505+ size_t availableDataAfterOffset = len - offsetInChunk;
509506
510- if (currentChunkStart <= METADATA_OFFSET &&
511- (len - currentChunkAfterOffset) >= sizeof (wled_custom_desc_t )) {
512- // We have enough data in the current chunk to validate
507+ if (availableDataAfterOffset >= sizeof (wled_custom_desc_t )) {
508+ // We have enough data in this chunk to validate immediately
513509 char errorMessage[128 ];
514- uint8_t * validationData = data + currentChunkAfterOffset;
515- size_t validationDataSize = len - currentChunkAfterOffset;
516-
517- releaseCheckPassed = shouldAllowOTA (validationData, validationDataSize,
510+ releaseCheckPassed = shouldAllowOTA (data + offsetInChunk, availableDataAfterOffset,
518511 errorMessage, sizeof (errorMessage));
519512 releaseCheckPending = false ;
520513
@@ -525,48 +518,53 @@ void initServer()
525518 } else {
526519 DEBUG_PRINTLN (F (" OTA allowed: Release compatibility check passed" ));
527520 }
528- } else if (currentChunkStart < METADATA_OFFSET && totalBytesReceived > METADATA_OFFSET) {
529- // Metadata spans across chunks, need to buffer exactly one callback worth
521+
522+ } else {
523+ // Not enough data in this chunk, buffer it for the next chunk
524+ metadataBuffer = (uint8_t *)malloc (len - offsetInChunk);
530525 if (!metadataBuffer) {
531- // Calculate how much data we need from the previous chunk
532- size_t prevChunkDataNeeded = METADATA_OFFSET - currentChunkStart;
533- size_t totalBufferSize = prevChunkDataNeeded + len;
534-
535- metadataBuffer = (uint8_t *)malloc (totalBufferSize);
536- if (!metadataBuffer) {
537- DEBUG_PRINTLN (F (" OTA failed: Could not allocate metadata buffer" ));
538- request->send (500 , FPSTR (CONTENT_TYPE_PLAIN), F (" Out of memory for validation" ));
539- return ;
540- }
541-
542- // For now, we'll validate on the next chunk when we have more data
543- metadataBufferSize = totalBufferSize;
544- memcpy (metadataBuffer, data, len);
545- DEBUG_PRINTLN (F (" Buffering metadata for validation on next chunk" ));
526+ DEBUG_PRINTLN (F (" OTA failed: Could not allocate metadata buffer" ));
527+ request->send (500 , FPSTR (CONTENT_TYPE_PLAIN), F (" Out of memory for validation" ));
528+ return ;
529+ }
530+ memcpy (metadataBuffer, data + offsetInChunk, len - offsetInChunk);
531+ metadataBufferUsed = len - offsetInChunk;
532+ DEBUG_PRINTF_P (PSTR (" Buffered %u bytes of metadata for next chunk\n " ), metadataBufferUsed);
533+ }
534+
535+ } else if (metadataBuffer && metadataBufferUsed > 0 ) {
536+ // We have buffered metadata from previous chunk, combine with current chunk
537+ size_t totalMetadataSize = metadataBufferUsed + len;
538+
539+ if (totalMetadataSize >= sizeof (wled_custom_desc_t )) {
540+ // Create combined buffer for validation
541+ uint8_t * combinedBuffer = (uint8_t *)malloc (totalMetadataSize);
542+ if (!combinedBuffer) {
543+ DEBUG_PRINTLN (F (" OTA failed: Could not allocate combined buffer" ));
544+ request->send (500 , FPSTR (CONTENT_TYPE_PLAIN), F (" Out of memory for validation" ));
545+ return ;
546+ }
547+
548+ memcpy (combinedBuffer, metadataBuffer, metadataBufferUsed);
549+ memcpy (combinedBuffer + metadataBufferUsed, data, len);
550+
551+ char errorMessage[128 ];
552+ releaseCheckPassed = shouldAllowOTA (combinedBuffer, totalMetadataSize,
553+ errorMessage, sizeof (errorMessage));
554+ releaseCheckPending = false ;
555+
556+ // Clean up buffers
557+ free (combinedBuffer);
558+ free (metadataBuffer);
559+ metadataBuffer = nullptr ;
560+ metadataBufferUsed = 0 ;
561+
562+ if (!releaseCheckPassed) {
563+ DEBUG_PRINTF_P (PSTR (" OTA declined: %s\n " ), errorMessage);
564+ request->send (400 , FPSTR (CONTENT_TYPE_PLAIN), errorMessage);
565+ return ;
546566 } else {
547- // We have buffered data from previous chunk, combine and validate
548- memcpy (metadataBuffer + metadataBufferSize - len, data, len);
549-
550- size_t metadataOffsetInBuffer = METADATA_OFFSET - (totalBytesReceived - metadataBufferSize);
551- char errorMessage[128 ];
552-
553- releaseCheckPassed = shouldAllowOTA (metadataBuffer + metadataOffsetInBuffer,
554- metadataBufferSize - metadataOffsetInBuffer,
555- errorMessage, sizeof (errorMessage));
556- releaseCheckPending = false ;
557-
558- // Clean up buffer
559- free (metadataBuffer);
560- metadataBuffer = nullptr ;
561- metadataBufferSize = 0 ;
562-
563- if (!releaseCheckPassed) {
564- DEBUG_PRINTF_P (PSTR (" OTA declined: %s\n " ), errorMessage);
565- request->send (400 , FPSTR (CONTENT_TYPE_PLAIN), errorMessage);
566- return ;
567- } else {
568- DEBUG_PRINTLN (F (" OTA allowed: Release compatibility check passed" ));
569- }
567+ DEBUG_PRINTLN (F (" OTA allowed: Release compatibility check passed" ));
570568 }
571569 }
572570 }
@@ -586,7 +584,7 @@ void initServer()
586584 if (metadataBuffer) {
587585 free (metadataBuffer);
588586 metadataBuffer = nullptr ;
589- metadataBufferSize = 0 ;
587+ metadataBufferUsed = 0 ;
590588 }
591589
592590 // Check if validation was still pending (shouldn't happen normally)
0 commit comments