ela-compil/BACnet

Decoding negative integer values with a length of 3 byte (24bit) is not correct

Closed this issue · 2 comments

A negative integer value of 3 bytes in length (for example -8336180) is incorrectly decoded from BACnet. That values are decoding in C# to an integer type (32 bit), but the highest 8 bits are not set to TRUE. That's necessary to get a negative 2's complement integer value.

Original code in ASN1.cs (starting at line 1176):

public static int decode_signed24(byte[] buffer, int offset, out int value)
{
    value = (buffer[offset + 0] << 16) & 0x00ff0000;
    value |= (buffer[offset + 1] << 8) & 0x0000ff00;
    value |= buffer[offset + 2] & 0x000000ff;
    return 3;
}

Modified code that should be work:

public static int decode_signed24(byte[] buffer, int offset, out int value)
{
    value = (buffer[offset + 0] << 16) & 0x00ff0000;
    if ((value & 0x800000) != 0)
        unchecked { value |= (int)0xff000000; }
    value |= (buffer[offset + 1] << 8) & 0x0000ff00;
    value |= buffer[offset + 2] & 0x000000ff;
    return 3;
}

@Eduard-G thanks for reporting this, indeed this is a bug. I checked and it's present in base YABE source code too. I have submited a pull request, can you take a look? Through unit tests I discovered that not only decoding but also encoding was invalid in one case 🤦‍♂

@gralin thanks for fast response! Your fix is working fine. The encoding issue was very "unvisible" from system-test perspective 😉