def test_named_struct(self): '4.7. Cryptographic Attributes' expected = { 'name': Symbol('UserType'), 'cryptographic_attribute': CryptographicAttribute('stream-ciphered'), 'fields': [ {'name': Symbol('field1'), 'type': Type('uint8')}, {'name': Symbol('field2'), 'type': Type('uint8')}, { 'cryptographic_attribute': CryptographicAttribute('digitally-signed'), 'fields': [ {'name': Symbol('field3'), 'vector_bounds': {'floor': Int('0'), 'ceiling': Int('255')}, 'vector_type': Type('uint8')}, {'name': Symbol('field4'), 'type': Type('uint8')}, ] } ] } code = ''' stream-ciphered struct { uint8 field1; uint8 field2; digitally-signed struct { uint8 field3<0..255>; uint8 field4; }; } UserType; ''' # TODO was 'digitally-signed opaque' but is probably an erratum and # should be 'digitally-signed struct' self.assert_parse_equal(code, expected, NamedStructure)
def test_named_struct(self): '4.6. Constructed Types' expected = { 'name': Symbol('T'), 'fields': [ { 'name': Symbol('f1'), 'type': Type('T1') }, { 'name': Symbol('f2'), 'type': Type('T2') }, { 'name': Symbol('fn'), 'type': Type('Tn') }, ] } code = '''struct { T1 f1; T2 f2; Tn fn; } T;''' self.assert_parse_equal(code, expected)
def test_variant_empty_struct(self): '4.6.1. Variants' expected = { 'name': Symbol('VariantRecord'), 'fields': [], 'structure_variant': { 'name': Symbol('variant_body'), 'variant_type': Type('VariantTag'), 'variant_cases': [ { 'cases': [Symbol('apple')], 'type': Type('V1') }, { 'cases': [Symbol('orange'), Symbol('banana')], 'type': Type('V2') }, ] } } code = '''struct { select (VariantTag) { case apple: V1; case orange: case banana: V2; } variant_body; } VariantRecord;''' self.assert_parse_equal(code, expected)
def test_internal_enum(self): 'Section 4.5. Enumerateds' expected = { 'name': Symbol('Amount'), 'enum_entries': [{ 'name': Symbol('low') }, { 'name': Symbol('medium') }, { 'name': Symbol('high') }], } code = 'enum { low, medium, high } Amount;' self.assert_parse_equal(code, expected)
def test_constant_uint8_vector(self): expected = { 'name': Symbol('Data'), 'vector_size': Int('9'), 'vector_type': Type('uint8') } code = 'uint8 Data[9];' self.assert_parse_equal(code, expected)
def test_constant_opaque_vector(self): '''Section 4.3 Vectors''' expected = { 'name': Symbol('Datum'), 'vector_size': Int('3'), 'vector_type': Type('opaque') } code = 'opaque Datum[3];' self.assert_parse_equal(code, expected)
def test_constant_custom_type_vector(self): '''Section 4.3 Vectors (see errata)''' expected = { 'name': Symbol('Data'), 'vector_size': Int('3'), 'vector_type': Type('Datum') } code = 'Datum Data[3];' self.assert_parse_equal(code, expected)
def test_external_enum_without_width(self): 'Section 4.5. Enumerateds' expected = { 'name': Symbol('Color'), 'enum_entries': [{ 'name': Symbol('red'), 'value': Int('3') }, { 'name': Symbol('blue'), 'value': Int('5') }, { 'name': Symbol('white'), 'value': Int('7') }], } code = 'enum { red(3), blue(5), white(7) } Color;' self.assert_parse_equal(code, expected)
def test_external_enum_with_width(self): 'Section 4.5. Enumerateds' expected = { 'name': Symbol('Taste'), 'enum_entries': [{ 'name': Symbol('sweet'), 'value': Int('1') }, { 'name': Symbol('sour'), 'value': Int('2') }, { 'name': Symbol('bitter'), 'value': Int('4') }], 'enum_width': Int('32000'), } code = 'enum { sweet(1), sour(2), bitter(4), (32000) } Taste;' self.assert_parse_equal(code, expected)
def test_variable_uint8_vector(self): expected = { 'name': Symbol('Data'), 'vector_type': Type('uint8'), 'vector_bounds': { 'floor': Int('3'), 'ceiling': Int('10'), }, } code = 'uint8 Data<3..10>;' self.assert_parse_equal(code, expected)
def test_variable_int16_vector(self): 'Section 4.3. Vectors' expected = { 'name': Symbol('longer'), 'vector_type': Type('uint16'), 'vector_bounds': { 'floor': Int('0'), 'ceiling': Int('800'), }, } code = 'uint16 longer<0..800>;' self.assert_parse_equal(code, expected)
def test_variable_opaque_vector(self): 'Section 4.3. Vectors' expected = { 'name': Symbol('mandatory'), 'vector_type': Type('opaque'), 'vector_bounds': { 'floor': Int('300'), 'ceiling': Int('400'), }, } code = 'opaque mandatory<300..400>;' self.assert_parse_equal(code, expected)
def test_constant_ints_vector(self): ''' Section 4.4. Numbers uint8 uint16[2]; uint8 uint24[3]; uint8 uint32[4]; uint8 uint64[8]; ''' for i, name in zip([2,3,4,8], ['uint16', 'uint24', 'uint32', 'uint64']): expected = { 'name': Symbol(name), 'vector_size': Int(str(i)), 'vector_type': Type('uint8') } code = 'uint8 {}[{}];'.format(name, i) self.assert_parse_equal(code, expected)
def test_variant_struct(self): '7.4. Handshake Protocol' expected = { 'name': Symbol('Handshake'), 'fields': [{ 'name': 'msg_type', 'type': 'HandshakeType', }, { 'name': 'length', 'type': 'uint24', }], 'structure_variant': { 'name': Symbol('body'), 'variant_type': Type('HandshakeType'), 'variant_cases': [ { 'cases': [Symbol('hello_request')], 'type': Type('HelloRequest'), }, { 'cases': [Symbol('client_hello')], 'type': Type('ClientHello'), }, { 'cases': [Symbol('server_hello')], 'type': Type('ServerHello'), }, { 'cases': [Symbol('certificate')], 'type': Type('Certificate'), }, { 'cases': [Symbol('server_key_exchange')], 'type': Type('ServerKeyExchange'), }, { 'cases': [Symbol('certificate_request')], 'type': Type('CertificateRequest'), }, { 'cases': [Symbol('server_hello_done')], 'type': Type('ServerHelloDone'), }, { 'cases': [Symbol('certificate_verify')], 'type': Type('CertificateVerify'), }, { 'cases': [Symbol('client_key_exchange')], 'type': Type('ClientKeyExchange'), }, { 'cases': [Symbol('finished')], 'type': Type('Finished'), }, ] } } code = ''' struct { HandshakeType msg_type; uint24 length; select (HandshakeType) { case hello_request: HelloRequest; case client_hello: ClientHello; case server_hello: ServerHello; case certificate: Certificate; case server_key_exchange: ServerKeyExchange; case certificate_request: CertificateRequest; case server_hello_done: ServerHelloDone; case certificate_verify: CertificateVerify; case client_key_exchange: ClientKeyExchange; case finished: Finished; } body; } Handshake; ''' self.assert_parse_equal(code, expected)