v3.25.0 review: the DF-tree ARR resolution walk-up
The live card references 6F06 from MF-tree files (MF/7F20/6F07 -> 8B 03 6F06 14), but the resolver compared only the path's first segment: the reference fell back to the ADF.USIM copy instead of the file's own DF copy (ISO 7816-4 5.4.3.3 / TS 102 221 9.2.7 walk-up) - masked on this card only because all four copies are byte-identical. - The server reads the DF.TELECOM and DF.GSM copies too (MF/7F10/6F06, MF/7F20/6F06 - TS 51.011), best effort. - fcpArrRules resolves by the file's DF chain (own DF first, then walking up to MF); a reference with no copy in the chain resolves only when a single candidate exists, otherwise it stays silent. - The implicit form prefers the file's DF copy (6F06), walking up to the MF copy (2F06). Tests: the DF copy wins over the ADF copy; two candidates outside the chain stay unresolved; a single one resolves; the implicit walk-up; the server reads the DF-tree paths. 879 frontend + 858 Python; sw cache simple-v424.
This commit is contained in:
@@ -1021,6 +1021,43 @@ test('ignoreFciRef compares the FCI without the EF.ARR reference', async () => {
|
||||
assert.strictEqual(strict.checks.find(c => c.label === 'fci').ok, false);
|
||||
});
|
||||
|
||||
test('a 6F06 reference resolves to the file DF\'s own ARR copy', () => {
|
||||
global.t = s => s;
|
||||
// 8B 03 6F06 01: record 1 of the DF-tree copy
|
||||
const hex = '621A82054221000F0583026F4F8A01058B036F06018802004B8801B0';
|
||||
const dfCopy = { fid: '6F06', path: 'MF/7F20/6F06', records: ['8001019000'] };
|
||||
const adfCopy = { fid: '6F06', path: 'ADF.USIM/6F06', records: ['800101A40683010A950108'] };
|
||||
// the file's own DF copy wins (ISO 7816-4 5.4.3.3 walk-up)
|
||||
const df = profilerFciPreviewItems(hex, { arr: [dfCopy, adfCopy], path: 'MF/7F20/6F07' });
|
||||
assert.ok(df.includes(': always'), df);
|
||||
assert.ok(!df.includes('ADM1'), df);
|
||||
// an ADF.USIM file uses the ADF's copy
|
||||
const adf = profilerFciPreviewItems(hex, { arr: [dfCopy, adfCopy], path: 'ADF.USIM/6F07' });
|
||||
assert.ok(adf.includes(': ADM1'), adf);
|
||||
// two candidates outside the file's chain stay unresolved (silent)
|
||||
const none = profilerFciPreviewItems(hex, { arr: [dfCopy, adfCopy], path: 'MF/7F10/6F07' });
|
||||
assert.ok(!none.includes('ADM1') && !none.includes(': always'), none);
|
||||
// a single candidate outside the chain still resolves
|
||||
const uniq = profilerFciPreviewItems(hex, { arr: [adfCopy], path: 'MF/7F10/6F07' });
|
||||
assert.ok(uniq.includes(': ADM1'), uniq);
|
||||
delete global.t;
|
||||
});
|
||||
|
||||
test('the implicit form prefers the file DF\'s own ARR copy', () => {
|
||||
global.t = s => s;
|
||||
// 8B 01 01: implicit EF_ARR, record 1
|
||||
const hex = '621882054221000F0583026F4F8A01058B01018002004B8801B0';
|
||||
const dfCopy = { fid: '6F06', path: 'MF/7F20/6F06', records: ['8001019000'] };
|
||||
const mfCopy = { fid: '2F06', path: 'MF/2F06', records: ['800101A40683010A950108'] };
|
||||
// the DF's own copy wins
|
||||
const df = profilerFciPreviewItems(hex, { arr: [dfCopy, mfCopy], path: 'MF/7F20/6F07' });
|
||||
assert.ok(df.includes(': always'), df);
|
||||
// without it the walk-up reaches the MF copy
|
||||
const up = profilerFciPreviewItems(hex, { arr: [mfCopy], path: 'MF/7F20/6F07' });
|
||||
assert.ok(up.includes(': ADM1'), up);
|
||||
delete global.t;
|
||||
});
|
||||
|
||||
test('profilerResultAspects and the summary include Access rules', () => {
|
||||
const res = { checks: [
|
||||
{ label: 'exists', ok: true },
|
||||
|
||||
Reference in New Issue
Block a user