From 761a36dafa03cb67bca1b7777031c40c999528a1 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Tue, 2 Jan 2018 13:04:38 +0300 Subject: [PATCH] Strict default values existence validation option --- doc/news.rst | 2 ++ pyderasn.py | 24 ++++++++++++++++++------ tests/test_pyderasn.py | 23 +++++++++++++++++++++++ 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/doc/news.rst b/doc/news.rst index 914a9f8..692f5cc 100644 --- a/doc/news.rst +++ b/doc/news.rst @@ -10,6 +10,8 @@ News keyword argument to ``decode()`` method * :ref:`defines_by_path ` option is now :ref:`decode context ` option, not a keyword argument +* Ability to do :ref:`strict validation ` + of defaulted values met in sequence, raising an exception .. _release1.6: diff --git a/pyderasn.py b/pyderasn.py index b4a10d9..cc44e24 100755 --- a/pyderasn.py +++ b/pyderasn.py @@ -207,6 +207,7 @@ decoding process. Currently available context options: * :ref:`defines_by_path ` +* :ref:`strict_default_existence ` .. _pprinting: @@ -3660,13 +3661,18 @@ class Sequence(Obj): All defaulted values are always optional. + .. _strict_default_existence_ctx: + .. warning:: When decoded DER contains defaulted value inside, then - technically this is not valid DER encoding. But we allow - and pass it. Of course reencoding of that kind of DER will + technically this is not valid DER encoding. But we allow and pass + it **by default**. Of course reencoding of that kind of DER will result in different binary representation (validly without - defaulted value inside). + defaulted value inside). You can enable strict defaulted values + existence validation by setting ``"strict_default_existence": + True`` :ref:`context ` option -- decoding process will raise + an exception if defaulted value is met. Two sequences are equal if they have equal specification (schema), implicit/explicit tagging and the same values. @@ -3900,9 +3906,15 @@ class Sequence(Obj): sub_offset += (value.expl_tlvlen if value.expled else value.tlvlen) v = v_tail if spec.default is not None and value == spec.default: - # Encoded default values are not valid in DER, - # but we allow that anyway - continue + if ctx.get("strict_default_existence", False): + raise DecodeError( + "DEFAULT value met", + klass=self.__class__, + decode_path=sub_decode_path, + offset=sub_offset, + ) + else: + continue values[name] = value spec_defines = getattr(spec, "defines", ()) diff --git a/tests/test_pyderasn.py b/tests/test_pyderasn.py index 498b160..5b98ea6 100644 --- a/tests/test_pyderasn.py +++ b/tests/test_pyderasn.py @@ -5112,3 +5112,26 @@ class TestAbsDecodePath(TestCase): abs_decode_path(decode_path, tuple([".."] * number_of_dots) + rel_path), decode_path[:-number_of_dots] + rel_path, ) + + +class TestStrictDefaultExistence(TestCase): + @given(data_strategy()) + def runTest(self, d): + count = d.draw(integers(min_value=1, max_value=10)) + chosen = d.draw(integers(min_value=0, max_value=count - 1)) + _schema = [ + ("int%d" % i, Integer(expl=tag_ctxc(i + 1))) + for i in range(count) + ] + + class Seq(Sequence): + schema = _schema + seq = Seq() + for i in range(count): + seq["int%d" % i] = Integer(123) + raw = seq.encode() + chosen = "int%d" % chosen + seq.specs[chosen] = seq.specs[chosen](default=123) + seq.decode(raw) + with assertRaisesRegex(self, DecodeError, "DEFAULT value met"): + seq.decode(raw, ctx={"strict_default_existence": True}) -- 2.44.0