]> Cypherpunks.ru repositories - pyderasn.git/blobdiff - pyderasn.py
Prepare for 4.3 release
[pyderasn.git] / pyderasn.py
index eca1825efd03429bcb88c3d7ef265644339565b9..9c4da4ec76b94b3561581453e2b981fa18e14ad3 100755 (executable)
@@ -542,6 +542,7 @@ from collections import OrderedDict
 from datetime import datetime
 from math import ceil
 from os import environ
+from string import ascii_letters
 from string import digits
 
 from six import add_metaclass
@@ -559,7 +560,7 @@ from six.moves import xrange as six_xrange
 
 try:
     from termcolor import colored
-except ImportError:
+except ImportError:  # pragma: no cover
     def colored(what, *args):
         return what
 
@@ -1084,7 +1085,7 @@ class Obj(object):
                     ctx=ctx,
                     tag_only=tag_only,
                 )
-                if tag_only:
+                if tag_only:  # pragma: no cover
                     return
                 obj, tail = result
                 eoc_expected, tail = tail[:EOC_LEN], tail[EOC_LEN:]
@@ -1119,7 +1120,7 @@ class Obj(object):
                     ctx=ctx,
                     tag_only=tag_only,
                 )
-                if tag_only:
+                if tag_only:  # pragma: no cover
                     return
                 obj, tail = result
                 if obj.tlvlen < l and not ctx.get("allow_expl_oob", False):
@@ -1170,7 +1171,10 @@ class Obj(object):
         return self.expl_tlvlen if self.expled else self.tlvlen
 
     def pps_lenindef(self, decode_path):
-        if self.lenindef:
+        if self.lenindef and not (
+            getattr(self, "defined", None) is not None and
+            self.defined[1].lenindef
+        ):
             yield _pp(
                 asn1_type_name="EOC",
                 obj_name="",
@@ -2314,7 +2318,7 @@ class BitString(Obj):
                 offset=offset,
             )
         if t == self.tag:
-            if tag_only:
+            if tag_only:  # pragma: no cover
                 return
             return self._decode_chunk(lv, offset, decode_path, ctx)
         if t == self.tag_constructed:
@@ -2325,7 +2329,7 @@ class BitString(Obj):
                     decode_path=decode_path,
                     offset=offset,
                 )
-            if tag_only:
+            if tag_only:  # pragma: no cover
                 return
             lenindef = False
             try:
@@ -2907,7 +2911,7 @@ class Null(Obj):
                 decode_path=decode_path,
                 offset=offset,
             )
-        if tag_only:
+        if tag_only:  # pragma: no cover
             return
         try:
             l, _, v = len_decode(lv)
@@ -3158,7 +3162,7 @@ class ObjectIdentifier(Obj):
                 decode_path=decode_path,
                 offset=offset,
             )
-        if tag_only:
+        if tag_only:  # pragma: no cover
             return
         try:
             l, llen, v = len_decode(lv)
@@ -3488,13 +3492,14 @@ class UTF8String(CommonString):
 class NumericString(CommonString):
     """Numeric string
 
-    Its value is properly sanitized: only ASCII digits can be stored.
+    Its value is properly sanitized: only ASCII digits with spaces can
+    be stored.
     """
     __slots__ = ()
     tag_default = tag_encode(18)
     encoding = "ascii"
     asn1_type_name = "NumericString"
-    allowable_chars = set(digits.encode("ascii"))
+    allowable_chars = set(digits.encode("ascii") + b" ")
 
     def _value_sanitize(self, value):
         value = super(NumericString, self)._value_sanitize(value)
@@ -3504,10 +3509,21 @@ class NumericString(CommonString):
 
 
 class PrintableString(CommonString):
+    """Printable string
+
+    Its value is properly sanitized: see X.680 41.4 table 10.
+    """
     __slots__ = ()
     tag_default = tag_encode(19)
     encoding = "ascii"
     asn1_type_name = "PrintableString"
+    allowable_chars = set((ascii_letters + digits + " '()+,-./:=?").encode("ascii"))
+
+    def _value_sanitize(self, value):
+        value = super(PrintableString, self)._value_sanitize(value)
+        if not set(value) <= self.allowable_chars:
+            raise DecodeError("non-printable value")
+        return value
 
 
 class TeletexString(CommonString):
@@ -3981,7 +3997,7 @@ class Choice(Obj):
                 decode_path=decode_path,
                 offset=offset,
             )
-        if tag_only:
+        if tag_only:  # pragma: no cover
             return
         value, tail = spec.decode(
             tlv,
@@ -4555,7 +4571,7 @@ class Sequence(Obj):
                 decode_path=decode_path,
                 offset=offset,
             )
-        if tag_only:
+        if tag_only:  # pragma: no cover
             return
         lenindef = False
         ctx_bered = ctx.get("bered", False)