keyword argument to ``decode()`` method
* :ref:`defines_by_path <defines_by_path_ctx>` option is now
:ref:`decode context <ctx>` option, not a keyword argument
+* Ability to do :ref:`strict validation <strict_default_existence_ctx>`
+ of defaulted values met in sequence, raising an exception
.. _release1.6:
Currently available context options:
* :ref:`defines_by_path <defines_by_path_ctx>`
+* :ref:`strict_default_existence <strict_default_existence_ctx>`
.. _pprinting:
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 <ctx>` 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.
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", ())
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})