from hypothesis.strategies import text
from hypothesis.strategies import tuples
from six import assertRaisesRegex
+from six import binary_type
from six import byte2int
from six import indexbytes
from six import int2byte
from pyderasn import DecodeError
from pyderasn import DecodePathDefBy
from pyderasn import Enumerated
+from pyderasn import EOC
+from pyderasn import EOC_LEN
from pyderasn import GeneralizedTime
from pyderasn import GeneralString
from pyderasn import GraphicString
with self.assertRaises(ValueError):
self.base_klass(impl=b"whatever", expl=b"whenever")
- @given(binary(), integers(), integers(), integers())
+ @given(binary(min_size=1), integers(), integers(), integers())
def test_decoded(self, impl, offset, llen, vlen):
obj = self.base_klass(impl=impl, _decoded=(offset, llen, vlen))
self.assertEqual(obj.offset, offset)
self.assertEqual(obj.tlen, len(impl))
self.assertEqual(obj.tlvlen, obj.tlen + obj.llen + obj.vlen)
- @given(binary())
+ @given(binary(min_size=1))
def test_impl_inherited(self, impl_tag):
class Inherited(self.base_klass):
impl = impl_tag
)))
@given(integers(min_value=0 + 1, max_value=255 - 1))
- def test_invalid_value(self, value):
+ def test_ber_value(self, value):
with assertRaisesRegex(self, DecodeError, "unacceptable Boolean value"):
Boolean().decode(b"".join((
Boolean.tag_default,
len_encode(1),
int2byte(value),
)))
+ obj, _ = Boolean().decode(
+ b"".join((
+ Boolean.tag_default,
+ len_encode(1),
+ int2byte(value),
+ )),
+ ctx={"bered": True},
+ )
+ self.assertTrue(bool(obj))
+ self.assertTrue(obj.bered)
+ self.assertFalse(obj.lenindef)
+
+ @given(
+ integers(min_value=1).map(tag_ctxc),
+ lists(
+ booleans(),
+ min_size=1,
+ max_size=5,
+ ),
+ )
+ def test_ber_expl(self, expl, values):
+ encoded = b""
+ for value in values:
+ encoded += (
+ expl +
+ b"\x80" +
+ Boolean(value).encode() +
+ EOC
+ )
+ encoded = SequenceOf.tag_default + len_encode(len(encoded)) + encoded
+
+ class SeqOf(SequenceOf):
+ schema = Boolean(expl=expl)
+ seqof, tail = SeqOf().decode(encoded, ctx={"bered": True})
+ self.assertSequenceEqual(tail, b"")
+ self.assertSequenceEqual([bool(v) for v in seqof], values)
+ self.assertSetEqual(
+ set(
+ (
+ v.tlvlen,
+ v.expl_tlvlen,
+ v.expl_tlen,
+ v.expl_llen,
+ v.bered,
+ v.lenindef,
+ v.expl_lenindef,
+ ) for v in seqof
+ ),
+ set(((
+ 3 + EOC_LEN,
+ len(expl) + 1 + 3 + EOC_LEN,
+ len(expl),
+ 1,
+ False,
+ False,
+ True,
+ ),)),
+ )
@composite
@given(
tuples(integers(min_value=0), binary()),
tuples(integers(min_value=0), binary()),
- binary(),
- binary(),
+ binary(min_size=1),
+ binary(min_size=1),
)
def test_comparison(self, value1, value2, tag1, tag2):
for klass in (BitString, BitStringInherited):
self.assertTrue(obj[9])
self.assertFalse(obj[17])
+ @given(
+ integers(min_value=1, max_value=30),
+ lists(
+ one_of(
+ binary(min_size=1, max_size=5),
+ lists(
+ binary(min_size=1, max_size=5),
+ min_size=1,
+ max_size=3,
+ ),
+ ),
+ min_size=0,
+ max_size=3,
+ ),
+ lists(booleans(), min_size=1),
+ )
+ def test_constructed(self, impl, chunk_inputs, chunk_last_bits):
+ def chunk_constructed(contents):
+ return (
+ tag_encode(form=TagFormConstructed, num=3) +
+ b"\x80" +
+ b"".join(BitString(content).encode() for content in contents) +
+ EOC
+ )
+ chunks = []
+ payload_expected = b""
+ bit_len_expected = 0
+ for chunk_input in chunk_inputs:
+ if isinstance(chunk_input, binary_type):
+ chunks.append(BitString(chunk_input).encode())
+ payload_expected += chunk_input
+ bit_len_expected += len(chunk_input) * 8
+ else:
+ chunks.append(chunk_constructed(chunk_input))
+ payload = b"".join(chunk_input)
+ payload_expected += payload
+ bit_len_expected += len(payload) * 8
+ chunk_last = BitString("'%s'B" % "".join(
+ "1" if bit else "0" for bit in chunk_last_bits
+ ))
+ payload_expected += bytes(chunk_last)
+ bit_len_expected += chunk_last.bit_len
+ encoded_indefinite = (
+ tag_encode(form=TagFormConstructed, num=impl) +
+ b"\x80" +
+ b"".join(chunks) +
+ chunk_last.encode() +
+ EOC
+ )
+ encoded_definite = (
+ tag_encode(form=TagFormConstructed, num=impl) +
+ len_encode(len(b"".join(chunks) + chunk_last.encode())) +
+ b"".join(chunks) +
+ chunk_last.encode()
+ )
+ with assertRaisesRegex(self, DecodeError, "unallowed BER"):
+ BitString(impl=tag_encode(impl)).decode(encoded_indefinite)
+ for lenindef_expected, encoded in (
+ (True, encoded_indefinite),
+ (False, encoded_definite),
+ ):
+ obj, tail = BitString(impl=tag_encode(impl)).decode(
+ encoded, ctx={"bered": True}
+ )
+ self.assertSequenceEqual(tail, b"")
+ self.assertEqual(obj.bit_len, bit_len_expected)
+ self.assertSequenceEqual(bytes(obj), payload_expected)
+ self.assertTrue(obj.bered)
+ self.assertEqual(obj.lenindef, lenindef_expected)
+ self.assertEqual(len(encoded), obj.tlvlen)
+
+ def test_x690_vector(self):
+ vector = BitString("'0A3B5F291CD'H")
+ obj, tail = BitString().decode(hexdec("0307040A3B5F291CD0"))
+ self.assertSequenceEqual(tail, b"")
+ self.assertEqual(obj, vector)
+ obj, tail = BitString().decode(
+ hexdec("23800303000A3B0305045F291CD00000"),
+ ctx={"bered": True},
+ )
+ self.assertSequenceEqual(tail, b"")
+ self.assertEqual(obj, vector)
+ self.assertTrue(obj.bered)
+ self.assertTrue(obj.lenindef)
+
@composite
def octet_string_values_strategy(draw, do_expl=False):
repr(obj)
pprint(obj)
- @given(binary(), binary(), binary(), binary())
+ @given(binary(), binary(), binary(min_size=1), binary(min_size=1))
def test_comparison(self, value1, value2, tag1, tag2):
for klass in (OctetString, OctetStringInherited):
obj1 = klass(value1)
)
self.assertEqual(obj_decoded.expl_offset, offset)
+ @given(
+ integers(min_value=1, max_value=30),
+ lists(
+ one_of(
+ binary(min_size=1, max_size=5),
+ lists(
+ binary(min_size=1, max_size=5),
+ min_size=1,
+ max_size=3,
+ ),
+ ),
+ min_size=1,
+ max_size=3,
+ ),
+ )
+ def test_constructed(self, impl, chunk_inputs):
+ def chunk_constructed(contents):
+ return (
+ tag_encode(form=TagFormConstructed, num=4) +
+ b"\x80" +
+ b"".join(OctetString(content).encode() for content in contents) +
+ EOC
+ )
+ chunks = []
+ payload_expected = b""
+ for chunk_input in chunk_inputs:
+ if isinstance(chunk_input, binary_type):
+ chunks.append(OctetString(chunk_input).encode())
+ payload_expected += chunk_input
+ else:
+ chunks.append(chunk_constructed(chunk_input))
+ payload = b"".join(chunk_input)
+ payload_expected += payload
+ encoded_indefinite = (
+ tag_encode(form=TagFormConstructed, num=impl) +
+ b"\x80" +
+ b"".join(chunks) +
+ EOC
+ )
+ encoded_definite = (
+ tag_encode(form=TagFormConstructed, num=impl) +
+ len_encode(len(b"".join(chunks))) +
+ b"".join(chunks)
+ )
+ with assertRaisesRegex(self, DecodeError, "unallowed BER"):
+ OctetString(impl=tag_encode(impl)).decode(encoded_indefinite)
+ for lenindef_expected, encoded in (
+ (True, encoded_indefinite),
+ (False, encoded_definite),
+ ):
+ obj, tail = OctetString(impl=tag_encode(impl)).decode(
+ encoded, ctx={"bered": True}
+ )
+ self.assertSequenceEqual(tail, b"")
+ self.assertSequenceEqual(bytes(obj), payload_expected)
+ self.assertTrue(obj.bered)
+ self.assertEqual(obj.lenindef, lenindef_expected)
+ self.assertEqual(len(encoded), obj.tlvlen)
+
@composite
def null_values_strategy(draw, do_expl=False):
data,
)))
+ def test_x690_vector(self):
+ self.assertEqual(
+ ObjectIdentifier().decode(hexdec("0603883703"))[0],
+ ObjectIdentifier((2, 999, 3)),
+ )
+
@composite
def enumerated_values_strategy(draw, schema=None, do_expl=False):
def test_comparison(self, d):
value1 = d.draw(text(alphabet=self.text_alphabet()))
value2 = d.draw(text(alphabet=self.text_alphabet()))
- tag1 = d.draw(binary())
- tag2 = d.draw(binary())
+ tag1 = d.draw(binary(min_size=1))
+ tag2 = d.draw(binary(min_size=1))
obj1 = self.base_klass(value1)
obj2 = self.base_klass(value2)
self.assertEqual(obj1 == obj2, value1 == value2)
):
base_klass = VisibleString
+ def test_x690_vector(self):
+ obj, tail = VisibleString().decode(hexdec("1A054A6F6E6573"))
+ self.assertSequenceEqual(tail, b"")
+ self.assertEqual(str(obj), "Jones")
+ self.assertFalse(obj.bered)
+ self.assertFalse(obj.lenindef)
+
+ obj, tail = VisibleString().decode(
+ hexdec("3A0904034A6F6E04026573"),
+ ctx={"bered": True},
+ )
+ self.assertSequenceEqual(tail, b"")
+ self.assertEqual(str(obj), "Jones")
+ self.assertTrue(obj.bered)
+ self.assertFalse(obj.lenindef)
+
+ obj, tail = VisibleString().decode(
+ hexdec("3A8004034A6F6E040265730000"),
+ ctx={"bered": True},
+ )
+ self.assertSequenceEqual(tail, b"")
+ self.assertEqual(str(obj), "Jones")
+ self.assertTrue(obj.bered)
+ self.assertTrue(obj.lenindef)
+
class TestGeneralString(
UnicodeDecodeErrorMixin,
min_value=self.min_datetime,
max_value=self.max_datetime,
))
- tag1 = d.draw(binary())
- tag2 = d.draw(binary())
+ tag1 = d.draw(binary(min_size=1))
+ tag2 = d.draw(binary(min_size=1))
if self.omit_ms:
value1 = value1.replace(microsecond=0)
value2 = value2.replace(microsecond=0)
class SeqMixing(object):
def test_invalid_value_type(self):
with self.assertRaises(InvalidValueType) as err:
- self.base_klass((1, 2, 3))
+ self.base_klass(123)
repr(err.exception)
def test_invalid_value_type_set(self):
seq[missing] = Boolean()
repr(err.exception)
+ def test_x690_vector(self):
+ class Seq(Sequence):
+ schema = (
+ ("name", IA5String()),
+ ("ok", Boolean()),
+ )
+ seq = Seq().decode(hexdec("300A1605536d6974680101FF"))[0]
+ self.assertEqual(seq["name"], "Smith")
+ self.assertEqual(seq["ok"], True)
+
class TestSet(SeqMixing, CommonMixin, TestCase):
base_klass = Set
seq.decode(raw)
with assertRaisesRegex(self, DecodeError, "DEFAULT value met"):
seq.decode(raw, ctx={"strict_default_existence": True})
+
+
+class TestX690PrefixedType(TestCase):
+ def runTest(self):
+ self.assertSequenceEqual(
+ VisibleString("Jones").encode(),
+ hexdec("1A054A6F6E6573"),
+ )
+ self.assertSequenceEqual(
+ VisibleString(
+ "Jones",
+ impl=tag_encode(3, klass=TagClassApplication),
+ ).encode(),
+ hexdec("43054A6F6E6573"),
+ )
+ self.assertSequenceEqual(
+ Any(
+ VisibleString(
+ "Jones",
+ impl=tag_encode(3, klass=TagClassApplication),
+ ),
+ expl=tag_ctxc(2),
+ ).encode(),
+ hexdec("A20743054A6F6E6573"),
+ )
+ self.assertSequenceEqual(
+ OctetString(
+ VisibleString(
+ "Jones",
+ impl=tag_encode(3, klass=TagClassApplication),
+ ).encode(),
+ impl=tag_encode(7, form=TagFormConstructed, klass=TagClassApplication),
+ ).encode(),
+ hexdec("670743054A6F6E6573"),
+ )
+ self.assertSequenceEqual(
+ VisibleString("Jones", impl=tag_ctxp(2)).encode(),
+ hexdec("82054A6F6E6573"),
+ )