Skip to content

Bug: Label_QQ groundspeed --- guard reads the wrong field (decodeResult.remaining.text), silently emits NaN groundspeed #507

Description

@kevinelliott

Summary

Label_QQ.decode() decodes the groundspeed field at message.text.substring(45, 48), and clearly intends to skip decoding it (calling ResultFormatter.unknown instead) when it is the placeholder ---. But the guard tests decodeResult.remaining.text, not the groundspeed field itself — and by the time the check runs, remaining.text reflects the previous unknown field at substring(42, 45), not the groundspeed field at substring(45, 48).

Result: any QQ message where the 45–48 field is --- but the 42–45 field is anything else passes the guard and calls ResultFormatter.groundspeed(decodeResult, Number('---')), storing NaN and rendering "NaN knots".

Location

lib/plugins/Label_QQ.ts:43-53

ResultFormatter.unknown(decodeResult, message.text.substring(42, 45));
ResultFormatter.position(decodeResult, pos);

if (decodeResult.remaining.text !== '---') {
  ResultFormatter.groundspeed(
    decodeResult,
    Number(message.text.substring(45, 48)),
  );
} else {
  ResultFormatter.unknown(decodeResult, message.text.substring(45, 48));
}

Why the guard is wrong

ResultFormatter.unknown appends to decodeResult.remaining.text (see lib/utils/result_formatter.ts:683-684):

if (!decodeResult.remaining.text) decodeResult.remaining.text = value;
else decodeResult.remaining.text += sep + value;

So after the substring(42, 45) call on the line above, remaining.text ends in that field's value. Checking remaining.text !== '---' is therefore checking the 42–45 field, not the groundspeed field the branch is about to decode.

The current tests don't catch this because in both fixture variants, either both fields are --- or neither is.

Reproduction

const msg = {
  label: 'QQ',
  text: 'KLGBKLAX0004\r\n001FE07000444N3349.8W11810.1028---0009',
};
const result = new Label_QQ().decode(msg);
// Actual:   result.raw.groundspeed === NaN, formatted contains "NaN knots"
// Expected: no groundspeed decoded; 45..48 recorded as unknown

Here substring(42, 45) is '028' (not ---), so the guard passes, but substring(45, 48) is '---', which Number('---') yields NaN.

Suggested fix

Read the field directly instead of the accumulated remaining.text:

const gsField = message.text.substring(45, 48);
if (gsField !== '---') {
  ResultFormatter.groundspeed(decodeResult, Number(gsField));
} else {
  ResultFormatter.unknown(decodeResult, gsField);
}

Add a test case covering the 028--- split.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions