From 0a608c7dd53d141cfede28e26286603c1a5a5d74 Mon Sep 17 00:00:00 2001 From: Daniel Hutchison Date: Thu, 7 Aug 2025 15:49:20 -0600 Subject: [PATCH] Fix for last block is not multiple of blocksize --- src/zsmake.cpp | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/zsmake.cpp b/src/zsmake.cpp index aa3c056..38829be 100644 --- a/src/zsmake.cpp +++ b/src/zsmake.cpp @@ -102,16 +102,18 @@ namespace zsync2 { bool writeBlockSums(const buffer_t& buffer, size_t bytesRead) { buffer_t checksum(CHECKSUM_SIZE); - // add padding to last block - if (bytesRead < blockSize) - std::fill(checksum.begin() + bytesRead, checksum.end(), 0); + // Create a copy of the buffer for processing, padding it to blockSize if needed + buffer_t padded_buffer(buffer.begin(), buffer.begin() + bytesRead); + if (bytesRead < blockSize) { + padded_buffer.resize(blockSize, 0); // pad with zeros to reach blockSize + } // sometimes, the inconsistent use of char and unsigned char within the old zsync code base can get // annoying... - auto r = rcksum_calc_rsum_block(reinterpret_cast(buffer.data()), blockSize); + auto r = rcksum_calc_rsum_block(reinterpret_cast(padded_buffer.data()), blockSize); rcksum_calc_checksum( reinterpret_cast(checksum.data()), - reinterpret_cast(buffer.data()), + reinterpret_cast(padded_buffer.data()), blockSize ); r.a = htons(r.a); @@ -152,6 +154,21 @@ namespace zsync2 { } } + // Handle the last partial block if any data was read but stream hit EOF + if (inFile.eof()) { + auto bytesRead = (size_t) inFile.gcount(); + if (bytesRead > 0) { + SHA1Update(&sha1Ctx, reinterpret_cast(buffer.data()), bytesRead); + writeBlockSums(buffer, bytesRead); + length += bytesRead; + } + } else if (inFile.fail() || inFile.bad()) { + auto error = errno; + std::string messagePrefix = "Failed to calculate block sums: "; + logMessage(messagePrefix + strerror(error)); + return false; + } + return true; }