X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=tests%2Ftest_pyderasn.py;h=dec37f3f3c65823612ff5a68bf23492a954ea0bb;hb=fa121badee14d881f0e341604c050facae3790f0;hp=174abb6d7beaaca1871cc4fadb84c208d0e8cc37;hpb=40b9fcc9381c4456152deb9a448b4e5fd014b7e7;p=pyderasn.git diff --git a/tests/test_pyderasn.py b/tests/test_pyderasn.py index 174abb6..dec37f3 100644 --- a/tests/test_pyderasn.py +++ b/tests/test_pyderasn.py @@ -1,11 +1,10 @@ # coding: utf-8 # PyDERASN -- Python ASN.1 DER/BER codec with abstract structures -# Copyright (C) 2017-2019 Sergey Matveev +# Copyright (C) 2017-2020 Sergey Matveev # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. +# published by the Free Software Foundation, version 3 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -622,6 +621,10 @@ class TestBoolean(CommonMixin, TestCase): 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), @@ -641,6 +644,11 @@ class TestBoolean(CommonMixin, TestCase): 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) + self.assertTrue(obj.bered) self.assertSequenceEqual(tail, junk) repr(obj) list(obj.pps()) @@ -1129,7 +1137,7 @@ def bit_string_values_strategy(draw, schema=None, value_required=False, do_expl= def _value(value_required): if not value_required and draw(booleans()): - return + return None generation_choice = 0 if value_required: generation_choice = draw(sampled_from((1, 2, 3))) @@ -1138,9 +1146,9 @@ def bit_string_values_strategy(draw, schema=None, value_required=False, do_expl= sampled_from(("0", "1")), max_size=len(schema), ))) - elif generation_choice == 2 or draw(booleans()): + if generation_choice == 2 or draw(booleans()): return draw(binary(max_size=len(schema) // 8)) - elif generation_choice == 3 or draw(booleans()): + if generation_choice == 3 or draw(booleans()): return tuple(draw(lists(sampled_from([name for name, _ in schema])))) return None value = _value(value_required) @@ -1584,6 +1592,10 @@ class TestBitString(CommonMixin, TestCase): 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( @@ -1716,6 +1728,10 @@ class TestBitString(CommonMixin, TestCase): 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) @composite @@ -2103,6 +2119,10 @@ class TestOctetString(CommonMixin, TestCase): 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( @@ -2410,6 +2430,7 @@ class TestObjectIdentifier(CommonMixin, TestCase): repr(err.exception) obj = ObjectIdentifier(value) self.assertTrue(obj.ready) + self.assertFalse(obj.ber_encoded) repr(obj) list(obj.pps()) pprint(obj, big_blobs=True, with_decode_path=True) @@ -2720,15 +2741,19 @@ class TestObjectIdentifier(CommonMixin, TestCase): ObjectIdentifier((2, 999, 3)), ) - @given(data_strategy()) - def test_nonnormalized_first_arc(self, d): + def test_nonnormalized_first_arc(self): tampered = ( ObjectIdentifier.tag_default + len_encode(2) + b'\x80' + ObjectIdentifier((1, 0)).encode()[-1:] ) - ObjectIdentifier().decode(tampered, ctx={"bered": True}) + 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) @@ -2740,8 +2765,8 @@ class TestObjectIdentifier(CommonMixin, TestCase): max_size=5, )) dered = ObjectIdentifier((1, 0) + tuple(arcs)).encode() - _, tlen, lv = tag_strip(dered) - _, llen, v = len_decode(lv) + _, _, lv = tag_strip(dered) + _, _, v = len_decode(lv) v_no_first_arc = v[1:] idx_for_tamper = d.draw(integers( min_value=0, @@ -2756,7 +2781,12 @@ class TestObjectIdentifier(CommonMixin, TestCase): len_encode(len(tampered)) + tampered ) - ObjectIdentifier().decode(tampered, ctx={"bered": True}) + 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) @@ -3491,6 +3521,10 @@ class TestVisibleString( 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 +3535,10 @@ class TestVisibleString( 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) class TestGeneralString( @@ -3733,6 +3771,7 @@ class TimeMixin(object): pprint(obj, big_blobs=True, with_decode_path=True) self.assertFalse(obj.expled) obj_encoded = obj.encode() + self.additional_symmetric_check(value, obj_encoded) obj_expled = obj(value, expl=tag_expl) self.assertTrue(obj_expled.expled) repr(obj_expled) @@ -3775,6 +3814,28 @@ class TestGeneralizedTime(TimeMixin, CommonMixin, TestCase): min_datetime = datetime(1900, 1, 1) max_datetime = datetime(9999, 12, 31) + def additional_symmetric_check(self, value, obj_encoded): + if value.microsecond > 0: + self.assertFalse(obj_encoded.endswith(b"0Z")) + + def test_x690_vector_valid(self): + for data in (( + b"19920521000000Z", + b"19920622123421Z", + b"19920722132100.3Z", + )): + GeneralizedTime(data) + + def test_x690_vector_invalid(self): + for data in (( + b"19920520240000Z", + b"19920622123421.0Z", + b"19920722132100.30Z", + )): + with self.assertRaises(DecodeError) as err: + GeneralizedTime(data) + repr(err.exception) + def test_go_vectors_invalid(self): for data in (( b"20100102030405", @@ -3851,6 +3912,11 @@ class TestGeneralizedTime(TimeMixin, CommonMixin, TestCase): junk ) + def test_ns_fractions(self): + GeneralizedTime(b"20010101000000.000001Z") + with assertRaisesRegex(self, DecodeError, "only microsecond fractions"): + GeneralizedTime(b"20010101000000.0000001Z") + class TestUTCTime(TimeMixin, CommonMixin, TestCase): base_klass = UTCTime @@ -3858,6 +3924,26 @@ class TestUTCTime(TimeMixin, CommonMixin, TestCase): min_datetime = datetime(2000, 1, 1) max_datetime = datetime(2049, 12, 31) + def additional_symmetric_check(self, value, obj_encoded): + pass + + def test_x690_vector_valid(self): + for data in (( + b"920521000000Z", + b"920622123421Z", + b"920722132100Z", + )): + UTCTime(data) + + def test_x690_vector_invalid(self): + for data in (( + b"920520240000Z", + b"9207221321Z", + )): + with self.assertRaises(DecodeError) as err: + UTCTime(data) + repr(err.exception) + def test_go_vectors_invalid(self): for data in (( b"a10506234540Z", @@ -4194,6 +4280,10 @@ class TestAny(CommonMixin, TestCase): 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) @@ -4579,15 +4669,13 @@ def seq_values_strategy(draw, seq_klass, do_expl=False): value = None if draw(booleans()): value = seq_klass() - value._value = { - k: v for k, v in draw(dictionaries( - integers(), - one_of( - booleans().map(Boolean), - integers().map(Integer), - ), - )).items() - } + value._value = draw(dictionaries( + integers(), + one_of( + booleans().map(Boolean), + integers().map(Integer), + ), + )) schema = None if draw(booleans()): schema = list(draw(dictionaries( @@ -4606,15 +4694,13 @@ def seq_values_strategy(draw, seq_klass, do_expl=False): default = None if draw(booleans()): default = seq_klass() - default._value = { - k: v for k, v in draw(dictionaries( - integers(), - one_of( - booleans().map(Boolean), - integers().map(Integer), - ), - )).items() - } + default._value = draw(dictionaries( + integers(), + one_of( + booleans().map(Boolean), + integers().map(Integer), + ), + )) optional = draw(one_of(none(), booleans())) _decoded = ( draw(integers(min_value=0)), @@ -5007,6 +5093,9 @@ class SeqMixing(object): 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): @@ -5124,6 +5213,9 @@ class SeqMixing(object): 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) @@ -5152,8 +5244,7 @@ class SeqMixing(object): with self.assertRaises(TagMismatch): seq_missing.decode(seq_encoded) - @given(data_strategy()) - def test_bered(self, d): + def test_bered(self): class Seq(self.base_klass): schema = (("underlying", Boolean()),) encoded = Boolean.tag_default + len_encode(1) + b"\x01" @@ -5162,6 +5253,10 @@ class SeqMixing(object): 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 +5273,10 @@ class SeqMixing(object): 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 TestSequence(SeqMixing, CommonMixin, TestCase): @@ -5274,9 +5373,12 @@ class TestSet(SeqMixing, CommonMixin, TestCase): 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( [bytes(seq_decoded[str(i)]) for i, t in enumerate(tags)], - [t for t in tags], + tags, ) @@ -5699,6 +5801,9 @@ class SeqOfMixing(object): ) 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) @@ -5708,8 +5813,7 @@ class SeqOfMixing(object): with self.assertRaises(DecodeError): obj.decode(obj_encoded_lenindef[:-2], ctx={"bered": True}) - @given(data_strategy()) - def test_bered(self, d): + def test_bered(self): class SeqOf(self.base_klass): schema = Boolean() encoded = Boolean(False).encode() @@ -5721,6 +5825,10 @@ class SeqOfMixing(object): 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 +5846,10 @@ class SeqOfMixing(object): 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 TestSequenceOf(SeqOfMixing, CommonMixin, TestCase): @@ -5803,6 +5915,9 @@ class TestSetOf(SeqOfMixing, CommonMixin, TestCase): 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( [obj.encode() for obj in seq_decoded], values, @@ -6006,7 +6121,10 @@ class TestPP(TestCase): chosen_id = oids[chosen] pp = _pp(asn1_type_name=ObjectIdentifier.asn1_type_name, value=chosen) self.assertNotIn(chosen_id, pp_console_row(pp)) - self.assertIn(chosen_id, pp_console_row(pp, oids=oids)) + self.assertIn( + chosen_id, + pp_console_row(pp, oid_maps=[{'whatever': 'whenever'}, oids]), + ) class TestAutoAddSlots(TestCase): @@ -6308,9 +6426,15 @@ class TestStrictDefaultExistence(TestCase): 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) class TestX690PrefixedType(TestCase):