fix BER long-form lengths: parseBerLen read b length bytes instead of b & 0x7F
parseBerLen treated the first long-form length byte (0x81/0x82/...) as the count of length bytes, so any TLV with a long-form length parsed as garbage: the profiler FCI decoder returned ok:false (decoded preview disappeared and never came back after editing an FCP with a '62 81 xx' outer length or a long-form inner TLV), and the same bug hit parseTlvList (C-APDU parser, INSTALL param walker), parseBerScript (expanded script rows >= 128 bytes) and readLvField. Per ISO 7816-4 5.2 / UICC_SPECS.md 1.7 the long form is 81-84 followed by (b & 0x7F) length bytes. Fixed; short-form behavior unchanged. New tests: parseBerLen short/81/82 forms, parseTlvList long-form outer and inner TLVs, fcpDecode long-form regression (81/82, nested A5, >=128-byte FCP) incl. the editor preview path. SW cache v73 -> v74.
This commit is contained in:
@@ -165,6 +165,39 @@ test('parseTlvList handles BER-TLVs', () => {
|
||||
assert.strictEqual(tlvs[1].tag, '82');
|
||||
});
|
||||
|
||||
test('parseBerLen handles short and long form lengths (ISO 7816-4 5.2)', () => {
|
||||
assert.deepStrictEqual(parseBerLen('1200', 0), { len: 18, consumed: 2 });
|
||||
assert.deepStrictEqual(parseBerLen('8112', 0), { len: 18, consumed: 4 });
|
||||
assert.deepStrictEqual(parseBerLen('820100', 0), { len: 256, consumed: 6 });
|
||||
assert.deepStrictEqual(parseBerLen('820182' + '0102030405060708', 0), { len: 386, consumed: 6 });
|
||||
});
|
||||
|
||||
test('parseTlvList parses long-form lengths (81/82)', () => {
|
||||
const short = parseTlvList('6212' + '8202412183026F078A010580020009880110');
|
||||
assert.strictEqual(short.length, 1);
|
||||
assert.strictEqual(short[0].tag, '62');
|
||||
assert.strictEqual(short[0].length, 18);
|
||||
|
||||
// same content with a long-form outer length
|
||||
const long81 = parseTlvList('628112' + '8202412183026F078A010580020009880110');
|
||||
assert.strictEqual(long81.length, 1);
|
||||
assert.strictEqual(long81[0].length, 18);
|
||||
assert.strictEqual(long81[0].value, short[0].value);
|
||||
|
||||
// 2-byte length form
|
||||
const long82 = parseTlvList('62820004' + '80020009');
|
||||
assert.strictEqual(long82.length, 1);
|
||||
assert.strictEqual(long82[0].length, 4);
|
||||
assert.strictEqual(long82[0].value, '80020009');
|
||||
|
||||
// inner TLV with a long-form length (A5 81 05 85 03 00 00 00)
|
||||
const inner = parseTlvList('A581058503000000');
|
||||
assert.strictEqual(inner.length, 1);
|
||||
assert.strictEqual(inner[0].tag, 'A5');
|
||||
assert.strictEqual(inner[0].length, 5);
|
||||
assert.strictEqual(inner[0].value, '8503000000');
|
||||
});
|
||||
|
||||
test('gsm7Decode unpacks "HI" from C824', () => {
|
||||
const bytes = new Uint8Array([0xC8, 0x24]);
|
||||
assert.strictEqual(gsm7Decode(bytes), 'HI');
|
||||
|
||||
Reference in New Issue
Block a user