Spec-truth pass: decodeTextData disambiguation, privilege tables per GPC v2.3

decodeTextData: legacy no-DCS UCS2 text whose first byte is 00/04 was
misrouted into DCS-aware branches (e.g. 'HI' = 00480049 decoded as GSM7
garbage). Now: dcs=08 strict (fail = '?', no reinterpretation); ambiguous
lead byte 00/04 prefers whole-buffer UCS2 when >=8 hex chars, %4==0,
printable, uniform high bytes; else DCS-aware path; legacy fallback kept.

Privileges per GPC v2.3 Tables 11-7/11-8/11-9 (verified against PDF):
- decodePrivileges rewritten table-driven; fixes wrong byte-2 mapping
  (was: Global Lock/Final Application/Receipt Generation on wrong bits)
  and byte-1 Card Terminate/Card Reset swap
- Reverted 'Token Management' rename: spec uses 'Token Verification'
  (66x vs single Table 11-8 outlier); checkbox + parser restored
- PLAY TONE qualifiers aligned to TS 102 223 §8.6 exact wording

Registry docs/uicc/UICC_SPECS.md corrected from primary sources:
- SET STATUS P1: '20' app/suppl SD -> '40' (GPC Table 11-86)
- SELECT P2 response field is b4b3 ('01' FCP / '11' none), not b3b2b1
  (TS 102 221 Table 11.2)
This commit is contained in:
2026-08-22 08:14:06 +03:00
parent 0fd91d7771
commit 7870682f3d
2 changed files with 68 additions and 31 deletions
+28
View File
@@ -170,6 +170,34 @@ test('gsm7Decode unpacks "HI" from C824', () => {
assert.strictEqual(gsm7Decode(bytes), 'HI');
});
test('decodeTextData legacy UCS2 without DCS (regression: lead 00 is not a DCS)', () => {
assert.strictEqual(decodeTextData('00480049'), 'HI');
});
test('decodeTextData legacy Cyrillic UCS2 (uniform 04 high bytes)', () => {
assert.strictEqual(decodeTextData('041f04400438043204350442'), 'Привет');
});
test('decodeTextData DCS-prefixed UCS2 (08)', () => {
assert.strictEqual(decodeTextData('0800480049'), 'HI');
});
test('decodeTextData DCS-prefixed GSM7 packed (00)', () => {
assert.strictEqual(decodeTextData('00C824'), 'HI');
});
test('decodeTextData DCS-prefixed unpacked 8-bit (04)', () => {
assert.strictEqual(decodeTextData('04414243'), 'ABC');
});
test('decodeTextData explicit DCS 08 with malformed payload returns ?', () => {
assert.strictEqual(decodeTextData('0841'), '?');
});
test('decodePrivileges byte 2 b6 is Token Verification per GPC v2.3 Table 11-8', () => {
assert.ok(decodePrivileges('0020').includes('Token Verification'));
});
test('decodePrivileges', () => {
assert.ok(decodePrivileges('00').includes('None'));
assert.ok(decodePrivileges('80').includes('Security Domain'));