X-Git-Url: http://www.git.cypherpunks.ru/?p=pyderasn.git;a=blobdiff_plain;f=pyderasn.py;h=df639eb9ffef8ece9ce95660464b91bbddb8b285;hp=3dd3ea9c151a3f1ca6f571a7765614e1c5bf5b91;hb=24bd1587aa3d3ce2723043db8e81c1f56974dc09;hpb=f928d1e65eeff56c2b5d511567e6b52417195f3b diff --git a/pyderasn.py b/pyderasn.py index 3dd3ea9..df639eb 100755 --- a/pyderasn.py +++ b/pyderasn.py @@ -5050,7 +5050,7 @@ class SequenceOf(Obj): v = b"".join(self._encoded_values()) return b"".join((self.tag, len_encode(len(v)), v)) - def _decode(self, tlv, offset, decode_path, ctx, tag_only): + def _decode(self, tlv, offset, decode_path, ctx, tag_only, ordering_check=False): try: t, tlen, lv = tag_strip(tlv) except DecodeError as err: @@ -5069,10 +5069,11 @@ class SequenceOf(Obj): if tag_only: return lenindef = False + ctx_bered = ctx.get("bered", False) try: l, llen, v = len_decode(lv) except LenIndefForm as err: - if not ctx.get("bered", False): + if not ctx_bered: raise err.__class__( msg=err.msg, klass=self.__class__, @@ -5100,22 +5101,38 @@ class SequenceOf(Obj): vlen = 0 sub_offset = offset + tlen + llen _value = [] + ctx_allow_unordered_set = ctx.get("allow_unordered_set", False) + value_prev = memoryview(v[:0]) + bered = False spec = self.spec while len(v) > 0: if lenindef and v[:EOC_LEN].tobytes() == EOC: break + sub_decode_path = decode_path + (str(len(_value)),) value, v_tail = spec.decode( v, sub_offset, leavemm=True, - decode_path=decode_path + (str(len(_value)),), + decode_path=sub_decode_path, ctx=ctx, ) value_len = value.fulllen + if ordering_check: + if value_prev.tobytes() > v[:value_len].tobytes(): + if ctx_bered or ctx_allow_unordered_set: + bered = True + else: + raise DecodeError( + "unordered " + self.asn1_type_name, + klass=self.__class__, + decode_path=sub_decode_path, + offset=sub_offset, + ) + value_prev = v[:value_len] + _value.append(value) sub_offset += value_len vlen += value_len v = v_tail - _value.append(value) try: obj = self.__class__( value=_value, @@ -5144,6 +5161,7 @@ class SequenceOf(Obj): ) obj.lenindef = True tail = v[EOC_LEN:] + obj.bered = bered return obj, tail def __repr__(self): @@ -5193,6 +5211,16 @@ class SetOf(SequenceOf): v = b"".join(raws) return b"".join((self.tag, len_encode(len(v)), v)) + def _decode(self, tlv, offset, decode_path, ctx, tag_only): + return super(SetOf, self)._decode( + tlv, + offset, + decode_path, + ctx, + tag_only, + ordering_check=True, + ) + def obj_by_path(pypath): # pragma: no cover """Import object specified as string Python path