doc/news.rst | 1 + pyderasn.py | 33 +++++++++++++++++++++++++++++++++ tests/test_pyderasn.py | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/doc/news.rst b/doc/news.rst index a189c8e6fe07fb96e4f39974ff6279021ca71dd9183ae30573bd5299e75d3979..3893a982abd4d0fd62d5130298f2b63c48abe78971ec31a087a075e8d79bbd02 100644 --- a/doc/news.rst +++ b/doc/news.rst @@ -7,6 +7,7 @@ 4.7 --- * ObjectIdentifier has ``ber_encoded`` set to True, if non-normalized arc encoding is met +* Preserve BER-related attributes during ``copy()`` .. _release4.6: diff --git a/pyderasn.py b/pyderasn.py index 730ec2ce556029a8452933b0a2ff04ab44678a82ee4a9c8d3df89a54bf0c63eb..b5f3fd72d6fe35a4cf8e6d57c5931efe7624dae95396d9bb7db4a29884560849 100755 --- a/pyderasn.py +++ b/pyderasn.py @@ -1569,6 +1569,9 @@ obj.optional = self.optional obj.offset = self.offset obj.llen = self.llen obj.vlen = self.vlen + obj.expl_lenindef = self.expl_lenindef + obj.lenindef = self.lenindef + obj.ber_encoded = self.ber_encoded return obj def __nonzero__(self): @@ -1825,6 +1828,9 @@ obj.optional = self.optional obj.offset = self.offset obj.llen = self.llen obj.vlen = self.vlen + obj.expl_lenindef = self.expl_lenindef + obj.lenindef = self.lenindef + obj.ber_encoded = self.ber_encoded return obj def __int__(self): @@ -2205,6 +2211,9 @@ obj.optional = self.optional obj.offset = self.offset obj.llen = self.llen obj.vlen = self.vlen + obj.expl_lenindef = self.expl_lenindef + obj.lenindef = self.lenindef + obj.ber_encoded = self.ber_encoded return obj def __iter__(self): @@ -2617,6 +2626,9 @@ obj.optional = self.optional obj.offset = self.offset obj.llen = self.llen obj.vlen = self.vlen + obj.expl_lenindef = self.expl_lenindef + obj.lenindef = self.lenindef + obj.ber_encoded = self.ber_encoded return obj def __bytes__(self): @@ -2903,6 +2915,9 @@ obj.optional = self.optional obj.offset = self.offset obj.llen = self.llen obj.vlen = self.vlen + obj.expl_lenindef = self.expl_lenindef + obj.lenindef = self.lenindef + obj.ber_encoded = self.ber_encoded return obj def __eq__(self, their): @@ -3113,6 +3128,9 @@ obj.optional = self.optional obj.offset = self.offset obj.llen = self.llen obj.vlen = self.vlen + obj.expl_lenindef = self.expl_lenindef + obj.lenindef = self.lenindef + obj.ber_encoded = self.ber_encoded return obj def __iter__(self): @@ -3362,6 +3380,9 @@ obj.optional = self.optional obj.offset = self.offset obj.llen = self.llen obj.vlen = self.vlen + obj.expl_lenindef = self.expl_lenindef + obj.lenindef = self.lenindef + obj.ber_encoded = self.ber_encoded return obj def __call__( @@ -3969,6 +3990,9 @@ obj.optional = self.optional obj.offset = self.offset obj.llen = self.llen obj.vlen = self.vlen + obj.expl_lenindef = self.expl_lenindef + obj.lenindef = self.lenindef + obj.ber_encoded = self.ber_encoded value = self._value if value is not None: obj._value = (value[0], value[1].copy()) @@ -4209,6 +4233,9 @@ obj.optional = self.optional obj.offset = self.offset obj.llen = self.llen obj.vlen = self.vlen + obj.expl_lenindef = self.expl_lenindef + obj.lenindef = self.lenindef + obj.ber_encoded = self.ber_encoded return obj def __eq__(self, their): @@ -4548,6 +4575,9 @@ obj.optional = self.optional obj.offset = self.offset obj.llen = self.llen obj.vlen = self.vlen + obj.expl_lenindef = self.expl_lenindef + obj.lenindef = self.lenindef + obj.ber_encoded = self.ber_encoded obj._value = {k: v.copy() for k, v in self._value.items()} return obj @@ -5125,6 +5155,9 @@ obj.optional = self.optional obj.offset = self.offset obj.llen = self.llen obj.vlen = self.vlen + obj.expl_lenindef = self.expl_lenindef + obj.lenindef = self.lenindef + obj.ber_encoded = self.ber_encoded obj._value = [v.copy() for v in self._value] return obj diff --git a/tests/test_pyderasn.py b/tests/test_pyderasn.py index 6fb765ba2aa2d6921ba4f82fba028e030b1e499d45e321878eec181bbf6b0ba5..d76e6779af23b77e1e0301541dcfdfb45fc63226aa17ec22244574bcdd4d2931 100644 --- a/tests/test_pyderasn.py +++ b/tests/test_pyderasn.py @@ -622,6 +622,10 @@ self.assertTrue(bool(obj)) self.assertTrue(obj.ber_encoded) self.assertFalse(obj.lenindef) self.assertTrue(obj.bered) + obj = obj.copy() + self.assertTrue(obj.ber_encoded) + self.assertFalse(obj.lenindef) + self.assertTrue(obj.bered) @given( integers(min_value=1).map(tag_ctxc), @@ -637,6 +641,11 @@ obj, tail = Boolean(expl=expl).decode( encoded + EOC + junk, ctx={"bered": True}, ) + self.assertTrue(obj.expl_lenindef) + self.assertFalse(obj.lenindef) + self.assertFalse(obj.ber_encoded) + self.assertTrue(obj.bered) + obj = obj.copy() self.assertTrue(obj.expl_lenindef) self.assertFalse(obj.lenindef) self.assertFalse(obj.ber_encoded) @@ -1584,6 +1593,10 @@ self.assertSequenceEqual(bytes(obj), payload_expected) self.assertTrue(obj.ber_encoded) self.assertEqual(obj.lenindef, lenindef_expected) self.assertTrue(obj.bered) + obj = obj.copy() + self.assertTrue(obj.ber_encoded) + self.assertEqual(obj.lenindef, lenindef_expected) + self.assertTrue(obj.bered) self.assertEqual(len(encoded), obj.tlvlen) @given( @@ -1713,6 +1726,10 @@ ctx={"bered": True}, ) self.assertSequenceEqual(tail, b"") self.assertEqual(obj, vector) + self.assertTrue(obj.ber_encoded) + self.assertTrue(obj.lenindef) + self.assertTrue(obj.bered) + obj = obj.copy() self.assertTrue(obj.ber_encoded) self.assertTrue(obj.lenindef) self.assertTrue(obj.bered) @@ -2103,6 +2120,10 @@ self.assertSequenceEqual(bytes(obj), payload_expected) self.assertTrue(obj.ber_encoded) self.assertEqual(obj.lenindef, lenindef_expected) self.assertTrue(obj.bered) + obj = obj.copy() + self.assertTrue(obj.ber_encoded) + self.assertEqual(obj.lenindef, lenindef_expected) + self.assertTrue(obj.bered) self.assertEqual(len(encoded), obj.tlvlen) @given( @@ -2731,6 +2752,10 @@ ObjectIdentifier((1, 0)).encode()[-1:] ) obj, _ = ObjectIdentifier().decode(tampered, ctx={"bered": True}) self.assertTrue(obj.ber_encoded) + self.assertTrue(obj.bered) + obj = obj.copy() + self.assertTrue(obj.ber_encoded) + self.assertTrue(obj.bered) with assertRaisesRegex(self, DecodeError, "non normalized arc encoding"): ObjectIdentifier().decode(tampered) @@ -2760,6 +2785,10 @@ tampered ) obj, _ = ObjectIdentifier().decode(tampered, ctx={"bered": True}) self.assertTrue(obj.ber_encoded) + self.assertTrue(obj.bered) + obj = obj.copy() + self.assertTrue(obj.ber_encoded) + self.assertTrue(obj.bered) with assertRaisesRegex(self, DecodeError, "non normalized arc encoding"): ObjectIdentifier().decode(tampered) @@ -3494,6 +3523,10 @@ self.assertEqual(str(obj), "Jones") self.assertTrue(obj.ber_encoded) self.assertFalse(obj.lenindef) self.assertTrue(obj.bered) + obj = obj.copy() + self.assertTrue(obj.ber_encoded) + self.assertFalse(obj.lenindef) + self.assertTrue(obj.bered) obj, tail = VisibleString().decode( hexdec("3A8004034A6F6E040265730000"), @@ -3501,6 +3534,10 @@ ctx={"bered": True}, ) self.assertSequenceEqual(tail, b"") self.assertEqual(str(obj), "Jones") + self.assertTrue(obj.ber_encoded) + self.assertTrue(obj.lenindef) + self.assertTrue(obj.bered) + obj = obj.copy() self.assertTrue(obj.ber_encoded) self.assertTrue(obj.lenindef) self.assertTrue(obj.bered) @@ -4197,6 +4234,10 @@ self.assertEqual(obj.tlvlen, len(encoded)) self.assertTrue(obj.lenindef) self.assertFalse(obj.ber_encoded) self.assertTrue(obj.bered) + obj = obj.copy() + self.assertTrue(obj.lenindef) + self.assertFalse(obj.ber_encoded) + self.assertTrue(obj.bered) repr(obj) list(obj.pps()) pprint(obj, big_blobs=True, with_decode_path=True) @@ -5010,6 +5051,9 @@ del ctx_copied["bered"] self.assertDictEqual(ctx_copied, ctx_dummy) self.assertTrue(seq_decoded_lenindef.lenindef) self.assertTrue(seq_decoded_lenindef.bered) + seq_decoded_lenindef = seq_decoded_lenindef.copy() + self.assertTrue(seq_decoded_lenindef.lenindef) + self.assertTrue(seq_decoded_lenindef.bered) with self.assertRaises(DecodeError): seq.decode(seq_encoded_lenindef[:-1], ctx={"bered": True}) with self.assertRaises(DecodeError): @@ -5127,6 +5171,9 @@ for ctx in ({"bered": True}, {"allow_default_values": True}): seq_decoded, _ = seq_with_default.decode(seq_encoded, ctx=ctx) self.assertTrue(seq_decoded.ber_encoded) self.assertTrue(seq_decoded.bered) + seq_decoded = seq_decoded.copy() + self.assertTrue(seq_decoded.ber_encoded) + self.assertTrue(seq_decoded.bered) for name, value in _schema: self.assertEqual(seq_decoded[name], seq_with_default[name]) self.assertEqual(seq_decoded[name], value) @@ -5165,6 +5212,10 @@ decoded, _ = Seq().decode(encoded, ctx={"bered": True}) self.assertFalse(decoded.ber_encoded) self.assertFalse(decoded.lenindef) self.assertTrue(decoded.bered) + decoded = decoded.copy() + self.assertFalse(decoded.ber_encoded) + self.assertFalse(decoded.lenindef) + self.assertTrue(decoded.bered) class Seq(self.base_klass): schema = (("underlying", OctetString()),) @@ -5178,6 +5229,10 @@ encoded = Seq.tag_default + len_encode(len(encoded)) + encoded with self.assertRaises(DecodeError): Seq().decode(encoded) decoded, _ = Seq().decode(encoded, ctx={"bered": True}) + self.assertFalse(decoded.ber_encoded) + self.assertFalse(decoded.lenindef) + self.assertTrue(decoded.bered) + decoded = decoded.copy() self.assertFalse(decoded.ber_encoded) self.assertFalse(decoded.lenindef) self.assertTrue(decoded.bered) @@ -5275,6 +5330,9 @@ with assertRaisesRegex(self, DecodeError, "unordered SET"): seq.decode(seq_encoded) for ctx in ({"bered": True}, {"allow_unordered_set": True}): seq_decoded, _ = Seq().decode(seq_encoded, ctx=ctx) + self.assertTrue(seq_decoded.ber_encoded) + self.assertTrue(seq_decoded.bered) + seq_decoded = seq_decoded.copy() self.assertTrue(seq_decoded.ber_encoded) self.assertTrue(seq_decoded.bered) self.assertSequenceEqual( @@ -5702,6 +5760,9 @@ ctx={"bered": True}, ) self.assertTrue(obj_decoded_lenindef.lenindef) self.assertTrue(obj_decoded_lenindef.bered) + obj_decoded_lenindef = obj_decoded_lenindef.copy() + self.assertTrue(obj_decoded_lenindef.lenindef) + self.assertTrue(obj_decoded_lenindef.bered) repr(obj_decoded_lenindef) list(obj_decoded_lenindef.pps()) pprint(obj_decoded_lenindef, big_blobs=True, with_decode_path=True) @@ -5724,6 +5785,10 @@ decoded, _ = SeqOf().decode(encoded, ctx={"bered": True}) self.assertFalse(decoded.ber_encoded) self.assertFalse(decoded.lenindef) self.assertTrue(decoded.bered) + decoded = decoded.copy() + self.assertFalse(decoded.ber_encoded) + self.assertFalse(decoded.lenindef) + self.assertTrue(decoded.bered) class SeqOf(self.base_klass): schema = OctetString() @@ -5738,6 +5803,10 @@ encoded = SeqOf.tag_default + len_encode(len(encoded)) + encoded with self.assertRaises(DecodeError): SeqOf().decode(encoded) decoded, _ = SeqOf().decode(encoded, ctx={"bered": True}) + self.assertFalse(decoded.ber_encoded) + self.assertFalse(decoded.lenindef) + self.assertTrue(decoded.bered) + decoded = decoded.copy() self.assertFalse(decoded.ber_encoded) self.assertFalse(decoded.lenindef) self.assertTrue(decoded.bered) @@ -5804,6 +5873,9 @@ seq.decode(seq_encoded) for ctx in ({"bered": True}, {"allow_unordered_set": True}): seq_decoded, _ = Seq().decode(seq_encoded, ctx=ctx) + self.assertTrue(seq_decoded.ber_encoded) + self.assertTrue(seq_decoded.bered) + seq_decoded = seq_decoded.copy() self.assertTrue(seq_decoded.ber_encoded) self.assertTrue(seq_decoded.bered) self.assertSequenceEqual( @@ -6311,7 +6383,13 @@ seq.decode(raw) decoded, _ = seq.decode(raw, ctx={"allow_default_values": True}) self.assertTrue(decoded.ber_encoded) self.assertTrue(decoded.bered) + decoded = decoded.copy() + self.assertTrue(decoded.ber_encoded) + self.assertTrue(decoded.bered) decoded, _ = seq.decode(raw, ctx={"bered": True}) + self.assertTrue(decoded.ber_encoded) + self.assertTrue(decoded.bered) + decoded = decoded.copy() self.assertTrue(decoded.ber_encoded) self.assertTrue(decoded.bered)