Skip to content

Bug: Label_ColonComma unconditionally returns decoded:true / decodeLevel:'full' for any input, even non-numeric text — emits NaN frequency silently #483

Description

@kevinelliott

Summary

Label_ColonComma.decode calls Number(message.text) / 1000, pushes the value into formatted.items, and sets decoded = true / decodeLevel = 'full' — with no validation whatsoever. For any non-numeric or empty payload, Number(...) returns NaN, and the plugin reports a "fully decoded" Aircraft Transceiver Frequency Change result with raw.frequency = NaN and the string "NaN MHz" in the formatted output.

Same false-success pattern as #463 (Label_8E) and #476 (Label_H2_02E), but for a different plugin.

Affected code

lib/plugins/Label_ColonComma.ts:14-32

decode(message: Message, options: Options = {}): DecodeResult {
  const decodeResult = this.defaultResult();
  decodeResult.decoder.name = this.name;

  decodeResult.raw.frequency = Number(message.text) / 1000;      // ← NaN on non-numeric text

  decodeResult.formatted.description =
    'Aircraft Transceiver Frequency Change';
  decodeResult.formatted.items.push({
    type: 'frequency',
    label: 'Frequency',
    value: `${decodeResult.raw.frequency} MHz`,                  // ← "NaN MHz"
    code: 'FREQ',
  });

  decodeResult.decoded = true;                                    // ← unconditional
  decodeResult.decoder.decodeLevel = 'full';                      // ← unconditional
  return decodeResult;
}

Also note: the plugin registers labels: [':;'] (colon-semicolon), but its class name is Label_ColonComma — a naming inconsistency that's worth cleaning up alongside the fix, though the label itself matches what MessageDecoder dispatches on.

Reproduction

const decoder = new MessageDecoder();

const r = decoder.decode({ label: ':;', text: 'not-a-number' });
// r.decoded === true
// r.decoder.decodeLevel === 'full'
// r.raw.frequency === NaN
// r.formatted.items[0].value === 'NaN MHz'

const r2 = decoder.decode({ label: ':;', text: '' });
// r2.decoded === true, r2.raw.frequency === 0, r2.formatted.items[0].value === '0 MHz'

The existing tests in lib/plugins/Label_ColonComma.test.ts only cover valid numeric inputs (131550, 129125).

Suggested fix

Validate the input before formatting, matching the #463 suggested pattern:

const kHz = Number(message.text);
if (!Number.isFinite(kHz) || message.text.trim().length === 0) {
  ResultFormatter.unknown(decodeResult, message.text);
  decodeResult.decoded = false;
  decodeResult.decoder.decodeLevel = 'none';
  return decodeResult;
}
decodeResult.raw.frequency = kHz / 1000;
// ... push formatted item ...
decodeResult.decoded = true;
decodeResult.decoder.decodeLevel = 'full';

Test coverage

Add cases to Label_ColonComma.test.ts:

  • text: 'not-a-number'decoded: false, decodeLevel: 'none'
  • text: ''decoded: false, decodeLevel: 'none'

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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