From 6cf265508b94ee8cae17d793f8971437da3e63b7 Mon Sep 17 00:00:00 2001 From: TheeCoderAhmed Date: Thu, 29 Oct 2026 04:57:16 +0300 Subject: [PATCH] asn1rt: fix ASN1Set.intersect() is_ext() tested _er, which is an empty list (not None) for a non-extensible set, so intersect() treated every set as extensible and then iterated _ev, which is None. For extensible sets, intersect() called _init() without its two arguments, and step 4.3 copied root ranges (from .root) into the extension values, which _init() then could not sort against integers. Test _ev in is_ext(), pass sort_root and sort_ext to _init(), and only copy individual root values in step 4.3, since the root ranges are already merged into the extension ranges in step 4.1. Fixes #214 --- pycrate_asn1rt/setobj.py | 9 +++++---- test/test_asn1rt.py | 18 ++++++++++++++++++ test/test_pycrate.py | 1 + 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/pycrate_asn1rt/setobj.py b/pycrate_asn1rt/setobj.py index fcb33e03..b3f3eabf 100644 --- a/pycrate_asn1rt/setobj.py +++ b/pycrate_asn1rt/setobj.py @@ -851,7 +851,7 @@ def is_empty(self): return self._rv == [] and self._rr == [] def is_ext(self): - return self._er is not None + return self._ev is not None def __contains__(self, v): if self._CONTAIN_WEXT: @@ -928,13 +928,14 @@ def intersect(self, S): if not ret.in_root(v) and not ret.in_ext(v): ret._ev.append(v) # 4.3) add self and S root values not intersecting - for v in self.root: + # (root ranges are already part of ret._er, from 4.1) + for v in self._rv: if not ret.in_root(v) and not ret.in_ext(v): ret._ev.append(v) - for v in S.root: + for v in S._rv: if not ret.in_root(v) and not ret.in_ext(v): ret._ev.append(v) - ret._init() + ret._init(True, True) return ret def get_root_dyn(self): diff --git a/test/test_asn1rt.py b/test/test_asn1rt.py index 9680d404..e556c5d6 100644 --- a/test/test_asn1rt.py +++ b/test/test_asn1rt.py @@ -2157,6 +2157,24 @@ def _test_rt_base(): return 0 +def test_setobj_intersect(): + # integer root ranges, for non-extensible and extensible sets + for ev in (None, []): + left = ASN1Set(rr=[ASN1RangeInt(0, 10)], ev=ev) + right = ASN1Set(rr=[ASN1RangeInt(5, 15)], ev=ev) + inter = left.intersect(right) + assert( [(r.lb, r.ub) for r in inter._rr] == [(5, 10)] ) + assert( inter.in_root(5) and inter.in_root(10) ) + assert( not inter.in_root(4) and not inter.in_root(11) ) + assert( inter.is_ext() == (ev is not None) ) + # individual root values outside the intersection go to the extension + left = ASN1Set(rv=[20], rr=[ASN1RangeInt(0, 10)], ev=[]) + right = ASN1Set(rr=[ASN1RangeInt(5, 15)], ev=[]) + inter = left.intersect(right) + assert( inter.in_root(7) and not inter.in_root(20) ) + assert( inter.in_ext(20) ) + return 0 + def test_rt_base(): _load_rt_base() _test_rt_base() diff --git a/test/test_pycrate.py b/test/test_pycrate.py index 1fd222b0..10b44b24 100644 --- a/test/test_pycrate.py +++ b/test/test_pycrate.py @@ -237,6 +237,7 @@ def test_asn1c_to_asn1(self): # asn1rt def test_asn1rt(self): print('[<>] testing pycrate_asn1rt') + test_setobj_intersect() test_rt_base() test_rrc3g() test_lteran()