v3.25.5: the PLI dictionary override guard fix

The live report: POST /api/pli-dict did not change the dictionary.
_PLI_DATA held a '' placeholder for every qualifier, and the clear
branch's pop removed the placeholder even when there was no override.
The PWA's Save posts every field, so one Save wiped the placeholders;
the guard `if code in _PLI_DATA` then silently skipped every later
override for those qualifiers (HTTP 200 + the unchanged/default dict)
until a restart - and the next Save wiped them again.

_PLI_DATA is now overrides-only ({}; the GET and _pli_data_hex already
fall back to PLI_DEFAULTS) and the guard tests PLI_QUALIFIER_NAMES, so a
new override always sticks and a clear never poisons a later set.

Tests: the endpoint test now saves/restores the dict (its pop(0x01)
cleanup was the same trap) plus a regression - the PWA-style full-dict
POST, then new overrides with and without defaults must stick, a clear
restores the default and a later set still works, an unknown qualifier
is ignored.  886 frontend + 874 Python; sw cache simple-v429.
This commit is contained in:
2026-10-11 16:34:08 +03:00
parent 2a58cfb235
commit f2046d7f0a
5 changed files with 55 additions and 7 deletions
+12 -3
View File
@@ -36,7 +36,7 @@ from osmocom.tlv import BER_TLV_IE
from osmocom.utils import rpad
VERSION = '3.25.4'
VERSION = '3.25.5'
MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE
@@ -2669,7 +2669,13 @@ PLI_DEFAULTS = {
0x0E: '3F02' + '0308',
}
_PLI_DATA = {q: '' for q in PLI_QUALIFIER_NAMES} # the operator overrides
# The operator's overrides only, keyed by qualifier code - the built-in
# PLI_DEFAULTS above are the base layer and stay the fallback; a field cleared
# through /api/pli-dict removes its entry (v3.25.5). Keeping this dict free
# of placeholder keys is deliberate: the POST's guard tests the known
# qualifiers, never "an override already exists" (a full-dict Save posts every
# field - an empty one must not make later overrides no-ops).
_PLI_DATA = {}
_BIP = httpota.BipTerminal()
# Active BIP session, shared by the SCP81 listener and the Simulator's
@@ -9102,7 +9108,10 @@ class PysimHandler(BaseHTTPRequestHandler):
if isinstance(v, str):
try:
code = int(k, 16)
if code in _PLI_DATA:
# a known qualifier - never "an override already
# exists": a new override must stick, and a clear
# must not poison a later set (v3.25.5, live report)
if code in PLI_QUALIFIER_NAMES:
if v:
bytes.fromhex(v) # valid hex only
_PLI_DATA[code] = v