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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user