Summary
DateTimeUtils.timestampToString has no guard against a NaN input. Every timestamp-family ResultFormatter (timestamp, eta, off, on, in, engineStart, engineStop) forwards its numeric arg into it, so when a plugin passes NaN (from convertHHMMSSToTod("ABCD") or similar) the call falls through to new Date(NaN).toISOString() and throws RangeError: Invalid time value. Because MessageDecoder.decode() has no top-level try/catch, one malformed timestamp aborts the entire message decode.
Location
lib/DateTimeUtils.ts:79-92
public static timestampToString(time: number): string {
const date = new Date(time * 1000);
if (time < 86400) { // NaN < 86400 === false
return date.toISOString().slice(11, 19);
}
if (time < 2678400) { // NaN < 2678400 === false
return `YYYY-MM-${date.toISOString().slice(8, 19)}`;
}
// Falls through -> Invalid Date.toISOString() -> RangeError
return date.toISOString().slice(0, -5) + 'Z';
}
Reproduction
new MessageDecoder().decode({
label: '44',
text: '00ETA03,N38241W081357,330,KBNA,KBWI,1107,ABCD,0208,008.1',
});
// -> passes Label_44_ETA's 9-field length check
// -> data[6] = 'ABCD' -> convertHHMMSSToTod('ABCD') -> NaN
// -> ResultFormatter.timestamp(result, NaN) -> timestampToString(NaN)
// -> RangeError: Invalid time value, escaping MessageDecoder.decode()
Same crash path is reachable from plugins that feed a time field into ResultFormatter.timestamp/eta/off/on/in/engineStart/engineStop without validating the input is numeric — e.g. Label_44_IN, Label_44_OFF/ON, Label_QP/QR/QS, Label_22_OFF, Label_H1_M_POS, Label_H1_StarPOS, Label_16_POSA1, Label_10_Slash.
Impact
Crash-level — one malformed timestamp field takes down the whole decode, not just the field. Related NaN-guard issues (#494, #496) enumerate a different set of ResultFormatter methods and explicitly do not cover the timestamp family, so this is not already tracked.
Suggested fix
Return early if !Number.isFinite(time) (either as a NaN/undefined sentinel or an empty string), and have ResultFormatter.timestamp et al. skip pushing the item if the input isn't finite — mirroring the existing pattern in ResultFormatter.position / flightNumber / altitude.
Summary
DateTimeUtils.timestampToStringhas no guard against aNaNinput. Every timestamp-familyResultFormatter(timestamp,eta,off,on,in,engineStart,engineStop) forwards its numeric arg into it, so when a plugin passesNaN(fromconvertHHMMSSToTod("ABCD")or similar) the call falls through tonew Date(NaN).toISOString()and throwsRangeError: Invalid time value. BecauseMessageDecoder.decode()has no top-level try/catch, one malformed timestamp aborts the entire message decode.Location
lib/DateTimeUtils.ts:79-92Reproduction
Same crash path is reachable from plugins that feed a time field into
ResultFormatter.timestamp/eta/off/on/in/engineStart/engineStopwithout validating the input is numeric — e.g.Label_44_IN,Label_44_OFF/ON,Label_QP/QR/QS,Label_22_OFF,Label_H1_M_POS,Label_H1_StarPOS,Label_16_POSA1,Label_10_Slash.Impact
Crash-level — one malformed timestamp field takes down the whole decode, not just the field. Related NaN-guard issues (#494, #496) enumerate a different set of
ResultFormattermethods and explicitly do not cover the timestamp family, so this is not already tracked.Suggested fix
Return early if
!Number.isFinite(time)(either as aNaN/undefinedsentinel or an empty string), and haveResultFormatter.timestampet al. skip pushing the item if the input isn't finite — mirroring the existing pattern inResultFormatter.position/flightNumber/altitude.