X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=pyderasn.py;h=5f0c0343ccd0d4153d29e6328fde4a73882229ec;hb=ac86b0fe801de06f9b861579e5d566d3cdb3236b;hp=32d942460436403c3bde2725f92aa370e63e715f;hpb=0265e9da3f3d6a84b79a231a7af0f694c7c96538;p=pyderasn.git diff --git a/pyderasn.py b/pyderasn.py index 32d9424..5f0c034 100755 --- a/pyderasn.py +++ b/pyderasn.py @@ -634,6 +634,7 @@ Various .. autoclass:: pyderasn.DecodeError :members: __init__ .. autoclass:: pyderasn.NotEnoughData +.. autoclass:: pyderasn.ExceedingData .. autoclass:: pyderasn.LenIndefForm .. autoclass:: pyderasn.TagMismatch .. autoclass:: pyderasn.InvalidLength @@ -677,7 +678,7 @@ except ImportError: # pragma: no cover def colored(what, *args, **kwargs): return what -__version__ = "5.5" +__version__ = "5.6" __all__ = ( "Any", @@ -689,6 +690,7 @@ __all__ = ( "DecodeError", "DecodePathDefBy", "Enumerated", + "ExceedingData", "GeneralizedTime", "GeneralString", "GraphicString", @@ -799,6 +801,18 @@ class NotEnoughData(DecodeError): pass +class ExceedingData(ASN1Error): + def __init__(self, nbytes): + super(ExceedingData, self).__init__() + self.nbytes = nbytes + + def __str__(self): + return "%d trailing bytes" % self.nbytes + + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, self) + + class LenIndefForm(DecodeError): pass @@ -1264,6 +1278,26 @@ class Obj(object): ) return obj, (tail if leavemm else tail.tobytes()) + def decod(self, data, offset=0, decode_path=(), ctx=None): + """Decode the data, check that tail is empty + + :raises ExceedingData: if tail is not empty + + This is just a wrapper over :py:meth:`pyderasn.Obj.decode` + (decode without tail) that also checks that there is no + trailing data left. + """ + obj, tail = self.decode( + data, + offset=offset, + decode_path=decode_path, + ctx=ctx, + leavemm=True, + ) + if len(tail) > 0: + raise ExceedingData(len(tail)) + return obj + @property def expled(self): """See :ref:`decoding` @@ -2310,7 +2344,7 @@ class BitString(Obj): if not frozenset(value) <= SET01: raise ValueError("B's coding contains unacceptable chars") return self._bits2octets(value) - elif value.endswith("'H"): + if value.endswith("'H"): value = value[1:-2] return ( len(value) * 4, @@ -2318,8 +2352,7 @@ class BitString(Obj): ) if isinstance(value, binary_type): return (len(value) * 8, value) - else: - raise InvalidValueType((self.__class__, string_types, binary_type)) + raise InvalidValueType((self.__class__, string_types, binary_type)) if isinstance(value, tuple): if ( len(value) == 2 and @@ -2438,7 +2471,7 @@ class BitString(Obj): octets, )) - def _decode_chunk(self, lv, offset, decode_path, ctx): + def _decode_chunk(self, lv, offset, decode_path): try: l, llen, v = len_decode(lv) except DecodeError as err: @@ -2509,7 +2542,7 @@ class BitString(Obj): if t == self.tag: if tag_only: # pragma: no cover return None - return self._decode_chunk(lv, offset, decode_path, ctx) + return self._decode_chunk(lv, offset, decode_path) if t == self.tag_constructed: if not ctx.get("bered", False): raise DecodeError( @@ -2828,7 +2861,7 @@ class OctetString(Obj): self._value, )) - def _decode_chunk(self, lv, offset, decode_path, ctx): + def _decode_chunk(self, lv, offset, decode_path): try: l, llen, v = len_decode(lv) except DecodeError as err: @@ -2885,7 +2918,7 @@ class OctetString(Obj): if t == self.tag: if tag_only: return None - return self._decode_chunk(lv, offset, decode_path, ctx) + return self._decode_chunk(lv, offset, decode_path) if t == self.tag_constructed: if not ctx.get("bered", False): raise DecodeError( @@ -4753,9 +4786,8 @@ class Sequence(Obj): if spec.optional: continue return False - else: - if not value.ready: - return False + if not value.ready: + return False return True @property @@ -5754,7 +5786,7 @@ def main(): # pragma: no cover print(pprinter( obj, oid_maps=oid_maps, - with_colours=True if environ.get("NO_COLOR") is None else False, + with_colours=environ.get("NO_COLOR") is None, with_decode_path=args.print_decode_path, decode_path_only=( () if args.decode_path_only is None else