Skip to content

ReadRange bug when response contains a special log record #76

@thomasbertanier-prog

Description

@thomasbertanier-prog

Hello

When reading a TREND_LOG that contains a special log record (e.g. log-interrupted), records after it are silently missing from the result — no error, no warning.

I spent some time debugging this with Wireshark and found that the raw UDP packet is perfectly valid and complete. The issue is in decodeRange.

What's happening

Special log records don't have status flags. A normal record ends with:

1f 2a 04 00   ← closing tag 1, opening tag 2, BIT_STRING, closing tag 2

A special record ends with just:

1f            ← closing tag 1, nothing after

But decodeRange unconditionally consumes 2 tags after the datum value without validating their tag numbers. So it reads into the bytes of the next record, shifts the offset by an unpredictable amount (depends on the byte values that follow), and loses sync for everything after.

The behavior is non-deterministic — sometimes records after the special one are silently dropped, sometimes the buffer appears truncated. Took a while to figure out why the same code would behave differently depending on which records were in the response.

Reproduction

const response = await client.readRange(
    { address: '10.x.x.x:47808' },
    { type: bacnet.ObjectType.TREND_LOG, instance: 100101 },
    startIndex, 20,
    {}
);
// response contains fewer records than expected
// no error thrown
// Wireshark shows the full response is received correctly

Thanks so much for the patch ;-)

Thomas

Metadata

Metadata

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions