]> Cypherpunks.ru repositories - pyderasn.git/commitdiff
Separate BERed and LenIndefinited properties
authorSergey Matveev <stargrave@stargrave.org>
Sun, 20 May 2018 08:53:59 +0000 (11:53 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sun, 20 May 2018 09:22:37 +0000 (12:22 +0300)
pyderasn.py
tests/test_pyderasn.py

index a048f4d3990c85e899f10a1f96179a89217da7aa..c8e29e3d767249c9de62be911540c9c3cf9e7992 100755 (executable)
@@ -849,8 +849,9 @@ class Obj(object):
         "offset",
         "llen",
         "vlen",
+        "lenindef",
+        "expl_lenindef",
         "bered",
-        "expl_bered",
     )
 
     def __init__(
@@ -872,8 +873,9 @@ class Obj(object):
         self.optional = optional
         self.offset, self.llen, self.vlen = _decoded
         self.default = None
+        self.lenindef = False
+        self.expl_lenindef = False
         self.bered = False
-        self.expl_bered = False
 
     @property
     def ready(self):  # pragma: no cover
@@ -1012,7 +1014,7 @@ class Obj(object):
                         offset=offset,
                     )
                 obj.vlen += EOC_LEN
-                obj.expl_bered = True
+                obj.expl_lenindef = True
             except DecodeError as err:
                 raise err.__class__(
                     msg=err.msg,
@@ -1054,7 +1056,7 @@ class Obj(object):
 
     @property
     def expl_llen(self):
-        if self.expl_bered:
+        if self.expl_lenindef:
             return 1
         return len(len_encode(self.tlvlen))
 
@@ -2121,12 +2123,12 @@ class BitString(Obj):
                 )
             if tag_only:
                 return
-            eoc_expected = False
+            lenindef = False
             try:
                 l, llen, v = len_decode(lv)
             except LenIndefiniteForm:
                 llen, l, v = 1, 0, lv[1:]
-                eoc_expected = True
+                lenindef = True
             except DecodeError as err:
                 raise err.__class__(
                     msg=err.msg,
@@ -2141,7 +2143,7 @@ class BitString(Obj):
                     decode_path=decode_path,
                     offset=offset,
                 )
-            if not eoc_expected and l == 0:
+            if not lenindef and l == 0:
                 raise NotEnoughData(
                     "zero length",
                     klass=self.__class__,
@@ -2152,7 +2154,7 @@ class BitString(Obj):
             sub_offset = offset + tlen + llen
             vlen = 0
             while True:
-                if eoc_expected:
+                if lenindef:
                     if v[:EOC_LEN].tobytes() == EOC:
                         break
                 else:
@@ -2210,10 +2212,11 @@ class BitString(Obj):
                 default=self.default,
                 optional=self.optional,
                 _specs=self.specs,
-                _decoded=(offset, llen, vlen + (EOC_LEN if eoc_expected else 0)),
+                _decoded=(offset, llen, vlen + (EOC_LEN if lenindef else 0)),
             )
+            obj.lenindef = lenindef
             obj.bered = True
-            return obj, v[EOC_LEN if eoc_expected else 0:]
+            return obj, (v[EOC_LEN:] if lenindef else v)
         raise TagMismatch(
             klass=self.__class__,
             decode_path=decode_path,
@@ -2472,12 +2475,12 @@ class OctetString(Obj):
                 )
             if tag_only:
                 return
-            eoc_expected = False
+            lenindef = False
             try:
                 l, llen, v = len_decode(lv)
             except LenIndefiniteForm:
                 llen, l, v = 1, 0, lv[1:]
-                eoc_expected = True
+                lenindef = True
             except DecodeError as err:
                 raise err.__class__(
                     msg=err.msg,
@@ -2492,7 +2495,7 @@ class OctetString(Obj):
                     decode_path=decode_path,
                     offset=offset,
                 )
-            if not eoc_expected and l == 0:
+            if not lenindef and l == 0:
                 raise NotEnoughData(
                     "zero length",
                     klass=self.__class__,
@@ -2503,7 +2506,7 @@ class OctetString(Obj):
             sub_offset = offset + tlen + llen
             vlen = 0
             while True:
-                if eoc_expected:
+                if lenindef:
                     if v[:EOC_LEN].tobytes() == EOC:
                         break
                 else:
@@ -2548,7 +2551,7 @@ class OctetString(Obj):
                     expl=self._expl,
                     default=self.default,
                     optional=self.optional,
-                    _decoded=(offset, llen, vlen + (EOC_LEN if eoc_expected else 0)),
+                    _decoded=(offset, llen, vlen + (EOC_LEN if lenindef else 0)),
                 )
             except DecodeError as err:
                 raise DecodeError(
@@ -2564,8 +2567,9 @@ class OctetString(Obj):
                     decode_path=decode_path,
                     offset=offset,
                 )
+            obj.lenindef = lenindef
             obj.bered = True
-            return obj, v[EOC_LEN if eoc_expected else 0:]
+            return obj, (v[EOC_LEN:] if lenindef else v)
         raise TagMismatch(
             klass=self.__class__,
             decode_path=decode_path,
@@ -3915,7 +3919,7 @@ class Any(Obj):
                         optional=self.optional,
                         _decoded=(offset, 0, tlvlen),
                     )
-                    obj.bered = True
+                    obj.lenindef = True
                     obj.tag = t
                     return obj, v[EOC_LEN:]
                 else:
@@ -4275,7 +4279,7 @@ class Sequence(Obj):
             )
         if tag_only:
             return
-        eoc_expected = False
+        lenindef = False
         try:
             l, llen, v = len_decode(lv)
         except LenIndefiniteForm as err:
@@ -4287,7 +4291,7 @@ class Sequence(Obj):
                     offset=offset,
                 )
             l, llen, v = 0, 1, lv[1:]
-            eoc_expected = True
+            lenindef = True
         except DecodeError as err:
             raise err.__class__(
                 msg=err.msg,
@@ -4302,14 +4306,14 @@ class Sequence(Obj):
                 decode_path=decode_path,
                 offset=offset,
             )
-        if not eoc_expected:
+        if not lenindef:
             v, tail = v[:l], v[l:]
         vlen = 0
         sub_offset = offset + tlen + llen
         values = {}
         for name, spec in self.specs.items():
             if spec.optional and (
-                (eoc_expected and v[:EOC_LEN].tobytes() == EOC) or
+                (lenindef and v[:EOC_LEN].tobytes() == EOC) or
                 len(v) == 0
             ):
                 continue
@@ -4403,7 +4407,7 @@ class Sequence(Obj):
                             abs_decode_path(sub_decode_path[:-1], rel_path),
                             (value, defined),
                         ))
-        if eoc_expected:
+        if lenindef:
             if v[:EOC_LEN].tobytes() != EOC:
                 raise DecodeError(
                     "no EOC",
@@ -4429,8 +4433,7 @@ class Sequence(Obj):
             _decoded=(offset, llen, vlen),
         )
         obj._value = values
-        if eoc_expected:
-            obj.bered = True
+        obj.lenindef = lenindef
         return obj, tail
 
     def __repr__(self):
@@ -4501,7 +4504,7 @@ class Set(Sequence):
             )
         if tag_only:
             return
-        eoc_expected = False
+        lenindef = False
         try:
             l, llen, v = len_decode(lv)
         except LenIndefiniteForm as err:
@@ -4513,7 +4516,7 @@ class Set(Sequence):
                     offset=offset,
                 )
             l, llen, v = 0, 1, lv[1:]
-            eoc_expected = True
+            lenindef = True
         except DecodeError as err:
             raise err.__class__(
                 msg=err.msg,
@@ -4527,14 +4530,14 @@ class Set(Sequence):
                 klass=self.__class__,
                 offset=offset,
             )
-        if not eoc_expected:
+        if not lenindef:
             v, tail = v[:l], v[l:]
         vlen = 0
         sub_offset = offset + tlen + llen
         values = {}
         specs_items = self.specs.items
         while len(v) > 0:
-            if eoc_expected and v[:EOC_LEN].tobytes() == EOC:
+            if lenindef and v[:EOC_LEN].tobytes() == EOC:
                 break
             for name, spec in specs_items():
                 sub_decode_path = decode_path + (name,)
@@ -4576,7 +4579,7 @@ class Set(Sequence):
             expl=self._expl,
             default=self.default,
             optional=self.optional,
-            _decoded=(offset, llen, vlen + (EOC_LEN if eoc_expected else 0)),
+            _decoded=(offset, llen, vlen + (EOC_LEN if lenindef else 0)),
         )
         obj._value = values
         if not obj.ready:
@@ -4586,10 +4589,8 @@ class Set(Sequence):
                 decode_path=decode_path,
                 offset=offset,
             )
-        if eoc_expected:
-            obj.bered = True
-            tail = v[EOC_LEN:]
-        return obj, tail
+        obj.lenindef = lenindef
+        return obj, (v[EOC_LEN:] if lenindef else tail)
 
 
 class SequenceOf(Obj):
@@ -4790,7 +4791,7 @@ class SequenceOf(Obj):
             )
         if tag_only:
             return
-        eoc_expected = False
+        lenindef = False
         try:
             l, llen, v = len_decode(lv)
         except LenIndefiniteForm as err:
@@ -4802,7 +4803,7 @@ class SequenceOf(Obj):
                     offset=offset,
                 )
             l, llen, v = 0, 1, lv[1:]
-            eoc_expected = True
+            lenindef = True
         except DecodeError as err:
             raise err.__class__(
                 msg=err.msg,
@@ -4817,14 +4818,14 @@ class SequenceOf(Obj):
                 decode_path=decode_path,
                 offset=offset,
             )
-        if not eoc_expected:
+        if not lenindef:
             v, tail = v[:l], v[l:]
         vlen = 0
         sub_offset = offset + tlen + llen
         _value = []
         spec = self.spec
         while len(v) > 0:
-            if eoc_expected and v[:EOC_LEN].tobytes() == EOC:
+            if lenindef and v[:EOC_LEN].tobytes() == EOC:
                 break
             value, v_tail = spec.decode(
                 v,
@@ -4848,10 +4849,8 @@ class SequenceOf(Obj):
             optional=self.optional,
             _decoded=(offset, llen, vlen),
         )
-        if eoc_expected:
-            obj.bered = True
-            tail = v[EOC_LEN:]
-        return obj, tail
+        obj.lenindef = lenindef
+        return obj, (v[EOC_LEN:] if lenindef else tail)
 
     def __repr__(self):
         return "%s[%s]" % (
index faa85699fd2d628058d3c9cf5d2ce83d8fbcc218..10ad675c49bceb537f509b2f685635e033043221 100644 (file)
@@ -607,6 +607,7 @@ class TestBoolean(CommonMixin, TestCase):
         )
         self.assertTrue(bool(obj))
         self.assertTrue(obj.bered)
+        self.assertFalse(obj.lenindef)
 
     @given(
         integers(min_value=1).map(tag_ctxc),
@@ -633,8 +634,26 @@ class TestBoolean(CommonMixin, TestCase):
         self.assertSequenceEqual(tail, b"")
         self.assertSequenceEqual([bool(v) for v in seqof], values)
         self.assertSetEqual(
-            set((v.tlvlen, v.expl_tlvlen, v.expl_tlen, v.expl_llen) for v in seqof),
-            set(((3 + EOC_LEN, len(expl) + 1 + 3 + EOC_LEN, len(expl), 1),)),
+            set(
+                (
+                    v.tlvlen,
+                    v.expl_tlvlen,
+                    v.expl_tlen,
+                    v.expl_llen,
+                    v.bered,
+                    v.lenindef,
+                    v.expl_lenindef,
+                ) for v in seqof
+            ),
+            set(((
+                3 + EOC_LEN,
+                len(expl) + 1 + 3 + EOC_LEN,
+                len(expl),
+                1,
+                False,
+                False,
+                True,
+            ),)),
         )
 
 
@@ -1485,7 +1504,10 @@ class TestBitString(CommonMixin, TestCase):
         )
         with assertRaisesRegex(self, DecodeError, "unallowed BER"):
             BitString(impl=tag_encode(impl)).decode(encoded_indefinite)
-        for encoded in (encoded_indefinite, encoded_definite):
+        for lenindef_expected, encoded in (
+            (True, encoded_indefinite),
+            (False, encoded_definite),
+        ):
             obj, tail = BitString(impl=tag_encode(impl)).decode(
                 encoded, ctx={"bered": True}
             )
@@ -1493,6 +1515,7 @@ class TestBitString(CommonMixin, TestCase):
             self.assertEqual(obj.bit_len, bit_len_expected)
             self.assertSequenceEqual(bytes(obj), payload_expected)
             self.assertTrue(obj.bered)
+            self.assertEqual(obj.lenindef, lenindef_expected)
             self.assertEqual(len(encoded), obj.tlvlen)
 
     def test_x690_vector(self):
@@ -1507,6 +1530,8 @@ class TestBitString(CommonMixin, TestCase):
         )
         self.assertSequenceEqual(tail, b"")
         self.assertEqual(obj, vector)
+        self.assertTrue(obj.bered)
+        self.assertTrue(obj.lenindef)
 
 
 @composite
@@ -1865,13 +1890,17 @@ class TestOctetString(CommonMixin, TestCase):
         )
         with assertRaisesRegex(self, DecodeError, "unallowed BER"):
             OctetString(impl=tag_encode(impl)).decode(encoded_indefinite)
-        for encoded in (encoded_indefinite, encoded_definite):
+        for lenindef_expected, encoded in (
+            (True, encoded_indefinite),
+            (False, encoded_definite),
+        ):
             obj, tail = OctetString(impl=tag_encode(impl)).decode(
                 encoded, ctx={"bered": True}
             )
             self.assertSequenceEqual(tail, b"")
             self.assertSequenceEqual(bytes(obj), payload_expected)
             self.assertTrue(obj.bered)
+            self.assertEqual(obj.lenindef, lenindef_expected)
             self.assertEqual(len(encoded), obj.tlvlen)
 
 
@@ -3085,24 +3114,29 @@ class TestVisibleString(
     base_klass = VisibleString
 
     def test_x690_vector(self):
-        self.assertEqual(
-            str(VisibleString().decode(hexdec("1A054A6F6E6573"))[0]),
-            "Jones",
-        )
-        self.assertEqual(
-            str(VisibleString().decode(
-                hexdec("3A0904034A6F6E04026573"),
-                ctx={"bered": True},
-            )[0]),
-            "Jones",
+        obj, tail = VisibleString().decode(hexdec("1A054A6F6E6573"))
+        self.assertSequenceEqual(tail, b"")
+        self.assertEqual(str(obj), "Jones")
+        self.assertFalse(obj.bered)
+        self.assertFalse(obj.lenindef)
+
+        obj, tail = VisibleString().decode(
+            hexdec("3A0904034A6F6E04026573"),
+            ctx={"bered": True},
         )
-        self.assertEqual(
-            str(VisibleString().decode(
-                hexdec("3A8004034A6F6E040265730000"),
-                ctx={"bered": True},
-            )[0]),
-            "Jones",
+        self.assertSequenceEqual(tail, b"")
+        self.assertEqual(str(obj), "Jones")
+        self.assertTrue(obj.bered)
+        self.assertFalse(obj.lenindef)
+
+        obj, tail = VisibleString().decode(
+            hexdec("3A8004034A6F6E040265730000"),
+            ctx={"bered": True},
         )
+        self.assertSequenceEqual(tail, b"")
+        self.assertEqual(str(obj), "Jones")
+        self.assertTrue(obj.bered)
+        self.assertTrue(obj.lenindef)
 
 
 class TestGeneralString(