v3.24.0 review: the ARR fetch retry and the DF-scope note
- pysimArrEnsure no longer caches a transient /api/arr fetch failure: the next file click retries instead of silently showing no ARR rules for the rest of the card session (a success is still cached per session, and a session change refetches). - The help (EN/RU) and both AGENTS state the cache scope: only the MF (2F06) and ADF.USIM (6F06) ARR copies are read - a reference to another DF's copy is left unresolved. - Test: the transient failure retries, a success is cached, a session change refetches. 869 frontend + 856 Python; sw cache simple-v423.
This commit is contained in:
@@ -397,7 +397,7 @@
|
||||
<p class="mb-3">Подключение к локальному <a href="https://github.com/anttro/simple" class="text-blue-600 dark:text-blue-400 hover:underline">pysim-simple-server</a> для работы с картой: введите URL сервера (по умолчанию <code class="font-mono text-sm">http://127.0.0.1:8080</code>) и нажмите <strong>Подключиться</strong>. Область статуса показывает состояние ридера/карты, а <strong>Подключить карту</strong> (пере)инициализирует карту после вставки. Подвкладки: <strong>Файловый менеджер</strong>, <strong>Командная строка pySim</strong> и <strong>Отправка APDU</strong>. <strong>«Профайлер»</strong> и <strong>«Симулятор»</strong> — отдельные вкладки верхнего уровня.</p>
|
||||
|
||||
<h3 id="file-manager" class="text-lg font-medium mb-2">6.1 Файловый менеджер</h3>
|
||||
<p class="text-sm mb-2">Дерево файловой системы отображается слева; выбор файла открывает панель деталей справа. Элементы сгруппированы: DF выше EF, сортировка по <strong>FID</strong> или символьному <strong>имени</strong> (пиллы и кнопка <strong>«Проверить все файлы»</strong> закреплены над прокручиваемым деревом; выбор сохраняется в <code class="font-mono text-sm">localStorage</code>). При выборе файла над содержимым также показываются FID, тип файла, размер / структура записей и декодированный FCI — в рамке с символьным именем файла. Если FCI ссылается на свои правила доступа через запись <code class="font-mono text-sm">EF.ARR</code> (атрибут безопасности <code class="font-mono text-sm">8B</code>), правила указанной записи показываются с отступом под этой строкой: они берутся из копий <code class="font-mono text-sm">EF.ARR</code> карты (читаются один раз за сессию при equip, обновляются при сбросе/equip и после записи <code class="font-mono text-sm">EF.ARR</code>); снимок разрешает те же ссылки из собственной захваченной копии.</p>
|
||||
<p class="text-sm mb-2">Дерево файловой системы отображается слева; выбор файла открывает панель деталей справа. Элементы сгруппированы: DF выше EF, сортировка по <strong>FID</strong> или символьному <strong>имени</strong> (пиллы и кнопка <strong>«Проверить все файлы»</strong> закреплены над прокручиваемым деревом; выбор сохраняется в <code class="font-mono text-sm">localStorage</code>). При выборе файла над содержимым также показываются FID, тип файла, размер / структура записей и декодированный FCI — в рамке с символьным именем файла. Если FCI ссылается на свои правила доступа через запись <code class="font-mono text-sm">EF.ARR</code> (атрибут безопасности <code class="font-mono text-sm">8B</code>), правила указанной записи показываются с отступом под этой строкой: они берутся из копий <code class="font-mono text-sm">EF.ARR</code> карты — копии MF (<code class="font-mono text-sm">2F06</code>) и копии ADF.USIM (<code class="font-mono text-sm">6F06</code>): читаются один раз за сессию при equip, обновляются при сбросе/equip и после записи <code class="font-mono text-sm">EF.ARR</code>; снимок разрешает те же ссылки из собственной захваченной копии. Ссылка на копию ARR другого DF не разрешается (строка остаётся как есть).</p>
|
||||
<ul class="list-disc list-inside text-sm space-y-1 mb-3">
|
||||
<li><strong>Читать сырые данные / Декодировать</strong> — чтение выбранного файла в виде hex-дампа или таблицы декодированных полей (клиентские декодеры EF: IMSI, ICCID, SPN, списки PLMN, LOCI/PSLOCI/EPSLOCI, ADN/MSISDN, таблицы сервисов, SUME, …); серверный pySim JSON того же чтения остаётся доступен в свёрнутом блоке <em>pySim JSON (сервер)</em>. Подсвеченная кнопка — текущий вид; нажатие любой из них (пере)читывает файл. «Декодировать» недоступна, если для файла нет клиентского декодера (проверка по имени/FID до чтения).</li>
|
||||
<li><strong>Редактировать сырые данные</strong> — изменение hex-данных, <strong>Сохранить</strong> для записи (или <strong>Отмена</strong>); transparent-файлы редактируются в textarea, record-файлы — по одному полю на запись с флажками выбора. Декодированный вид доступен только для чтения — «Редактировать сырые данные» сначала переключает на hex-вид и при необходимости читает файл.</li>
|
||||
|
||||
+1
-1
@@ -396,7 +396,7 @@
|
||||
<p class="mb-3">Connects to a local <a href="https://github.com/anttro/simple" class="text-blue-600 dark:text-blue-400 hover:underline">pysim-simple-server</a> for live card operations: enter the server URL (default <code class="font-mono text-sm">http://127.0.0.1:8080</code>) and press <strong>Connect</strong>. The status area shows the reader/card state, and <strong>Equip card</strong> (re)initializes the card after insertion. Sub-tabs: <strong>File manager</strong>, <strong>pySim command line</strong>, and <strong>Raw APDU</strong>. The <strong>Profiler</strong> and <strong>Simulator</strong> are separate top-level tabs.</p>
|
||||
|
||||
<h3 id="file-manager" class="text-lg font-medium mb-2">6.1 File manager</h3>
|
||||
<p class="text-sm mb-2">The file system tree is displayed on the left; selecting a file opens its detail pane on the right. Entries are grouped with DFs above EFs and sorted by <strong>FID</strong> or symbolic <strong>Name</strong> (pills pinned above the scrolling tree together with <strong>Probe all files</strong>; the choice is remembered in <code class="font-mono text-sm">localStorage</code>). Selecting a file also shows its FID, file type, size / record layout and the decoded FCI — in a bordered block labelled with the file’s symbolic name — above the content pane. When the FCI references its access rules through an <code class="font-mono text-sm">EF.ARR</code> record (security attribute <code class="font-mono text-sm">8B</code>), the rules of the referenced record are shown as indented lines under that row: they are resolved from the card’s <code class="font-mono text-sm">EF.ARR</code> copies (read once per card session at equip, refreshed on reset/equip and after an <code class="font-mono text-sm">EF.ARR</code> write); a snapshot resolves the same references from its own captured copy.</p>
|
||||
<p class="text-sm mb-2">The file system tree is displayed on the left; selecting a file opens its detail pane on the right. Entries are grouped with DFs above EFs and sorted by <strong>FID</strong> or symbolic <strong>Name</strong> (pills pinned above the scrolling tree together with <strong>Probe all files</strong>; the choice is remembered in <code class="font-mono text-sm">localStorage</code>). Selecting a file also shows its FID, file type, size / record layout and the decoded FCI — in a bordered block labelled with the file’s symbolic name — above the content pane. When the FCI references its access rules through an <code class="font-mono text-sm">EF.ARR</code> record (security attribute <code class="font-mono text-sm">8B</code>), the rules of the referenced record are shown as indented lines under that row: they are resolved from the card’s <code class="font-mono text-sm">EF.ARR</code> copies — the MF copy (<code class="font-mono text-sm">2F06</code>) and the ADF.USIM copy (<code class="font-mono text-sm">6F06</code>): read once per card session at equip, refreshed on reset/equip and after an <code class="font-mono text-sm">EF.ARR</code> write; a snapshot resolves the same references from its own captured copy. A reference to another DF’s ARR copy is not resolved (the row stays as it is).</p>
|
||||
<ul class="list-disc list-inside text-sm space-y-1 mb-3">
|
||||
<li><strong>Read raw / Read decoded</strong> — read the selected file as a hex dump or as a decoded field table (client-side EF decoders: IMSI, ICCID, SPN, PLMN lists, LOCI/PSLOCI/EPSLOCI, ADN/MSISDN, service tables, SUME, …); the server-side pySim JSON of the same read stays available in the collapsed <em>pySim JSON (server)</em> disclosure. The highlighted pill is the current view; clicking either pill (re-)reads the file. <strong>Read decoded</strong> is disabled when the client-side decoders do not cover the file (name/FID check, before reading).</li>
|
||||
<li><strong>Edit raw</strong> — edit the raw hex data, <strong>Save</strong> to write back (or <strong>Cancel</strong>); transparent files use a textarea, record files one input per record with selection checkboxes. The decoded view is read-only — <strong>Edit raw</strong> switches to the hex view first and reads the file if needed.</li>
|
||||
|
||||
+2
-1
@@ -15095,7 +15095,8 @@ async function pysimArrEnsure() {
|
||||
const data = await pysimFetch('/api/arr');
|
||||
_pysimArrCache = { session: _pysimCardSession, arrs: (data && data.arrs) || [] };
|
||||
} catch (e) {
|
||||
_pysimArrCache = { session: _pysimCardSession, arrs: [] };
|
||||
// a transient fetch failure is not cached: the next click retries
|
||||
return [];
|
||||
}
|
||||
return _pysimArrCache.arrs;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,9 @@ code += extractFunc(html, 'profilerCardIccid', true) + '\n';
|
||||
code += extractFunc(html, 'profilerCheck', true) + '\n';
|
||||
code += extractFunc(html, 'profilerCheckSnapshot', true) + '\n';
|
||||
code += extractFunc(html, 'profilerScanSnapshot', true) + '\n';
|
||||
code += extractFunc(html, 'pysimArrEnsure', true) + '\n';
|
||||
code += "var _scanTarget = 'profile';\nvar profilerResults = null;\nvar profilerResultsHeader = null;\nvar profilerMismatchOnly = false;\n";
|
||||
code += "var _pysimArrCache = null;\nvar _pysimCardSession = null;\n";
|
||||
// the view-history hooks (the router lives in the page; this pure test stubs it)
|
||||
code += 'globalThis.navRecord = function() {};\nglobalThis.navReplace = function() {};\n';
|
||||
code += html.match(/const PROFILER_MASK_PREFIX4_FIDS = \{[\s\S]*?\n\};/)[0] + '\n';
|
||||
@@ -902,6 +904,32 @@ test('pysimFsInfoHtml shows the referenced ARR rules when given the cache', () =
|
||||
delete global.t;
|
||||
});
|
||||
|
||||
test('pysimArrEnsure does not cache a transient failure', async () => {
|
||||
_pysimArrCache = null;
|
||||
_pysimCardSession = 7;
|
||||
let calls = 0;
|
||||
globalThis.pysimFetch = async () => {
|
||||
calls++;
|
||||
if (calls === 1) throw new Error('server down');
|
||||
return { arrs: [{ fid: '2F06' }] };
|
||||
};
|
||||
// the failure is not cached: the next call retries and succeeds
|
||||
assert.deepStrictEqual(await pysimArrEnsure(), []);
|
||||
assert.strictEqual(_pysimArrCache, null);
|
||||
assert.deepStrictEqual(await pysimArrEnsure(), [{ fid: '2F06' }]);
|
||||
assert.strictEqual(calls, 2);
|
||||
// the success is cached for the card session
|
||||
assert.deepStrictEqual(await pysimArrEnsure(), [{ fid: '2F06' }]);
|
||||
assert.strictEqual(calls, 2);
|
||||
// a session change refetches
|
||||
_pysimCardSession = 8;
|
||||
await pysimArrEnsure();
|
||||
assert.strictEqual(calls, 3);
|
||||
delete globalThis.pysimFetch;
|
||||
_pysimArrCache = null;
|
||||
_pysimCardSession = null;
|
||||
});
|
||||
|
||||
test('pysimFsInfoHtml embeds the symbolic name in the FCI border', () => {
|
||||
global.t = s => s;
|
||||
const hex = '6212800200098202412183026F078A0105880110';
|
||||
|
||||
Reference in New Issue
Block a user