fix: BER-safe proactive TLV walks + hardened FETCH loop (v3.6.57)
The live 500 in the Explore ('OTA send error: index out of range') was a
parser bug, reproduced with the live FETCH shape: _parse_proactive_header
walked the command TLVs reading the length as a single byte, so the card's
SEND SHORT MESSAGE with its 150-byte SMS TPDU (8B 81 96) was mis-walked
into the TPDU and eventually indexed past the end (val[2] on a short
slice) - the FETCH was left unanswered and the request answered 500.
- _ber_tlv_list/_proactive_body helpers: BER lengths (_ber_len_at) plus a
bounds check that stops at a truncated TLV instead of walking into the
value; _parse_proactive_header, _parse_display_text, _parse_select_item,
_parse_setup_menu_items, _tlv_map and _decode_poll_negotiation all use
them now (the same latent bug for any long-form TLV);
- _run_proactive_chain guards every step (header parse, proactive log,
on_fetch, BIP/timer handlers): an exception is logged with the offending
FETCH bytes and the TERMINAL RESPONSE is still sent - a decoder bug can
never leave a FETCH unanswered again;
- the expanded-registry report distinguishes a request error from a remote
SW: 'ELFs: request error (index out of range) - compact listing used'.
Regression tests: the live long-form FETCH shape parses (header + TLV map +
TPDU), truncated TLVs stop the walk, and a raising parser still gets a TR.
sw cache simple-v330; tests: 553 Python / 711 Node.
This commit is contained in:
@@ -666,6 +666,14 @@ test('ramExpandedReport summarizes the query forms and the fallbacks', () => {
|
||||
{ p1: '10', label: 'ELFs', compact: true, form: 'lean', sw: '9000', entries: 3 },
|
||||
{ p1: '20', label: 'ELFs', compact: true, form: 'notags', sw: '9000', entries: 5 },
|
||||
]), 'Expanded registry: lean tag list (ELFs)');
|
||||
// a request/transport failure is not a remote status word
|
||||
assert.strictEqual(ramExpandedReport([
|
||||
{ p1: '40', label: 'Apps', compact: true, form: 'tags', sw: '9000', entries: 9 },
|
||||
{ p1: '10', label: 'ELFs', compact: true, form: null, sw: 'index out of range', transport: true },
|
||||
]), 'Expanded registry: tag list + EA (Apps) \u00b7 ELFs: request error (index out of range) \u2014 compact listing used');
|
||||
assert.strictEqual(ramExpandedReport([
|
||||
{ p1: '10', label: 'ELFs', compact: false, form: null, sw: 'index out of range', transport: true },
|
||||
]), 'Expanded registry refused by the card \u2014 compact listing only (package versions unavailable) ELFs: request error (index out of range)');
|
||||
assert.strictEqual(ramExpandedReport([]), '');
|
||||
delete globalThis.t;
|
||||
});
|
||||
@@ -707,6 +715,8 @@ test('the Explore detects the expanded query form and reports it', () => {
|
||||
assert.ok(src.includes('ramChainGetResponse(apdu)'), '61xx must be answered with a chained GET RESPONSE');
|
||||
assert.ok(!src.includes('00C00000'), 'no standalone GET RESPONSE (it answers 6700)');
|
||||
assert.ok(src.includes('ramExpandedQueryApdu(p1, form, page > 1)'), '6310 must page');
|
||||
// a transport failure must not be reported as a remote status word
|
||||
assert.ok(src.includes('transportError'), 'request errors are marked as such');
|
||||
});
|
||||
|
||||
test('ramParseAppStatus parses the expanded E3 listing (vendor traces)', () => {
|
||||
|
||||
Reference in New Issue
Block a user