Clean up packet error handling

This commit is contained in:
Daniel Huigens 2025-05-19 20:00:34 +02:00
parent db772316a9
commit 82ce0ac421
No known key found for this signature in database
GPG Key ID: CB064A128FA90686

View File

@ -10,7 +10,6 @@ import {
import util from '../util'; import util from '../util';
import enums from '../enums'; import enums from '../enums';
import defaultConfig from '../config'; import defaultConfig from '../config';
import { GrammarError } from './grammar';
/** /**
* Instantiate a new packet given its tag * Instantiate a new packet given its tag
@ -88,7 +87,14 @@ class PacketList extends Array {
const packet = newPacketFromTag(parsed.tag, allowedPackets); const packet = newPacketFromTag(parsed.tag, allowedPackets);
packet.packets = new PacketList(); packet.packets = new PacketList();
packet.fromStream = util.isStream(parsed.packet); packet.fromStream = util.isStream(parsed.packet);
try {
await packet.read(parsed.packet, config); await packet.read(parsed.packet, config);
} catch (e) {
if (!(e instanceof UnsupportedError)) {
e.name = 'MalformedPacketError';
}
throw e;
}
await writer.write(packet); await writer.write(packet);
writtenTags.push(parsed.tag); writtenTags.push(parsed.tag);
// The `writtenTags` are only sensitive if we are parsing an _unauthenticated_ decrypted stream, // The `writtenTags` are only sensitive if we are parsing an _unauthenticated_ decrypted stream,
@ -100,20 +106,37 @@ class PacketList extends Array {
// If an implementation encounters a critical packet where the packet type is unknown in a packet sequence, // If an implementation encounters a critical packet where the packet type is unknown in a packet sequence,
// it MUST reject the whole packet sequence. On the other hand, an unknown non-critical packet MUST be ignored. // it MUST reject the whole packet sequence. On the other hand, an unknown non-critical packet MUST be ignored.
// Packet Tags from 0 to 39 are critical. Packet Tags from 40 to 63 are non-critical. // Packet Tags from 0 to 39 are critical. Packet Tags from 40 to 63 are non-critical.
const throwUnknownPacketError = e instanceof UnknownPacketError && parsed.tag <= 39; const throwUnknownPacketError =
const throwUnsupportedError = e instanceof UnsupportedError && !(e instanceof UnknownPacketError) && !config.ignoreUnsupportedPackets; e instanceof UnknownPacketError &&
const throwMalformedError = !(e instanceof UnsupportedError) && !config.ignoreMalformedPackets; parsed.tag <= 39;
const throwGrammarError = e instanceof GrammarError; // In case of unsupported packet versions/algorithms/etc, we ignore the error by default
// (unless the packet is a data packet, see below).
const throwUnsupportedError =
e instanceof UnsupportedError &&
!(e instanceof UnknownPacketError) &&
!config.ignoreUnsupportedPackets;
// In case of packet parsing errors, e.name was set to 'MalformedPacketError' above.
// By default, we throw for these errors.
const throwMalformedPacketError =
e.name === 'MalformedPacketError' &&
!config.ignoreMalformedPackets;
// The packets that support streaming are the ones that contain message data.
// Those are also the ones we want to be more strict about and throw on all errors
// (since we likely cannot process the message without these packets anyway).
const throwDataPacketError = supportsStreaming(parsed.tag);
// Throw all other errors, including `GrammarError`s and unexpected errors.
const throwOtherError = !(
e instanceof UnknownPacketError ||
e instanceof UnsupportedError ||
e.name === 'MalformedPacketError'
);
if ( if (
throwUnknownPacketError || throwUnknownPacketError ||
throwUnsupportedError || throwUnsupportedError ||
throwMalformedError || throwMalformedPacketError ||
throwGrammarError || throwDataPacketError ||
supportsStreaming(parsed.tag) throwOtherError
) { ) {
// The packets that support streaming are the ones that contain message data.
// Those are also the ones we want to be more strict about and throw on parse errors
// (since we likely cannot process the message without these packets anyway).
await writer.abort(e); await writer.abort(e);
} else { } else {
const unparsedPacket = new UnparseablePacket(parsed.tag, parsed.packet); const unparsedPacket = new UnparseablePacket(parsed.tag, parsed.packet);