]> Cypherpunks.ru repositories - pyderasn.git/commitdiff
Fix double encoded values decoding in SET
authorSergey Matveev <stargrave@stargrave.org>
Wed, 12 Feb 2020 09:50:22 +0000 (12:50 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sun, 16 Feb 2020 09:20:11 +0000 (12:20 +0300)
VERSION
doc/install.rst
doc/news.rst
pyderasn.py
tests/test_pyderasn.py

diff --git a/VERSION b/VERSION
index 0faee7d968ea0de3ddfd2aea0b5d76f0024aa7de..4fedf1d20e15761409d6e4e3bf99c0beb499fdfe 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-6.3
+7.0
index 03d1116285a6c764a42684aeb58eefaa30c47988..a14ebc590b23fbc88d727720b21cc2d3ad6e3ff4 100644 (file)
@@ -4,11 +4,11 @@ Install
 Preferable way is to :ref:`download <download>` tarball with the
 signature from `official website <http://pyderasn.cypherpunks.ru/>`__::
 
-    $ [fetch|wget] http://pyderasn.cypherpunks.ru/pyderasn-6.3.tar.xz
-    $ [fetch|wget] http://pyderasn.cypherpunks.ru/pyderasn-6.3.tar.xz.sig
-    $ gpg --verify pyderasn-6.3.tar.xz.sig pyderasn-6.3.tar.xz
-    $ xz --decompress --stdout pyderasn-6.3.tar.xz | tar xf -
-    $ cd pyderasn-6.3
+    $ [fetch|wget] http://pyderasn.cypherpunks.ru/pyderasn-7.0.tar.xz
+    $ [fetch|wget] http://pyderasn.cypherpunks.ru/pyderasn-7.0.tar.xz.sig
+    $ gpg --verify pyderasn-7.0.tar.xz.sig pyderasn-7.0.tar.xz
+    $ xz --decompress --stdout pyderasn-7.0.tar.xz | tar xf -
+    $ cd pyderasn-7.0
     $ python setup.py install
     # or copy pyderasn.py (+six.py, possibly termcolor.py) to your PYTHONPATH
 
@@ -19,7 +19,7 @@ You can also find it mirrored on :ref:`download <download>` page.
 You could use pip (**no** OpenPGP authentication is performed!) with PyPI::
 
     $ cat > requirements.txt <<EOF
-    pyderasn==6.3 --hash=sha256:TO-BE-FILLED
+    pyderasn==7.0 --hash=sha256:TO-BE-FILLED
     six==1.14.0 --hash=sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a
     EOF
     $ pip install --requirement requirements.txt
index 0034e1f9ac9ae50c86c6687cb481870f50fb8669..47fcc107d04231fc650d0bc0d96a6806b0d182d7 100644 (file)
@@ -1,6 +1,13 @@
 News
 ====
 
+.. _release7.0:
+
+7.0
+---
+* Fixed invalid behaviour where SET OF allowed multiple objects with the
+  same tag to be successfully decoded
+
 .. _release6.3:
 
 6.3
index 43475f19fbdb486580b6c198a1a629698be8b90b..4cabec726c6a2c14f12a242fd326355f3334ee56 100755 (executable)
@@ -808,7 +808,7 @@ except ImportError:  # pragma: no cover
     def colored(what, *args, **kwargs):
         return what
 
-__version__ = "6.3"
+__version__ = "7.0"
 
 __all__ = (
     "Any",
@@ -5641,9 +5641,6 @@ class Set(Sequence):
         v = b"".join(raws)
         return b"".join((self.tag, len_encode(len(v)), v))
 
-    def _specs_items(self):
-        return iteritems(self.specs)
-
     def _decode(self, tlv, offset, decode_path, ctx, tag_only):
         try:
             t, tlen, lv = tag_strip(tlv)
@@ -5698,11 +5695,12 @@ class Set(Sequence):
         ctx_allow_default_values = ctx.get("allow_default_values", False)
         ctx_allow_unordered_set = ctx.get("allow_unordered_set", False)
         value_prev = memoryview(v[:0])
+        _specs_items = copy(self.specs)
 
         while len(v) > 0:
             if lenindef and v[:EOC_LEN].tobytes() == EOC:
                 break
-            for name, spec in self._specs_items():
+            for name, spec in iteritems(_specs_items):
                 sub_decode_path = decode_path + (name,)
                 try:
                     spec.decode(
@@ -5754,10 +5752,12 @@ class Set(Sequence):
                     offset=sub_offset,
                 )
             values[name] = value
+            del _specs_items[name]
             value_prev = v[:value_len]
             sub_offset += value_len
             vlen += value_len
             v = v_tail
+
         obj = self.__class__(
             schema=self.specs,
             impl=self.tag,
index 1cce9ed5a3988a92b92248e987d2e012366bf798..3161102997daf57449b26c20194b1081613f8b65 100644 (file)
@@ -6049,6 +6049,22 @@ class TestSet(SeqMixing, CommonMixin, TestCase):
                 tags,
             )
 
+    def test_same_value_twice(self):
+        class Seq(Set):
+            schema = (
+                ("bool", Boolean()),
+                ("int", Integer()),
+            )
+
+        encoded = b"".join((
+            Integer(123).encode(),
+            Integer(234).encode(),
+            Boolean(True).encode(),
+        ))
+        encoded = Seq.tag_default + len_encode(len(encoded)) + encoded
+        with self.assertRaises(TagMismatch):
+            Seq().decod(encoded, ctx={"allow_unordered_set": True})
+
 
 @composite
 def seqof_values_strategy(draw, schema=None, do_expl=False):