diff --git a/frontend/help-ru.html b/frontend/help-ru.html index 968e829..35fc682 100644 --- a/frontend/help-ru.html +++ b/frontend/help-ru.html @@ -319,7 +319,7 @@ ОперацияОписание Обзор карты (все данные GP)Запрос GET STATUS для ISD, приложений, ELF и модулей ELF, а также GET DATA FF21 для информации о памяти. Результаты отображаются в обзоре с кнопками Удалить для каждого элемента. - Установка пакета (.cap файл)Отправка .cap файла на карту через сервер: INSTALL[for load] → LOAD ×N → INSTALL[for install (+make selectable)]. Load-файл делится на LOAD APDU размера размер блока LOAD (1–240 байт полезной нагрузки, по умолчанию 240); каждый защищённый пакет доставляется одним SMS или, если он больше, конкатенированной SMS-PP загрузкой до 5 сегментов, так что большой .cap просто занимает несколько SMS. Сразу после выбора файл проверяется и в форме показывается оценка требований к памяти: требование NVRAM (образ кода + постоянные данные, сумма в стиле C6+C8 из GP Card Spec) и оценка RAM. Там же показаны библиотеки, с которыми слинкован CAP (его компонент Import, в виде имя ≥ версия — имена стандартных библиотек подставляются, а где известно, даётся подсказка о версии Java Card), идентификаторы пакета и апплетов и разбивка по компонентам (размеры и доли в порядке load-файла) — всё сгруппировано по разделам Package, Requires, Memory и Components. Повреждённый файл не проходит анализ, и Execute остаётся недоступной до успешного анализа. + Установка пакета (.cap файл)Отправка .cap файла на карту через сервер: INSTALL[for load] → LOAD ×N → INSTALL[for install (+make selectable)]. Load-файл делится на LOAD APDU размера размер блока LOAD (1–240 байт полезной нагрузки, по умолчанию 240); каждый защищённый пакет доставляется одним SMS или, если он больше, конкатенированной SMS-PP загрузкой до 5 сегментов, так что большой .cap просто занимает несколько SMS. Сразу после выбора файл проверяется и в форме показывается оценка требований к памяти: требование NVRAM (образ кода + постоянные данные, сумма в стиле C6+C8 из GP Card Spec) и оценка RAM. Там же показаны библиотеки, с которыми слинкован CAP (его компонент Import: имя библиотеки, AID и минимальная версия ≥ x.y — имена стандартных библиотек и семейства подставляются, а где известно, даётся подсказка о версии Java Card), идентификаторы пакета и апплетов и разбивка по компонентам (размеры и доли в порядке load-файла) — всё сгруппировано по разделам Package, Requires, Memory и Components. Повреждённый файл не проходит анализ, и Execute остаётся недоступной до успешного анализа. diff --git a/frontend/help.html b/frontend/help.html index add1da8..ecb55e4 100644 --- a/frontend/help.html +++ b/frontend/help.html @@ -318,7 +318,7 @@ OperationDescription Explore Card (all GP data)Queries GET STATUS for ISD, Applications, ELFs, and ELF Modules, plus GET DATA FF21 for memory info. Results appear in an explorer view with per-item Delete buttons. - Install Package (.cap file)Sends a .cap file to the card via the server: INSTALL[for load] → LOAD ×N → INSTALL[for install (+make selectable)]. The load file is split into LOAD APDUs of the LOAD block size (1–240 bytes of payload, 240 by default); each secured packet is delivered as a single SMS or, when larger, as a concatenated SMS-PP download of up to 5 segments, so a large .cap simply takes several SMS. As soon as the file is selected it is validated and its memory requirements are estimated in the form: the NVRAM requirement (the code image + persistent data, the GlobalPlatform Card Spec C6+C8 style total) and the RAM estimate. The same box reports the libraries the CAP is linked against (its Import component, shown as name ≥ version with standard library names resolved and a Java Card SDK hint where known), the package/applet identity and the component breakdown (sizes and shares in load-file order) — grouped under the Package, Requires, Memory and Components headings. A corrupt or wrong-format file fails the analysis, and Execute stays disabled until a successful analysis. + Install Package (.cap file)Sends a .cap file to the card via the server: INSTALL[for load] → LOAD ×N → INSTALL[for install (+make selectable)]. The load file is split into LOAD APDUs of the LOAD block size (1–240 bytes of payload, 240 by default); each secured packet is delivered as a single SMS or, when larger, as a concatenated SMS-PP download of up to 5 segments, so a large .cap simply takes several SMS. As soon as the file is selected it is validated and its memory requirements are estimated in the form: the NVRAM requirement (the code image + persistent data, the GlobalPlatform Card Spec C6+C8 style total) and the RAM estimate. The same box reports the libraries the CAP is linked against (its Import component: library name, AID and the minimum version ≥ x.y, with standard names and families resolved and a Java Card SDK hint where known), the package/applet identity and the component breakdown (sizes and shares in load-file order) — grouped under the Package, Requires, Memory and Components headings. A corrupt or wrong-format file fails the analysis, and Execute stays disabled until a successful analysis. diff --git a/frontend/index.html b/frontend/index.html index 6f85d8d..ed32b10 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1616,7 +1616,7 @@ // ===== Version ===== // Single source of truth for the PWA version: shown in the header and used // by the server version check in pysimConnect(). -const SIMPLE_VERSION = '3.5.17'; +const SIMPLE_VERSION = '3.5.18'; document.getElementById('app-version').textContent = 'v' + SIMPLE_VERSION; // ===== Tab switching ===== @@ -8083,12 +8083,15 @@ function capMemHtml(mem) { // ">=" requirements: same major, minor >= the export version (4.5.2); // refs = distinct constant-pool references to the package (6.7) ── if (imports.length) { - let reqRows = row(head('', 'text-left') + head(esc(t('Version')), 'pl-4 text-right whitespace-nowrap') + + let reqRows = row(head('', 'text-left') + head(esc(t('AID')), 'pl-4 text-left') + + head(esc(t('Version')), 'pl-4 text-right whitespace-nowrap') + head(esc(t('Family')), 'pl-4 text-left') + head(esc(t('Refs')), 'pl-4 text-right whitespace-nowrap')); imports.forEach(im => { const name = jcAidName(im.aid); const fam = jcAidFamily(im.aid); - reqRows += row(cell(name ? esc(name) : '' + esc(im.aid) + '', 'whitespace-nowrap') + + // unresolved names show a dash: the AID column carries the identifier + reqRows += row(cell(name ? esc(name) : '\u2014', 'whitespace-nowrap') + + cell(esc(im.aid), 'pl-4 font-mono break-all') + num('\u2265 ' + (Number(im.major) || 0) + '.' + (Number(im.minor) || 0)) + part(esc(fam)) + num(String(Number(im.refs) || 0))); }); @@ -16180,6 +16183,7 @@ const LANG_RU = { 'Compiled': 'Собрано', 'Requires': 'Требуются', 'Family': 'Семейство', + 'AID': 'AID', 'Refs': 'Ссылки', 'NVRAM requirement': 'Требование NVRAM', 'code image (load file)': 'образ кода (load-файл)', diff --git a/frontend/sw.js b/frontend/sw.js index 7ca1e35..883ed0d 100644 --- a/frontend/sw.js +++ b/frontend/sw.js @@ -1,4 +1,4 @@ -const CACHE = 'simple-v270'; +const CACHE = 'simple-v271'; const URLS = [ 'index.html', 'help.html', diff --git a/frontend/tests/capmem.test.js b/frontend/tests/capmem.test.js index aa8b01c..684d5d7 100644 --- a/frontend/tests/capmem.test.js +++ b/frontend/tests/capmem.test.js @@ -106,15 +106,14 @@ test('capMemHtml renders the grouped report: package, requires, memory, componen assert.ok(out.includes('>24 B'), out); assert.ok(out.includes('peak method frame 8 B'), out); assert.ok(out.includes('C6=3000 C7=0x0110 C8=0x0088'), out); - // requires: library name, version, family and refs; the AID is not - // repeated when the name resolves (it adds nothing), and the section - // carries no package AIDs - assert.ok(out.includes('>javacard.framework'), out); - assert.ok(out.includes('>\u2265 1.0'), out); - assert.ok(out.includes('>Oracle JavaCard API'), out); - assert.ok(out.includes('>6'), out); + // requires: library name, AID, minimum version, family and refs const req = out.slice(out.indexOf('Requires (1)'), out.indexOf('Memory')); - assert.ok(!req.includes('A0000000620101'), req); + assert.ok(req.includes('>AID'), req); + assert.ok(req.includes('>javacard.framework'), req); + assert.ok(req.includes('>A0000000620101'), req); + assert.ok(req.includes('>\u2265 1.0'), req); + assert.ok(req.includes('>Oracle JavaCard API'), req); + assert.ok(req.includes('>6'), req); // package identity + compiled-against hint derived from the framework version assert.ok(out.includes('A0000000620101') && out.includes('>v1.0'), out); assert.ok(out.includes('applet package'), out); @@ -143,12 +142,13 @@ test('capMemHtml skips the import section on a response without imports', () => assert.ok(out.includes('>2.1 kB'), out); }); -test('capMemHtml keeps unknown import AIDs bare and labels the family only when known', () => { +test('capMemHtml shows a dash for an unresolved import name (the AID column carries it)', () => { const mem = memFixture(); mem.imports = [{ aid: 'A1130001180001', minor: 0, major: 1, refs: 2 }]; const out = capMemHtml(mem); const req = out.slice(out.indexOf('Requires (1)'), out.indexOf('Memory')); - assert.ok(req.includes('A1130001180001'), req); // unknown AID: shown as the name + assert.ok(req.includes('>\u2014'), req); // no resolved name: a dash + assert.ok(req.includes('>A1130001180001'), req); // the AID column carries it assert.ok(req.includes('>\u2265 1.0'), req); assert.ok(req.includes('>2'), req); // refs assert.ok(!out.includes('Java Card'), out); // no framework import diff --git a/pyproject.toml b/pyproject.toml index 83b25e7..00ecb0e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "pysim-simple-server" -version = "3.5.17" +version = "3.5.18" description = "HTTP REST server wrapping pysim for the SIMple PWA" requires-python = ">=3.8" # pysim is a git-only dependency installed explicitly by setup.bat/setup.sh. diff --git a/pysim_simple_server/server.py b/pysim_simple_server/server.py index c9a0250..b70fa3e 100644 --- a/pysim_simple_server/server.py +++ b/pysim_simple_server/server.py @@ -31,7 +31,7 @@ from osmocom.tlv import BER_TLV_IE from osmocom.utils import rpad -VERSION = '3.5.17' +VERSION = '3.5.18' MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE