receiver: guard size_t underflow in compression buffer sizing

When per-image CBOR metadata comes within 32 bytes of the buffer slot
size, slot_size - (metadata_size + 32) wrapped around (size_t), passing a
huge output_size to CompressImage. That defeated the buffer-too-small
guard and let the compressor write the full image past the end of the
slot, corrupting adjacent memory; AppendImage then threw a plain
JFJochException that aborted the whole collection after the fact.

Detect metadata_size + 32 >= slot_size explicitly and throw
CompressionBufferTooSmallException, so the existing catch drops just this
frame gracefully - the case the change was meant to handle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-01 14:05:20 +02:00
co-authored by Claude Opus 4.8
parent b7613c559c
commit c67ea2fa42
+7 -1
View File
@@ -479,9 +479,15 @@ void JFJochReceiverFPGA::FrameTransformationThread(uint32_t threadid) {
const auto compression_start_time = std::chrono::steady_clock::now();
try {
// Reserve 32 bytes for close, etc. If the metadata already fills the
// slot the subtraction below would wrap (size_t), so bail out here and
// let the catch drop just this frame.
if (metadata_size + 32 >= slot_size)
throw CompressionBufferTooSmallException("CBOR metadata leaves no room for the compressed image");
size_t image_size = transformation.CompressImage(
writer_buffer + serializer.GetImageAppendOffset(),
slot_size - (metadata_size + 32)); // keep 32 byte extra for close, etc.
slot_size - (metadata_size + 32));
const auto compression_end_time = std::chrono::steady_clock::now();
message.compression_time_s = std::chrono::duration<float>(
compression_end_time - compression_start_time).count();