Same peer that uses the Guangdong fuel-cell extension also emits a
proprietary 0x83 block that is NOT in the published v1.0 spec table 8.
Empirically it follows a TLV layout: type(1) + length(2) + value(N).
Adds:
- InfoBlock.GuangdongFc.VendorTlv(typeCode, declaredLength, payload)
record + permits clause + InfoBlockType.GD_FC_VENDOR_TLV enum entry.
- GdFcVendorTlvBlockParser: typeCode injected via constructor, reads
2B big-endian length then exactly that many payload bytes. Defends
against declaredLength > remaining by truncating to remaining.
- AutoConfig: registers `new GdFcVendorTlvBlockParser(0x83)` under the
guangdong-fc catalog entry. Future unknown vendor typeCodes can be
added by inserting more instances; no new class required.
Critical correctness property — the parser is strictly bounded by the
length field, so BodyParser's main loop continues processing blocks
that come AFTER the TLV instead of having them swallowed by the
old generic Raw fallback. Three unit tests cover this:
- parsesPayloadOfDeclaredLengthExactly: round-trip a 5-byte payload
- doesNotSwallowSubsequentBlocksWhenChainedInBodyParser: feeds a body
containing 0x83 TLV(4B) followed by a 0x01 standard Vehicle block;
asserts both blocks are parsed
- truncatesPayloadIfDeclaredLengthExceedsRemaining: defensive case
Test count: 32 -> 35.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>