Skip to content

[cbor] Invalid value returned for negative int32 where the absolute value is > 2^31 - 1 #124

@JacekLach

Description

@JacekLach

In #30, parsing of positive integers was fixed for the case where the uint32 value overflows a java int:

// 15-Oct-2016, as per [dataformats-binary#30], we got an edge case here
{
int v = _decode32Bits();
if (v >= 0) {
_numberInt = v;
} else {
long l = (long) v;
_numberLong = l & 0xFFFFFFFFL;
_numTypesValid = NR_LONG;
}
}

However, the parsing of negative numbers (major type 1) was not adjusted correctly:

// 15-Oct-2016, as per [dataformats-binary#30], we got an edge case here
{
int v = _decode32Bits();
if (v < 0) {
_numberLong = ((long) v) + -1L;
_numTypesValid = NR_LONG;
} else {
_numberInt = -v - 1;
}
}

The cast of _numberLong = ((long) v) + -1L; does not adequately prevent overflow; if v is negative, it has to be adjusted to represent the uint32 value, and then negated:

case 2:
    {
        int v = _decode32Bits();
        if (v < 0) {
            long unsignedV = (long) v & 0xFFFFFFFFL;
            _numberLong = -1L - unsignedV;
            _numTypesValid = NR_LONG;
        } else {
            _numberInt = -v - 1;
        }
    }
    break;

Similar adjustment is required for other sizes.

As a test case, deserializing 3A 9FF0947F should produce -2683344000; currently it results in -1611623298.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions