Skip to content

asn1rt: fix PER encode/decode of permitted-alphabet constraint on non-known-multiplier char strings - #107

Merged
mitshell merged 1 commit into
pycrate-org:masterfrom
Yuren0312:fix-issue-104
Oct 10, 2026
Merged

mitshell merged 1 commit into
pycrate-org:masterfrom
Yuren0312:fix-issue-104

Conversation

@Yuren0312

Copy link
Copy Markdown
Contributor

Fixes #104.

Problem

For character string types that are not known-multiplier types (UTF8String, GeneralString, GraphicString, TeletexString/T61String, VideotexString), a permitted-alphabet (FROM) constraint is not PER-visible (ITU-T X.691 30.6). Such a value must be encoded as an unconstrained length in octets followed by the octets, exactly as if the constraint were absent.

pycrate applied the alphabet anyway: _get_char_dyn() returned the alphabet's bit width (self._const_alpha.rdyn) even though _clen is None for these types, so __to_per_val() and _from_per() evaluated cdyn < self._clen against None and raised TypeError: '<' not supported between instances of 'int' and 'NoneType'. A valid value could neither be encoded nor decoded, in UPER or APER.

Fix

Ignore the alphabet constraint in _get_char_dyn() when _clen is None (i.e. for non-known-multiplier types), so the value is encoded as raw octets with an unconstrained length, matching the spec and the behaviour of the same type without a constraint:/n/n```diff
def _get_char_dyn(self):
# returns the number of bits required to encode a character

  •    if self._const_alpha:/n+        if self._const_alpha and self._clen is not None:/n```
    

Verification

Added regression types U8s04 ::= UTF8String (FROM ("013")), Ges01 ::= GeneralString (FROM ("013")) and Tes01 ::= TeletexString (FROM ("013")) to test/res/test_asn1rt_mod.asn, plus encode/decode assertions in test_asn1rt.py. All three now round-trip "13" as 023133 (one length octet 02 + octets 31 33), identical to an unconstrained UTF8String.

test/test_asn1rt.py runs green end-to-end (test_rt_base, test_rrc3g, test_lteran, test_nrran, test_tcap_map, test_tcap_cap, test_x509).

Related: #42 fixed the SIZE half of the same X.691 30.6 rule for UTF8String; this covers the remaining permitted-alphabet case.

…-known-multiplier char strings

For character string types that are not known-multiplier types (UTF8String,
GeneralString, TeletexString, ...), a permitted-alphabet constraint is not
PER-visible (ITU-T X.691 30.6): the value is encoded as an unconstrained
length in octets followed by the octets, as if the constraint were absent.

_get_char_dyn() however returned the alphabet's bit width (rdyn) even though
_clen is None for these types, so __to_per_val() and _from_per() evaluated
'cdyn < self._clen' against None and raised TypeError. Ignore the alphabet
constraint when _clen is None.

Fixes pycrate-org#104
@mitshell
mitshell merged commit e372226 into pycrate-org:master Oct 10, 2026
13 checks passed
@mitshell

Copy link
Copy Markdown
Member

Thanks for the fix and the PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PER: a FROM constraint on UTF8String (or another non-known-multiplier string) raises TypeError on encode and decode

2 participants