frame_serialize: write CBOR length big-endian without bswap intrinsic

AppendImage wrote the CBOR byte-string length (major type 2, 8-byte length,
which is defined big-endian) via __builtin_bswap64 under #ifdef LITTLE_ENDIAN.
That is broken two ways off GCC/Clang+glibc: __builtin_bswap64 is not available
on MSVC, and LITTLE_ENDIAN is not defined there, so the #else path skipped the
swap and emitted a little-endian length on a little-endian host -> corrupt
frames.

Write the 8 length bytes most-significant-first directly. This is big-endian by
construction on any host, needs no byte-swap intrinsic and no endianness macro,
and is byte-for-byte identical to the previous output on little-endian hosts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-18 15:02:39 +02:00
co-authored by Claude Opus 4.8
parent 5d9e1be814
commit bee35f7a25
+7 -6
View File
@@ -917,12 +917,13 @@ void CBORStream2Serializer::AppendImage(size_t image_size) {
buffer[curr_size - 2] = 0x40 + 27;
curr_size--;
#ifdef LITTLE_ENDIAN
size_t image_size_be = __builtin_bswap64(image_size);
#else
size_t image_size_be = image_size;
#endif
memcpy(buffer + curr_size, &image_size_be, sizeof(size_t));
// CBOR encodes the byte-string length as a big-endian 64-bit integer (major
// type 2, additional info 27). Write it big-endian byte-by-byte so the result
// is correct on any host endianness and needs no compiler-specific byte-swap
// intrinsic (__builtin_bswap64 is GCC/Clang-only; MSVC lacks it).
const uint64_t image_size_be = image_size;
for (size_t k = 0; k < sizeof(uint64_t); ++k)
buffer[curr_size + k] = static_cast<uint8_t>(image_size_be >> (8 * (sizeof(uint64_t) - 1 - k)));
curr_size += sizeof(size_t);
curr_size += image_size + 0;
buffer[curr_size] = 0xFF;