X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=pyderasn.py;h=162c1404a3af15ddbae345c63d391f8d34fb45e2;hb=498f47100e12f1bef247b29460ac4621fa0fc9f9;hp=62e884ba9357bfc49f21f77c19c7cd90fe21f954;hpb=f71a94a5977de93d84b6f00a92a8be6c72f9a50b;p=pyderasn.git diff --git a/pyderasn.py b/pyderasn.py index 62e884b..162c140 100755 --- a/pyderasn.py +++ b/pyderasn.py @@ -665,6 +665,11 @@ parse the CRL above with fully assembled ``RevokedCertificate``:: ): print("serial number:", int(obj["userCertificate"])) +.. note:: + + SEQUENCE/SET values with DEFAULT specified are automatically decoded + without evgen mode. + .. _mmap: mmap-ed file @@ -912,7 +917,7 @@ _______ Integer _______ .. autoclass:: pyderasn.Integer - :members: __init__, named + :members: __init__, named, tohex BitString _________ @@ -1180,7 +1185,7 @@ except ImportError: # pragma: no cover def colored(what, *args, **kwargs): return what -__version__ = "7.2" +__version__ = "7.4" __all__ = ( "agg_octet_string", @@ -1190,6 +1195,7 @@ __all__ = ( "Boolean", "BoundsError", "Choice", + "colonize_hex", "DecodeError", "DecodePathDefBy", "encode2pass", @@ -2372,13 +2378,8 @@ def pp_console_row( cols.append(_colourize("(%s)" % oid_name, "green", with_colours)) break if pp.asn1_type_name == Integer.asn1_type_name: - hex_repr = hex(int(pp.obj._value))[2:].upper() - if len(hex_repr) % 2 != 0: - hex_repr = "0" + hex_repr cols.append(_colourize( - "(%s)" % colonize_hex(hex_repr), - "green", - with_colours, + "(%s)" % colonize_hex(pp.obj.tohex()), "green", with_colours, )) if with_blob: if pp.blob.__class__ == binary_type: @@ -2845,6 +2846,16 @@ class Integer(Obj): self._assert_ready() return int(self._value) + def tohex(self): + """Hexadecimal representation + + Use :py:func:`pyderasn.colonize_hex` for colonizing it. + """ + hex_repr = hex(int(self))[2:].upper() + if len(hex_repr) % 2 != 0: + hex_repr = "0" + hex_repr + return hex_repr + def __hash__(self): self._assert_ready() return hash(b"".join(( @@ -2936,7 +2947,6 @@ class Integer(Obj): else: break return octets - return b"".join((self.tag, len_encode(len(octets)), octets)) def _encode(self): octets = self._encode_payload() @@ -6195,11 +6205,10 @@ class Sequence(SequenceEncode1stMixing, Obj): defaulted values existence validation by setting ``"allow_default_values": True`` :ref:`context ` option. - .. warning:: - - Check for default value existence is not performed in - ``evgen_mode``, because previously decoded values are not stored - in memory, to be able to compare them. + All values with DEFAULT specified are decoded atomically in + :ref:`evgen mode `. If DEFAULT value is some kind of + SEQUENCE, then it will be yielded as a single element, not + disassembled. That is required for DEFAULT existence check. Two sequences are equal if they have equal specification (schema), implicit/explicit tagging and the same values. @@ -6425,9 +6434,10 @@ class Sequence(SequenceEncode1stMixing, Obj): len(v) == 0 ): continue + spec_defaulted = spec.default is not None sub_decode_path = decode_path + (name,) try: - if evgen_mode: + if evgen_mode and not spec_defaulted: for _decode_path, value, v_tail in spec.decode_evgen( v, sub_offset, @@ -6505,9 +6515,10 @@ class Sequence(SequenceEncode1stMixing, Obj): vlen += value_len sub_offset += value_len v = v_tail - if not evgen_mode: - if spec.default is not None and value == spec.default: - # This will not work in evgen_mode + if spec_defaulted: + if evgen_mode: + yield sub_decode_path, value, v_tail + if value == spec.default: if ctx_bered or ctx_allow_default_values: ber_encoded = True else: @@ -6517,6 +6528,7 @@ class Sequence(SequenceEncode1stMixing, Obj): decode_path=sub_decode_path, offset=sub_offset, ) + if not evgen_mode: values[name] = value spec_defines = getattr(spec, "defines", ()) if len(spec_defines) == 0: @@ -6716,7 +6728,8 @@ class Set(Sequence, SequenceEncode1stMixing): decode_path=decode_path, offset=offset, ) - if evgen_mode: + spec_defaulted = spec.default is not None + if evgen_mode and not spec_defaulted: for _decode_path, value, v_tail in spec.decode_evgen( v, sub_offset, @@ -6748,17 +6761,20 @@ class Set(Sequence, SequenceEncode1stMixing): decode_path=sub_decode_path, offset=sub_offset, ) - if spec.default is None or value != spec.default: - pass - elif ctx_bered or ctx_allow_default_values: - ber_encoded = True - else: - raise DecodeError( - "DEFAULT value met", - klass=self.__class__, - decode_path=sub_decode_path, - offset=sub_offset, - ) + if spec_defaulted: + if evgen_mode: + yield sub_decode_path, value, v_tail + if value != spec.default: + pass + elif ctx_bered or ctx_allow_default_values: + ber_encoded = True + else: + raise DecodeError( + "DEFAULT value met", + klass=self.__class__, + decode_path=sub_decode_path, + offset=sub_offset, + ) values[name] = value del _specs_items[name] tag_order_prev = value_tag_order @@ -7483,4 +7499,5 @@ def main(): # pragma: no cover if __name__ == "__main__": + from pyderasn import * main()