From 3bdec8f765e0fa8ed27162a8c0abe391a44dc664 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Tue, 13 Feb 2018 21:03:42 +0300 Subject: [PATCH 1/1] Colourized output --- VERSION | 2 +- doc/index.rst | 6 ++ doc/install.rst | 10 ++-- doc/news.rst | 9 +++ doc/pprinting.png | Bin 0 -> 50795 bytes pyderasn.py | 130 +++++++++++++++++++++++++++++++---------- tests/test_pyderasn.py | 8 +-- 7 files changed, 123 insertions(+), 42 deletions(-) create mode 100644 doc/pprinting.png diff --git a/VERSION b/VERSION index 879b416..9f55b2c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1 +3.0 diff --git a/doc/index.rst b/doc/index.rst index 2eb228a..0197abd 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -19,6 +19,12 @@ README), it is still often can be seen anywhere in our life. PyDERASN is `free software `__, licenced under `GNU LGPLv3+ `__. +.. figure:: pprinting.png + :alt: Pretty printing example output + + An example of pretty printed X.509 certificate with automatically + parsed DEFINED BY fields. + .. toctree:: :maxdepth: 1 diff --git a/doc/install.rst b/doc/install.rst index d1e1325..e6f6ba1 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -4,11 +4,11 @@ Install Preferable way is to :ref:`download ` tarball with the signature from `official website `__:: - % wget http://pyderasn.cypherpunks.ru/pyderasn-1.0.tar.xz - % wget http://pyderasn.cypherpunks.ru/pyderasn-1.0.tar.xz.sig - % gpg --verify pyderasn-1.0.tar.xz.sig pyderasn-1.0.tar.xz - % xz -d < pyderasn-1.0.tar.xz | tar xf - - % cd pyderasn-1.0 + % wget http://pyderasn.cypherpunks.ru/pyderasn-3.0.tar.xz + % wget http://pyderasn.cypherpunks.ru/pyderasn-3.0.tar.xz.sig + % gpg --verify pyderasn-3.0.tar.xz.sig pyderasn-3.0.tar.xz + % xz -d < pyderasn-3.0.tar.xz | tar xf - + % cd pyderasn-3.0 % python setup.py install # or copy pyderasn.py (+six.py) to your PYTHONPATH diff --git a/doc/news.rst b/doc/news.rst index e935e0e..ab752f4 100644 --- a/doc/news.rst +++ b/doc/news.rst @@ -1,6 +1,15 @@ News ==== +.. _release3.0: + +3.0 +--- +* :py:func:`pyderasn.decode_path_defby` is replaced with + :py:class:`pyderasn.DecodePathDefBy` +* Ability to turn colourized terminal output by calling + ``pprint(..., with_colours=True)`` + .. _release2.1: 2.1 diff --git a/doc/pprinting.png b/doc/pprinting.png new file mode 100644 index 0000000000000000000000000000000000000000..8f74110e6715c2bccc18540e0979519f8ead1327 GIT binary patch literal 50795 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 z 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
@^2}rsafNs#_hM%v*ry_ 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 literal 0 HcmV?d00001 diff --git a/pyderasn.py b/pyderasn.py index cd96a33..e69b190 100755 --- a/pyderasn.py +++ b/pyderasn.py @@ -329,7 +329,7 @@ of ``PKIResponse``:: ( ( "content", - decode_path_defby(id_signedData), + DecodePathDefBy(id_signedData), "encapContentInfo", "eContentType", ), @@ -341,10 +341,10 @@ of ``PKIResponse``:: ( ( "content", - decode_path_defby(id_signedData), + DecodePathDefBy(id_signedData), "encapContentInfo", "eContent", - decode_path_defby(id_cct_PKIResponse), + DecodePathDefBy(id_cct_PKIResponse), "controlSequence", any, "attrType", @@ -358,7 +358,7 @@ of ``PKIResponse``:: ), )) -Pay attention for :py:func:`pyderasn.decode_path_defby` and ``any``. +Pay attention for :py:class:`pyderasn.DecodePathDefBy` and ``any``. First function is useful for path construction when some automatic decoding is already done. ``any`` means literally any value it meet -- useful for SEQUENCE/SET OF-s. @@ -486,6 +486,13 @@ from six import text_type from six.moves import xrange as six_xrange +try: + from termcolor import colored +except ImportError: + def colored(what, *args): + return what + + __all__ = ( "Any", "BitString", @@ -493,8 +500,8 @@ __all__ = ( "Boolean", "BoundsError", "Choice", - "decode_path_defby", "DecodeError", + "DecodePathDefBy", "Enumerated", "GeneralizedTime", "GeneralString", @@ -1001,10 +1008,24 @@ class Obj(object): return self.expl_tlen + self.expl_llen + self.expl_vlen -def decode_path_defby(defined_by): +class DecodePathDefBy(object): """DEFINED BY representation inside decode path """ - return "DEFINED BY (%s)" % defined_by + __slots__ = ('defined_by',) + + def __init__(self, defined_by): + self.defined_by = defined_by + + def __eq__(self, their): + if not isinstance(their, self.__class__): + return False + return self.defined_by == their.defined_by + + def __str__(self): + return "DEFINED BY " + str(self.defined_by) + + def __repr__(self): + return "<%s: %s>" % (self.__class__.__name__, self.defined_by) ######################################################################## @@ -1072,49 +1093,75 @@ def _pp( ) -def pp_console_row(pp, oids=None, with_offsets=False, with_blob=True): +def _colorize(what, colour, with_colours, attrs=("bold",)): + return colored(what, colour, attrs=attrs) if with_colours else what + + +def pp_console_row( + pp, + oids=None, + with_offsets=False, + with_blob=True, + with_colours=False, +): cols = [] if with_offsets: - cols.append("%5d%s [%d,%d,%4d]" % ( + col = "%5d%s" % ( pp.offset, ( " " if pp.expl_offset is None else ("-%d" % (pp.offset - pp.expl_offset)) ), - pp.tlen, - pp.llen, - pp.vlen, - )) + ) + cols.append(_colorize(col, "red", with_colours, ())) + col = "[%d,%d,%4d]" % (pp.tlen, pp.llen, pp.vlen) + cols.append(_colorize(col, "green", with_colours, ())) if len(pp.decode_path) > 0: cols.append(" ." * (len(pp.decode_path))) - cols.append("%s:" % pp.decode_path[-1]) + ent = pp.decode_path[-1] + if isinstance(ent, DecodePathDefBy): + cols.append(_colorize("DEFINED BY", "red", with_colours, ("reverse",))) + value = str(ent.defined_by) + if ( + oids is not None and + ent.defined_by.asn1_type_name == + ObjectIdentifier.asn1_type_name and + value in oids + ): + cols.append(_colorize("%s:" % oids[value], "green", with_colours)) + else: + cols.append(_colorize("%s:" % value, "white", with_colours)) + else: + cols.append(_colorize("%s:" % ent, "yellow", with_colours)) if pp.expl is not None: klass, _, num = pp.expl - cols.append("[%s%d] EXPLICIT" % (TagClassReprs[klass], num)) + col = "[%s%d] EXPLICIT" % (TagClassReprs[klass], num) + cols.append(_colorize(col, "blue", with_colours)) if pp.impl is not None: klass, _, num = pp.impl - cols.append("[%s%d]" % (TagClassReprs[klass], num)) + col = "[%s%d]" % (TagClassReprs[klass], num) + cols.append(_colorize(col, "blue", with_colours)) if pp.asn1_type_name.replace(" ", "") != pp.obj_name.upper(): - cols.append(pp.obj_name) - cols.append(pp.asn1_type_name) + cols.append(_colorize(pp.obj_name, "magenta", with_colours)) + cols.append(_colorize(pp.asn1_type_name, "cyan", with_colours)) if pp.value is not None: value = pp.value + cols.append(_colorize(value, "white", with_colours)) if ( oids is not None and pp.asn1_type_name == ObjectIdentifier.asn1_type_name and value in oids ): - value = "%s (%s)" % (oids[value], pp.value) - cols.append(value) + cols.append(_colorize("(%s)" % oids[value], "green", with_colours)) if with_blob: if isinstance(pp.blob, binary_type): cols.append(hexenc(pp.blob)) elif isinstance(pp.blob, tuple): cols.append(", ".join(pp.blob)) if pp.optional: - cols.append("OPTIONAL") + cols.append(_colorize("OPTIONAL", "red", with_colours)) if pp.default: - cols.append("DEFAULT") + cols.append(_colorize("DEFAULT", "red", with_colours)) return " ".join(cols) @@ -1133,7 +1180,7 @@ def pp_console_blob(pp): yield " ".join(cols + [", ".join(pp.blob)]) -def pprint(obj, oids=None, big_blobs=False): +def pprint(obj, oids=None, big_blobs=False, with_colours=False): """Pretty print object :param Obj obj: object you want to pretty print @@ -1142,6 +1189,8 @@ def pprint(obj, oids=None, big_blobs=False): :param big_blobs: if large binary objects are met (like OctetString values), do we need to print them too, on separate lines + :param with_colours: colourize output, if ``termcolor`` library + is available """ def _pprint_pps(pps): for pp in pps: @@ -1152,11 +1201,18 @@ def pprint(obj, oids=None, big_blobs=False): oids=oids, with_offsets=True, with_blob=False, + with_colours=with_colours, ) for row in pp_console_blob(pp): yield row else: - yield pp_console_row(pp, oids=oids, with_offsets=True) + yield pp_console_row( + pp, + oids=oids, + with_offsets=True, + with_blob=True, + with_colours=with_colours, + ) else: for row in _pprint_pps(pp): yield row @@ -2009,7 +2065,7 @@ class BitString(Obj): defined_by, defined = self.defined or (None, None) if defined_by is not None: yield defined.pps( - decode_path=decode_path + (decode_path_defby(defined_by),) + decode_path=decode_path + (DecodePathDefBy(defined_by),) ) @@ -2233,7 +2289,7 @@ class OctetString(Obj): defined_by, defined = self.defined or (None, None) if defined_by is not None: yield defined.pps( - decode_path=decode_path + (decode_path_defby(defined_by),) + decode_path=decode_path + (DecodePathDefBy(defined_by),) ) @@ -3545,7 +3601,7 @@ class Any(Obj): defined_by, defined = self.defined or (None, None) if defined_by is not None: yield defined.pps( - decode_path=decode_path + (decode_path_defby(defined_by),) + decode_path=decode_path + (DecodePathDefBy(defined_by),) ) @@ -3871,7 +3927,7 @@ class Sequence(Obj): for i, _value in enumerate(value): sub_sub_decode_path = sub_decode_path + ( str(i), - decode_path_defby(defined_by), + DecodePathDefBy(defined_by), ) defined_value, defined_tail = defined_spec.decode( memoryview(bytes(_value)), @@ -3899,14 +3955,14 @@ class Sequence(Obj): if value.expled else (value.tlen + value.llen) ), leavemm=True, - decode_path=sub_decode_path + (decode_path_defby(defined_by),), + decode_path=sub_decode_path + (DecodePathDefBy(defined_by),), ctx=ctx, ) if len(defined_tail) > 0: raise DecodeError( "remaining data", klass=self.__class__, - decode_path=sub_decode_path + (decode_path_defby(defined_by),), + decode_path=sub_decode_path + (DecodePathDefBy(defined_by),), offset=offset, ) value.defined = (defined_by, defined_value) @@ -4397,7 +4453,7 @@ def generic_decoder(): # pragma: no cover __slots__ = () schema = choice - def pprint_any(obj, oids=None): + def pprint_any(obj, oids=None, with_colours=False): def _pprint_pps(pps): for pp in pps: if hasattr(pp, "_fields"): @@ -4411,6 +4467,7 @@ def generic_decoder(): # pragma: no cover oids=oids, with_offsets=True, with_blob=False, + with_colours=with_colours, ) for row in pp_console_blob(pp): yield row @@ -4442,6 +4499,11 @@ def main(): # pragma: no cover "--defines-by-path", help="Python path to decoder's defines_by_path", ) + parser.add_argument( + "--with-colours", + action='store_true', + help="Enable coloured output", + ) parser.add_argument( "DERFile", type=argparse.FileType("rb"), @@ -4465,7 +4527,11 @@ def main(): # pragma: no cover {"defines_by_path": obj_by_path(args.defines_by_path)} ), ) - print(pprinter(obj, oids=oids)) + print(pprinter( + obj, + oids=oids, + with_colours=True if args.with_colours else False, + )) if tail != b"": print("\nTrailing data: %s" % hexenc(tail)) diff --git a/tests/test_pyderasn.py b/tests/test_pyderasn.py index 13322d7..18ce656 100644 --- a/tests/test_pyderasn.py +++ b/tests/test_pyderasn.py @@ -57,8 +57,8 @@ from pyderasn import BMPString from pyderasn import Boolean from pyderasn import BoundsError from pyderasn import Choice -from pyderasn import decode_path_defby from pyderasn import DecodeError +from pyderasn import DecodePathDefBy from pyderasn import Enumerated from pyderasn import GeneralizedTime from pyderasn import GeneralString @@ -5017,7 +5017,7 @@ class TestDefinesByPath(TestCase): self.assertIsNone(seq_inner["valueInner"].defined) defines_by_path.append(( - ("value", decode_path_defby(type_sequenced), "typeInner"), + ("value", DecodePathDefBy(type_sequenced), "typeInner"), ((("valueInner",), {type_innered: Pairs()}),), )) seq_sequenced, _ = Seq().decode( @@ -5036,9 +5036,9 @@ class TestDefinesByPath(TestCase): defines_by_path.append(( ( "value", - decode_path_defby(type_sequenced), + DecodePathDefBy(type_sequenced), "valueInner", - decode_path_defby(type_innered), + DecodePathDefBy(type_innered), any, "type", ), -- 2.44.0