X-Git-Url: http://www.git.cypherpunks.ru/?p=pyderasn.git;a=blobdiff_plain;f=pyderasn.py;h=a7732964dedcc8befbd31da6f4778cfb1cb23dc6;hp=7edfc8064c2c0571404e2449a7906ea745ffd264;hb=2dc06a21fd4bd1e52bbea125ef744d58fc0d17bf;hpb=cb9ebe2012c619dea2633b00427898312801a840 diff --git a/pyderasn.py b/pyderasn.py index 7edfc80..a773296 100755 --- a/pyderasn.py +++ b/pyderasn.py @@ -213,10 +213,10 @@ decoding process. Currently available context options: +* :ref:`allow_default_values ` * :ref:`allow_expl_oob ` * :ref:`bered ` * :ref:`defines_by_path ` -* :ref:`strict_default_existence ` .. _pprinting: @@ -383,7 +383,7 @@ constructed primitive types should be parsed successfully. * If object is encoded in BER form (not the DER one), then ``bered`` attribute is set to True. Only ``BOOLEAN``, ``BIT STRING``, ``OCTET - STRING`` can contain it. + STRING``, ``SEQUENCE``, ``SET`` can contain it. * If object has an indefinite length encoding, then its ``lenindef`` attribute is set to True. Only ``BIT STRING``, ``OCTET STRING``, ``SEQUENCE``, ``SET``, ``SEQUENCE OF``, ``SET OF``, ``ANY`` can @@ -4338,18 +4338,14 @@ class Sequence(Obj): All defaulted values are always optional. - .. _strict_default_existence_ctx: + .. _allow_default_values_ctx: - .. warning:: - - When decoded DER contains defaulted value inside, then - technically this is not valid DER encoding. But we allow and pass - it **by default**. Of course reencoding of that kind of DER will - result in different binary representation (validly without - defaulted value inside). You can enable strict defaulted values - existence validation by setting ``"strict_default_existence": - True`` :ref:`context ` option -- decoding process will raise - an exception if defaulted value is met. + DER prohibits default value encoding and will raise an error if + default value is unexpectedly met during decode. + If :ref:`bered ` context option is set, then no error + will be raised, but ``bered`` attribute set. You can disable strict + defaulted values existence validation by setting + ``"allow_default_values": True`` :ref:`context ` option. Two sequences are equal if they have equal specification (schema), implicit/explicit tagging and the same values. @@ -4509,10 +4505,11 @@ class Sequence(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__, @@ -4540,6 +4537,8 @@ class Sequence(Obj): vlen = 0 sub_offset = offset + tlen + llen values = {} + bered = False + ctx_allow_default_values = ctx.get("allow_default_values", False) for name, spec in self.specs.items(): if spec.optional and ( (lenindef and v[:EOC_LEN].tobytes() == EOC) or @@ -4612,15 +4611,15 @@ class Sequence(Obj): sub_offset += value_len v = v_tail if spec.default is not None and value == spec.default: - if ctx.get("strict_default_existence", False): + if ctx_bered or ctx_allow_default_values: + bered = True + else: raise DecodeError( "DEFAULT value met", klass=self.__class__, decode_path=sub_decode_path, offset=sub_offset, ) - else: - continue values[name] = value spec_defines = getattr(spec, "defines", ()) @@ -4663,6 +4662,7 @@ class Sequence(Obj): ) obj._value = values obj.lenindef = lenindef + obj.bered = bered return obj, tail def __repr__(self): @@ -4738,10 +4738,11 @@ class Set(Sequence): 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__, @@ -4768,6 +4769,8 @@ class Set(Sequence): vlen = 0 sub_offset = offset + tlen + llen values = {} + bered = False + ctx_allow_default_values = ctx.get("allow_default_values", False) specs_items = self.specs.items while len(v) > 0: if lenindef and v[:EOC_LEN].tobytes() == EOC: @@ -4803,18 +4806,18 @@ class Set(Sequence): sub_offset += value_len vlen += value_len v = v_tail - if spec.default is None: - values[name] = value + if spec.default is None or value != spec.default: + pass + elif ctx_bered or ctx_allow_default_values: + bered = True else: - if value != spec.default: - values[name] = value - if ctx.get("strict_default_existence", False): - raise DecodeError( - "DEFAULT value met", - klass=self.__class__, - decode_path=sub_decode_path, - offset=sub_offset, - ) + raise DecodeError( + "DEFAULT value met", + klass=self.__class__, + decode_path=sub_decode_path, + offset=sub_offset, + ) + values[name] = value obj = self.__class__( schema=self.specs, impl=self.tag, @@ -4824,6 +4827,7 @@ class Set(Sequence): _decoded=(offset, llen, vlen + (EOC_LEN if lenindef else 0)), ) obj._value = values + obj.bered = bered if lenindef: if v[:EOC_LEN].tobytes() != EOC: raise DecodeError(