]> Cypherpunks.ru repositories - pyderasn.git/blobdiff - pyderasn.py
Ability to specify defines_by_path during command line invocation
[pyderasn.git] / pyderasn.py
index 56eec8d7953e62d6b63295b80795d1dd148d8aed..6d1e7eb736235ec29d37853a0b418525a2e16599 100755 (executable)
@@ -261,6 +261,8 @@ defined, ``value`` contains corresponding decoded value. For example
 above, ``content_info["content"].defined == (id_signedData,
 signed_data)``.
 
+.. _defines_by_path_kwarg:
+
 defines_by_path kwarg
 _____________________
 
@@ -4282,6 +4284,47 @@ def obj_by_path(pypath):  # pragma: no cover
     return obj
 
 
+def generic_decoder():  # pragma: no cover
+    # All of this below is a big hack with self references
+    choice = PrimitiveTypes()
+    choice.specs["SequenceOf"] = SequenceOf(schema=choice)
+    choice.specs["SetOf"] = SetOf(schema=choice)
+    for i in range(31):
+        choice.specs["SequenceOf%d" % i] = SequenceOf(
+            schema=choice,
+            expl=tag_ctxc(i),
+        )
+    choice.specs["Any"] = Any()
+
+    # Class name equals to type name, to omit it from output
+    class SEQUENCEOF(SequenceOf):
+        __slots__ = ()
+        schema = choice
+
+    def pprint_any(obj, oids=None):
+        def _pprint_pps(pps):
+            for pp in pps:
+                if hasattr(pp, "_fields"):
+                    if pp.asn1_type_name == Choice.asn1_type_name:
+                        continue
+                    pp_kwargs = pp._asdict()
+                    pp_kwargs["decode_path"] = pp.decode_path[:-1] + (">",)
+                    pp = _pp(**pp_kwargs)
+                    yield pp_console_row(
+                        pp,
+                        oids=oids,
+                        with_offsets=True,
+                        with_blob=False,
+                    )
+                    for row in pp_console_blob(pp):
+                        yield row
+                else:
+                    for row in _pprint_pps(pp):
+                        yield row
+        return "\n".join(_pprint_pps(obj.pps()))
+    return SEQUENCEOF(), pprint_any
+
+
 def main():  # pragma: no cover
     import argparse
     parser = argparse.ArgumentParser(description="PyDERASN ASN.1 DER decoder")
@@ -4293,6 +4336,10 @@ def main():  # pragma: no cover
         "--schema",
         help="Python path to schema definition to use",
     )
+    parser.add_argument(
+        "--defines-by-path",
+        help="Python path to decoder's defines_by_path",
+    )
     parser.add_argument(
         "DERFile",
         type=argparse.FileType("rb"),
@@ -4307,46 +4354,14 @@ def main():  # pragma: no cover
         from functools import partial
         pprinter = partial(pprint, big_blobs=True)
     else:
-        # All of this below is a big hack with self references
-        choice = PrimitiveTypes()
-        choice.specs["SequenceOf"] = SequenceOf(schema=choice)
-        choice.specs["SetOf"] = SetOf(schema=choice)
-        for i in range(31):
-            choice.specs["SequenceOf%d" % i] = SequenceOf(
-                schema=choice,
-                expl=tag_ctxc(i),
-            )
-        choice.specs["Any"] = Any()
-
-        # Class name equals to type name, to omit it from output
-        class SEQUENCEOF(SequenceOf):
-            __slots__ = ()
-            schema = choice
-        schema = SEQUENCEOF()
-
-        def pprint_any(obj, oids=None):
-            def _pprint_pps(pps):
-                for pp in pps:
-                    if hasattr(pp, "_fields"):
-                        if pp.asn1_type_name == Choice.asn1_type_name:
-                            continue
-                        pp_kwargs = pp._asdict()
-                        pp_kwargs["decode_path"] = pp.decode_path[:-1] + (">",)
-                        pp = _pp(**pp_kwargs)
-                        yield pp_console_row(
-                            pp,
-                            oids=oids,
-                            with_offsets=True,
-                            with_blob=False,
-                        )
-                        for row in pp_console_blob(pp):
-                            yield row
-                    else:
-                        for row in _pprint_pps(pp):
-                            yield row
-            return "\n".join(_pprint_pps(obj.pps()))
-        pprinter = pprint_any
-    obj, tail = schema().decode(der)
+        schema, pprinter = generic_decoder()
+    obj, tail = schema().decode(
+        der,
+        defines_by_path=(
+            None if args.defines_by_path is None
+            else obj_by_path(args.defines_by_path)
+        ),
+    )
     print(pprinter(obj, oids=oids))
     if tail != b"":
         print("\nTrailing data: %s" % hexenc(tail))