diff --git a/c++/src/capnp/layout.c++ b/c++/src/capnp/layout.c++ index 07606ef4d9ed00cd405425df51a02e3bbcb12d13..ab41c38d767a2e91b356ffbef4e9c9e216300ad6 100644 --- a/c++/src/capnp/layout.c++ +++ b/c++/src/capnp/layout.c++ @@ -1812,13 +1812,14 @@ struct WireHelpers { // List of data. ref->listRef.set(value.elementSize, value.elementCount); - auto wholeByteSize = value.elementCount * value.step / BITS_PER_BYTE; + auto wholeByteSize = upgradeBound<uint64_t>(value.elementCount) * value.step / BITS_PER_BYTE; copyMemory(reinterpret_cast<byte*>(ptr), value.ptr, wholeByteSize); - auto leftoverBits = value.elementCount * value.step % BITS_PER_BYTE; - if (leftoverBits > 0) { + auto leftoverBits = + (upgradeBound<uint64_t>(value.elementCount) * value.step) % (BYTES * BITS_PER_BYTE); + if (leftoverBits > ZERO * BITS) { // We need to copy a partial byte. - uint8_t mask = (1 << leftoverBits) - 1; - (reinterpret_cast<byte*>(ptr))[wholeByteSize] = mask & value.ptr[wholeByteSize]; + uint8_t mask = (1 << leftoverBits / BITS) - 1; + *((reinterpret_cast<byte*>(ptr)) + wholeByteSize) = mask & *(value.ptr + wholeByteSize); } } @@ -3162,9 +3163,10 @@ bool ListReader::isCanonical(const word **readHead, const WirePointer *ref) { auto byteReadHead = reinterpret_cast<const uint8_t*>(*readHead) + truncatedByteSize; auto readHeadEnd = *readHead + WireHelpers::roundBitsUpToWords(bitSize); - auto leftoverBits = bitSize % 8; - if (leftoverBits > 0) { - uint8_t mask = ~((1 << leftoverBits) - 1); + auto leftoverBits = bitSize % (BYTES * BITS_PER_BYTE); + if (leftoverBits > ZERO * BITS) { + auto mask = ~((1 << (leftoverBits / BITS)) - 1); + if (mask & *byteReadHead) { return false; }