fix: make the Explore Delete buttons send the GP DELETE APDU (v3.6.6)
ramDeleteFromExplorer() called an undefined `_ber_len()` helper, so clicking Delete / Delete All raised a ReferenceError right after the confirm and no APDU was ever sent. The inline builder also omitted the mandatory Le byte. - new pure `ramDeleteApdu(aid, withCascade)` = GP Card Spec v2.3.1 Table 11-20/23 form: `80 E4 00 <p2> <Lc> 4F <len> <AID> 00` (P2 00 = object, 80 = object and related objects), used by the Explore handler. - `scp81DeleteApdus()` (the "Delete AID" script template) now shares the same builder: it used to send the raw AID without the mandatory '4F' TLV. - tests: exact bytes for 7/16-byte AIDs and both P2 modes, the SCP81 script expectations updated to the TLV form, and a wiring check that the undefined helper call does not come back (`_ber_len(`). 611 frontend / 495 Python green; version 3.6.6; sw simple-v279.
This commit is contained in:
@@ -22,7 +22,7 @@ function extractFunc(src, name) {
|
||||
}
|
||||
|
||||
// Extract chain builder functions and dependencies
|
||||
const FNS = ['berLenStr', 'buildApdu', 'escHtml', 'esc', 'chainInit', 'chainRamBuildRowHex', 'ramFmtLifecycle', 'ramFmtPrivileges', 'ramRenderExploreHtml', 'ramStepLine', 'ramGetStatusApdu',
|
||||
const FNS = ['berLenStr', 'buildApdu', 'escHtml', 'esc', 'chainInit', 'chainRamBuildRowHex', 'ramFmtLifecycle', 'ramFmtPrivileges', 'ramRenderExploreHtml', 'ramStepLine', 'ramGetStatusApdu', 'ramDeleteApdu',
|
||||
'_parseRawElfEntry', '_parseRawAppEntry', 'ramParseElfStatus', 'ramParseAppStatus', 'parseTLV', '_parseE3Entry',
|
||||
'ramCardIdxAfterRemove', 'ramClearResults', 'ramHideProgress', 'ramOpChanged', 'ramRender', 'ramApplyCard', 'ramExecute',
|
||||
'jcAidNorm', 'jcAidName', 'jcAidSuffix', 'jcAidHtml'];
|
||||
@@ -414,3 +414,18 @@ test('ramParseAppStatus keeps 16-byte AIDs (no rawLen-1 truncation)', () => {
|
||||
]);
|
||||
assert.strictEqual(apps[3].lifecycle, '07');
|
||||
});
|
||||
|
||||
test('ramDeleteApdu builds the GP DELETE with the 4F AID TLV and Le (F0414C46416101)', () => {
|
||||
// GP Card Spec v2.3.1 Table 11-20/23: P1=00, P2.b8 = object / object+related,
|
||||
// data = '4F' AID TLV, Le=00. The old handler called an undefined helper
|
||||
// and no APDU was ever sent.
|
||||
assert.strictEqual(ramDeleteApdu('F0414C46416101', false),
|
||||
'80E40000094F07F0414C4641610100');
|
||||
assert.strictEqual(ramDeleteApdu('F0414C46416101', true),
|
||||
'80E40080094F07F0414C4641610100');
|
||||
assert.strictEqual(ramDeleteApdu('A1130001180002FFF7100E8904000200', true),
|
||||
'80E40080124F10A1130001180002FFF7100E890400020000');
|
||||
assert.strictEqual(ramDeleteApdu('', false), '');
|
||||
// the dead helper reference must not come back
|
||||
assert.ok(!html.includes('_ber_len('), 'undefined _ber_len() call is back');
|
||||
});
|
||||
|
||||
@@ -26,6 +26,8 @@ function extractFunc(src, name) {
|
||||
global.t = (s) => s;
|
||||
eval(extractFunc(html, 'cardsPskMap'));
|
||||
eval(extractFunc(html, 'scriptsParseApdus'));
|
||||
eval(extractFunc(html, 'berLenStr'));
|
||||
eval(extractFunc(html, 'ramDeleteApdu'));
|
||||
eval(extractFunc(html, 'scp81DeleteApdus'));
|
||||
eval(extractFunc(html, 'scp81LogLine'));
|
||||
eval(extractFunc(html, 'scp81LogEntryHtml'));
|
||||
@@ -82,9 +84,9 @@ test('scriptsParseApdus accepts comments and whitespace, rejects bad lines', ()
|
||||
|
||||
test('scp81DeleteApdus builds GP DELETE APDUs per AID', () => {
|
||||
assert.deepStrictEqual(scp81DeleteApdus(['A000000003000000'], '00'),
|
||||
['80E4000008A00000000300000000']);
|
||||
['80E400000A4F08A00000000300000000']);
|
||||
assert.deepStrictEqual(scp81DeleteApdus(['A000000003000000', 'A000000100'], '80'),
|
||||
['80E4800008A00000000300000000', '80E4800005A00000010000']);
|
||||
['80E400800A4F08A00000000300000000', '80E40080074F05A00000010000']);
|
||||
assert.deepStrictEqual(scp81DeleteApdus([], '00'), []);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user