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'
Summary
Label_ColonComma.decodecallsNumber(message.text) / 1000, pushes the value intoformatted.items, and setsdecoded = true/decodeLevel = 'full'— with no validation whatsoever. For any non-numeric or empty payload,Number(...)returnsNaN, and the plugin reports a "fully decoded"Aircraft Transceiver Frequency Changeresult withraw.frequency = NaNand 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-32Also note: the plugin registers
labels: [':;'](colon-semicolon), but its class name isLabel_ColonComma— a naming inconsistency that's worth cleaning up alongside the fix, though the label itself matches whatMessageDecoderdispatches on.Reproduction
The existing tests in
lib/plugins/Label_ColonComma.test.tsonly cover valid numeric inputs (131550,129125).Suggested fix
Validate the input before formatting, matching the
#463suggested pattern:Test coverage
Add cases to
Label_ColonComma.test.ts:text: 'not-a-number'→decoded: false,decodeLevel: 'none'text: ''→decoded: false,decodeLevel: 'none'