-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
It appears that the serialization and deserialization code in UInt64.h truncates the value of the UInt64 to 4 bytes. This has no issues with values up to UInt32.Max
(which is plenty big enough for most real world applications) but this appears to be a potential source of errors down the line. Unless of course I'm missing some trick being used to compress the UInt64 value into 4 bytes? But that would conflict with the offset line:
offset += sizeof(this->data); // data is uint64 therefore size == 8
It's worth noting that the same is not true of the signed Int64.h, which does include all 8 bytes.
Here is a very quick sanity check I was using:
#include <iostream>
int main()
{
union
{
uint64_t real;
uint32_t base;
} u_x;
u_x.real = 5294967295;
std::cout << "u.real (size) = " << sizeof(u_x.real) << '\n';
std::cout << "u.real = " << u_x.real << '\n';
std::cout << std::hex << "u.real (hex) = " << u_x.real << '\n';
std::cout << std::hex << "u.real[0] = " << ((u_x.real >> (8 * 0)) & 0xFF) << '\n';
std::cout << std::hex << "u.real[1] = " << ((u_x.real >> (8 * 1)) & 0xFF) << '\n';
std::cout << std::hex << "u.real[2] = " << ((u_x.real >> (8 * 2)) & 0xFF) << '\n';
std::cout << std::hex << "u.real[3] = " << ((u_x.real >> (8 * 3)) & 0xFF) << '\n';
std::cout << std::hex << "u.real[4] = " << ((u_x.real >> (8 * 4)) & 0xFF) << '\n';
std::cout << std::hex << "u.real[5] = " << ((u_x.real >> (8 * 5)) & 0xFF) << '\n';
std::cout << std::hex << "u.real[6] = " << ((u_x.real >> (8 * 6)) & 0xFF) << '\n';
std::cout << std::hex << "u.real[7] = " << ((u_x.real >> (8 * 7)) & 0xFF) << '\n';
std::cout << std::hex << "u.base (hex) = " << u_x.base << '\n';
std::cout << std::hex << "u.base[0] = " << ((u_x.base >> (8 * 0)) & 0xFF) << '\n';
std::cout << std::hex << "u.base[1] = " << ((u_x.base >> (8 * 1)) & 0xFF) << '\n';
std::cout << std::hex << "u.base[2] = " << ((u_x.base >> (8 * 2)) & 0xFF) << '\n';
std::cout << std::hex << "u.base[3] = " << ((u_x.base >> (8 * 3)) & 0xFF) << '\n';
//std::cout << std::hex << "u.base[4] = " << ((u_x.base >> (8 * 4)) & 0xFF) << '\n';
//std::cout << std::hex << "u.base[5] = " << ((u_x.base >> (8 * 5)) & 0xFF) << '\n';
//std::cout << std::hex << "u.base[6] = " << ((u_x.base >> (8 * 6)) & 0xFF) << '\n';
//std::cout << std::hex << "u.base[7] = " << ((u_x.base >> (8 * 7)) & 0xFF) << '\n';
union
{
uint64_t real;
uint32_t base;
} u_data;
u_data.base = 0;
u_data.base |= ((u_x.base >> (8 * 0)) & 0xFF) << (8 * 0);
u_data.base |= ((u_x.base >> (8 * 1)) & 0xFF) << (8 * 1);
u_data.base |= ((u_x.base >> (8 * 2)) & 0xFF) << (8 * 2);
u_data.base |= ((u_x.base >> (8 * 3)) & 0xFF) << (8 * 3);
uint64_t value = u_data.base;
std::cout << "value = " << value << '\n';
}
Output:
u.real (size) = 8
u.real = 5294967295
u.real (hex) = 13b9ac9ff
u.real[0] = ff
u.real[1] = c9
u.real[2] = 9a
u.real[3] = 3b
u.real[4] = 1
u.real[5] = 0
u.real[6] = 0
u.real[7] = 0
u.base (hex) = 3b9ac9ff // missing 1 byte
u.base[0] = ff
u.base[1] = c9
u.base[2] = 9a
u.base[3] = 3b
value = 3b9ac9ff
Thanks,
Seb
Metadata
Metadata
Assignees
Labels
No labels