Skip to content

UInt64 Message (De)serialization code truncates the value #1

@sebandraos

Description

@sebandraos

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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions