feat: CAP compatibility test as its own operation + append-only imports (v3.6.48)
The import probe no longer lives in 'Install Package (.cap file)': a
diagnostic that can leave a LOADED-only package does not belong in the
operation meant to produce a working applet. /api/ram-install no longer
takes probe_imports; the install form's probe fieldset is gone.
New RAM operation CAP compatibility test (POST /api/cap-compat): the
server runs the format check, INSTALL [for load] and the LOAD blocks only
up to the block that completes the Import component (_cap_import_end +
_cap_compat_blocks, computed from the load file and the C4 TLV framing),
then stops - no last-block flag, no INSTALL [for install], so nothing is
committed and nothing needs deleting. The verdict (imports_ok,
boundary_block/total_blocks) states it covers the LOAD/import gate only;
the link gate stays the real install's business. Verified on the real
RemMobileID CAP: the boundary is LOAD 1/64, 2/128, 3/240 for 240/120/64 B
blocks - exactly the blocks where the live cards rejected the load.
_probe_import_versions(load_file, overrides, additions) now supports
append-only synthetic imports: +AID=version appends a new entry, the
Import component's size field and the Directory's Import size are patched,
and existing entries keep their positions (constant-pool import indices
stay valid); an AID that is already imported becomes a version override.
This is the card-capability query ('does this card export package X at
>= Y?') without building a probe applet.
PWA: new op section (CAP file + analysis + the version list + block size),
ramCompatTest with inline results and ramCompatVerdict, ramProbeParse
understands +AID=version; help EN/RU documents the operation, the two-step
bisect and the gate scope.
sw cache simple-v321; tests: 538 Python / 686 Node.
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', 'ramStepComponents', 'ramInstallFailHint', 'ramProbeParse', 'ramExpandedDetailsInit', 'ramExpandedDetailsChanged', 'ramGetStatusApdu', 'ramDeleteApdu',
|
||||
const FNS = ['berLenStr', 'buildApdu', 'escHtml', 'esc', 'chainInit', 'chainRamBuildRowHex', 'ramFmtLifecycle', 'ramFmtPrivileges', 'ramRenderExploreHtml', 'ramStepLine', 'ramStepComponents', 'ramInstallFailHint', 'ramProbeParse', 'ramCompatVerdict', 'ramExpandedDetailsInit', 'ramExpandedDetailsChanged', 'ramGetStatusApdu', 'ramDeleteApdu',
|
||||
'stkParamsBuild', 'ramRemoteSwOk', 'spPorAccepted', 'ramIncrementCntr', 'ramDeleteFromExplorer', 'ramListingSpi2', 'ramRemoveFromExplorer', 'ramHasInstance', 'ramExpandedQueryApdu',
|
||||
'_parseRawElfEntry', '_parseRawAppEntry', 'ramParseElfStatus', 'ramParseAppStatus', 'parseTLV', '_parseE3Entry',
|
||||
'ramCardIdxAfterRemove', 'ramClearResults', 'ramHideProgress', 'ramOpChanged', 'ramRender', 'ramApplyCard', 'ramExecute', 'decodePrivileges', 'ramActionBtn', 'ramCapToolkitMode', 'ramOpProgressText',
|
||||
@@ -789,6 +789,31 @@ test('ramProbeParse reads AID=version lines', () => {
|
||||
assert.ok(ramProbeParse('A0000000620101=x.y').error);
|
||||
assert.ok(ramProbeParse('').error);
|
||||
assert.ok(ramProbeParse(' \n# only comments\n').error);
|
||||
// '+AID=version' appends a synthetic import (a card-capability query)
|
||||
r = ramProbeParse('+A0000000090005FFFFFFFF8912000000=1.11');
|
||||
assert.deepStrictEqual(r.map, {});
|
||||
assert.deepStrictEqual(r.additions,
|
||||
[{ aid: 'A0000000090005FFFFFFFF8912000000', version: '1.11' }]);
|
||||
r = ramProbeParse('A0000000620101=0.0\n+0102030405=1.0');
|
||||
assert.deepStrictEqual(r.map, { 'A0000000620101': '0.0' });
|
||||
assert.strictEqual(r.additions.length, 1);
|
||||
assert.ok(ramProbeParse('+all=1.0').error);
|
||||
});
|
||||
|
||||
test('ramCompatVerdict reports the import-gate verdict', () => {
|
||||
globalThis.t = s => s;
|
||||
const ok = ramCompatVerdict({ imports_ok: true, boundary_block: 3, total_blocks: 240 });
|
||||
assert.strictEqual(ok, 'Import list accepted \u2014 tested through LOAD 3/240');
|
||||
const bad = ramCompatVerdict({ imports_ok: false, boundary_block: 3, total_blocks: 240,
|
||||
error: 'remote SW 6438' });
|
||||
assert.ok(bad.startsWith('Import list rejected \u2014 tested through LOAD 3/240'), bad);
|
||||
assert.ok(bad.includes('remote SW 6438'), bad);
|
||||
assert.strictEqual(ramCompatVerdict(null), '');
|
||||
});
|
||||
|
||||
test('ramExecute dispatches the compatibility test op', () => {
|
||||
const src = extractFunc(html, 'ramExecute');
|
||||
assert.ok(/op === 'compat'/.test(src), 'the compat op must be dispatched');
|
||||
});
|
||||
|
||||
test('ramRenderExploreHtml counts apps and ELFs in the section headings', () => {
|
||||
|
||||
Reference in New Issue
Block a user