def create_array_message() -> Message: length_type = ModularInteger("Arrays.Length", Pow(Number(2), Number(8))) modular_type = ModularInteger("Arrays.Modular_Integer", Pow(Number(2), Number(16))) modular_vector_type = Array("Arrays.Modular_Vector", modular_type) range_type = RangeInteger("Arrays.Range_Integer", Number(1), Number(100), Number(8)) range_vector_type = Array("Arrays.Range_Vector", range_type) enum_type = Enumeration( "Arrays.Enumeration", { "ZERO": Number(0), "ONE": Number(1), "TWO": Number(2) }, Number(8), False, ) enum_vector_type = Array("Arrays.Enumeration_Vector", enum_type) av_enum_type = Enumeration( "Arrays.AV_Enumeration", { "AV_ZERO": Number(0), "AV_ONE": Number(1), "AV_TWO": Number(2) }, Number(8), True, ) av_enum_vector_type = Array("Arrays.AV_Enumeration_Vector", av_enum_type) structure = [ Link(INITIAL, Field("Length")), Link(Field("Length"), Field("Modular_Vector"), length=Mul(Variable("Length"), Number(8))), Link(Field("Modular_Vector"), Field("Range_Vector"), length=Number(16)), Link(Field("Range_Vector"), Field("Enumeration_Vector"), length=Number(16)), Link(Field("Enumeration_Vector"), Field("AV_Enumeration_Vector"), length=Number(16)), Link(Field("AV_Enumeration_Vector"), FINAL), ] types = { Field("Length"): length_type, Field("Modular_Vector"): modular_vector_type, Field("Range_Vector"): range_vector_type, Field("Enumeration_Vector"): enum_vector_type, Field("AV_Enumeration_Vector"): av_enum_vector_type, } return Message("Arrays.Message", structure, types)
def test_pow_simplified(self) -> None: self.assertEqual(Pow(Variable("X"), Number(1)).simplified(), Pow(Variable("X"), Number(1))) self.assertEqual( Pow(Variable("X"), Add(Number(1), Number(1))).simplified(), Pow(Variable("X"), Number(2)), ) self.assertEqual(Pow(Number(6), Number(2)).simplified(), Number(36))
def test_dot_graph(tmp_path: Path) -> None: f_type = ModularInteger("P::T", Pow(Number(2), Number(32))) m = Message( "P::M", structure=[Link(INITIAL, Field("X")), Link(Field("X"), FINAL)], types={Field("X"): f_type}, ) expected = """ digraph "P::M" { graph [bgcolor="#00000000", pad="0.1", ranksep="0.1 equally", splines=true, truecolor=true]; edge [color="#6f6f6f", fontcolor="#6f6f6f", fontname="Fira Code", penwidth="2.5"]; node [color="#6f6f6f", fillcolor="#009641", fontcolor="#ffffff", fontname=Arimo, shape=box, style="rounded,filled", width="1.5"]; Initial [fillcolor="#ffffff", label="", shape=circle, width="0.5"]; X; intermediate_0 [color="#6f6f6f", fontcolor="#6f6f6f", fontname="Fira Code", height=0, label="(⊤, 32, ⋆)", penwidth=0, style="", width=0]; Initial -> intermediate_0 [arrowhead=none]; intermediate_0 -> X [minlen=1]; intermediate_1 [color="#6f6f6f", fontcolor="#6f6f6f", fontname="Fira Code", height=0, label="(⊤, 0, ⋆)", penwidth=0, style="", width=0]; X -> intermediate_1 [arrowhead=none]; intermediate_1 -> Final [minlen=1]; Final [fillcolor="#6f6f6f", label="", shape=circle, width="0.5"]; } """ assert_graph(create_message_graph(m), expected, tmp_path)
def test_graph_object() -> None: f_type = ModularInteger("P::T", Pow(Number(2), Number(32))) m = Message( "P::M", structure=[Link(INITIAL, Field("X")), Link(Field("X"), FINAL)], types={Field("X"): f_type}, ) g = create_message_graph(m) assert [(e.get_source(), e.get_destination()) for e in g.get_edges()] == [ ("Initial", "intermediate_0"), ("intermediate_0", "X"), ("X", "intermediate_1"), ("intermediate_1", "Final"), ] assert [n.get_name() for n in g.get_nodes()] == [ "graph", "edge", "node", "Initial", "X", "intermediate_0", "intermediate_1", "Final", ]
def test_field_coverage_2(self) -> None: foo_type = ModularInteger("P.Foo", Pow(Number(2), Number(32))) structure = [ Link(INITIAL, Field("F1")), Link(Field("F1"), Field("F2")), Link(Field("F2"), Field("F4"), Greater(Variable("F1"), Number(100))), Link( Field("F2"), Field("F3"), LessEqual(Variable("F1"), Number(100)), first=Add(Last("F2"), Number(64)), ), Link(Field("F3"), Field("F4")), Link(Field("F4"), FINAL), ] types = { Field("F1"): foo_type, Field("F2"): foo_type, Field("F3"): foo_type, Field("F4"): foo_type, } with mock.patch("rflx.model.Message._Message__verify_conditions", lambda x: None): with self.assertRaisesRegex( ModelError, "^path F1 -> F2 -> F3 -> F4 does not cover whole message"): Message("P.M", structure, types)
def test_range_size(self) -> None: self.assertEqual(RangeInteger('UINT32', Number(0), Sub(Pow(Number(2), Number(32)), Number(1)), Number(32) ).size, Number(32))
def parse_mathematical_expression(string: str, location: int, tokens: ParseResults) -> Expr: result: List[Expr] = tokens[0] while len(result) > 1: left = result.pop(0) operator = result.pop(0) right = result.pop(0) assert left.location, f'expression "{left}" without location' assert right.location, f'expression "{right}" without location' assert left.location.source == right.location.source, "expression with different source" locn = Location(left.location.start, left.location.source, left.location.end) expression: Expr if operator == "+": expression = Add(left, right) expression.location = locn elif operator == "-": expression = Sub(left, right, locn) elif operator == "*": expression = Mul(left, right) expression.location = locn elif operator == "/": expression = Div(left, right, locn) elif operator == "**": expression = Pow(left, right, locn) else: raise ParseFatalException(string, location, "unexpected mathematical operator") result.insert(0, expression) return result[0]
def test_message_unsupported_expression() -> None: x = Field("X") structure = [ Link(INITIAL, x), Link( x, FINAL, condition=LessEqual( Pow( Number(2), Add(Variable("X", location=Location((10, 23))), Number(1)), location=Location((10, 19)), ), Number(1024), ), ), ] types = {x: MODULAR_INTEGER} assert_message_model_error( structure, types, '^<stdin>:10:19: model: error: unsupported expression in "P.M"\n' '<stdin>:10:23: model: info: variable "X" in exponent', )
def test_range_size() -> None: assert_equal( RangeInteger("P.T", Number(0), Sub(Pow(Number(2), Number(32)), Number(1)), Number(32)).size, Number(32), )
def create_tlv_message() -> Message: tag_type = Enumeration("TLV.Tag", { "Msg_Data": Number(1), "Msg_Error": Number(3) }, Number(2), False) length_type = ModularInteger("TLV.Length", Pow(Number(2), Number(14))) structure = [ Link(INITIAL, Field("Tag")), Link(Field("Tag"), Field("Length"), Equal(Variable("Tag"), Variable("Msg_Data"))), Link(Field("Tag"), FINAL, Equal(Variable("Tag"), Variable("Msg_Error"))), Link(Field("Length"), Field("Value"), length=Mul(Variable("Length"), Number(8))), Link(Field("Value"), FINAL), ] types = { Field("Tag"): tag_type, Field("Length"): length_type, Field("Value"): Payload() } return Message("TLV.Message", structure, types)
def test_mathematical_expression_precedence() -> None: assert_equal( grammar.mathematical_expression().parseString("A - B * 2**3 - 1")[0], Sub(Sub(Variable("A"), Mul(Variable("B"), Pow(Number(2), Number(3)))), Number(1)), ) assert_equal( grammar.mathematical_expression().parseString("(A - B) * 2**3 - 1")[0], Sub(Mul(Sub(Variable("A"), Variable("B")), Pow(Number(2), Number(3))), Number(1)), ) assert_equal( grammar.mathematical_expression().parseString("A - B * 2**(3 - 1)")[0], Sub(Variable("A"), Mul(Variable("B"), Pow(Number(2), Sub(Number(3), Number(1))))), ) assert_equal( grammar.mathematical_expression().parseString("A - (B * 2)**3 - 1")[0], Sub(Sub(Variable("A"), Pow(Mul(Variable("B"), Number(2)), Number(3))), Number(1)), ) assert_equal( grammar.mathematical_expression().parseString("A - (B * 2**3 - 1)")[0], Sub(Variable("A"), Sub(Mul(Variable("B"), Pow(Number(2), Number(3))), Number(1))), )
def create_array_inner_message() -> Message: length_type = ModularInteger("Arrays.Length", Pow(Number(2), Number(8))) structure = [ Link(INITIAL, Field("Length")), Link(Field("Length"), Field("Payload"), length=Mul(Variable("Length"), Number(8))), Link(Field("Payload"), FINAL), ] types = {Field("Length"): length_type, Field("Payload"): Payload()} return Message("Arrays.Inner_Message", structure, types)
def test_subsequent_variable(self) -> None: t = ModularInteger("P.T", Pow(Number(2), Number(32))) structure = [ Link(INITIAL, Field("F1")), Link(Field("F1"), Field("F2"), Equal(Variable("F2"), Number(42))), Link(Field("F2"), FINAL), ] types = {Field("F1"): t, Field("F2"): t} with self.assertRaisesRegex( ModelError, '^subsequent field "F2" referenced in ' + 'condition 0 from field "F1" to "F2"', ): Message("P.M", structure, types)
def create_ethernet_pdu() -> PDU: uint48 = ModularInteger('UINT48', Pow(Number(2), Number(48))) uint16 = RangeInteger('UINT16', Number(0), Sub(Pow(Number(2), Number(16)), Number(1)), Number(16)) payload_array = Array('Payload_Array') initial = InitialNode() destination = Node('Destination', uint48) source = Node('Source', uint48) tpid = Node('TPID', uint16) tci = Node('TCI', uint16) ether_type = Node('EtherType', uint16) payload = Node('Payload', payload_array) initial.edges = [Edge(destination)] destination.edges = [Edge(source)] source.edges = [Edge(tpid)] tpid.edges = [Edge(tci, Equal(Value('TPID'), Number(0x8100))), Edge(ether_type, NotEqual(Value('TPID'), Number(0x8100)), first=First('TPID'))] tci.edges = [Edge(ether_type)] ether_type.edges = [Edge(payload, LessEqual(Value('EtherType'), Number(1500)), Mul(LengthValue('EtherType'), Number(8))), Edge(payload, GreaterEqual(Value('EtherType'), Number(1536)), Sub(Last('Message'), Last('EtherType')))] payload.edges = [Edge(FINAL, And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)), LessEqual(Div(Length('Payload'), Number(8)), Number(1500))))] return PDU('Ethernet.Frame', initial)
def test_nonexistent_variable(self) -> None: mod_type = ModularInteger("P.MT", Pow(Number(2), Number(32))) enum_type = Enumeration("P.ET", {"Val1": Number(0), "Val2": Number(1)}, Number(8), True) structure = [ Link(INITIAL, Field("F1")), Link(Field("F1"), Field("F2"), Equal(Variable("F1"), Variable("Val3"))), Link(Field("F2"), FINAL), ] types = {Field("F1"): enum_type, Field("F2"): mod_type} with self.assertRaisesRegex( ModelError, '^undefined variable "Val3" referenced in ' + 'condition 0 from field "F1" to "F2"', ): Message("P.M", structure, types)
def test_array_unsupported_element_type() -> None: assert_type_error( Array( "P.A", ModularInteger("P.B", Pow(Number(2), Number(4)), Location((3, 4))), Location((5, 4)), ), r'^<stdin>:5:4: model: error: unsupported element type size of array "A"\n' r'<stdin>:3:4: model: info: type "B" has size 4, must be multiple of 8$', ) assert_type_error( Array("P.A", BOOLEAN, Location((5, 4))), r'^<stdin>:5:4: model: error: unsupported element type size of array "A"\n' r'__BUILTINS__:0:0: model: info: type "Boolean" has size 1, must be multiple of 8$', )
def test_message_subsequent_variable() -> None: f1 = Field("F1") f2 = Field("F2") t = ModularInteger("P.T", Pow(Number(2), Number(32))) structure = [ Link(INITIAL, f1), Link(f1, f2, Equal(Variable("F2", location=Location((1024, 57))), Number(42))), Link(f2, FINAL), ] types = {Field("F1"): t, Field("F2"): t} assert_message_model_error( structure, types, '^<stdin>:1024:57: model: error: subsequent field "F2" referenced', )
def test_message_in_message() -> None: length = ModularInteger("Message_In_Message.Length", Pow(Number(2), Number(16))) length_value = Message( "Message_In_Message.Length_Value", [ Link(INITIAL, Field("Length")), Link(Field("Length"), Field("Value"), length=Mul(Number(8), Variable("Length"))), Link(Field("Value"), FINAL), ], {Field("Length"): length, Field("Value"): Opaque()}, ) derived_length_value = DerivedMessage("Message_In_Message.Derived_Length_Value", length_value) message = Message( "Message_In_Message.Message", [ Link(INITIAL, Field("Foo_Length")), Link(Field("Foo_Value"), Field("Bar_Length")), Link(Field("Bar_Value"), FINAL), Link( Field("Foo_Length"), Field("Foo_Value"), length=Mul(Variable("Foo_Length"), Number(8)), ), Link( Field("Bar_Length"), Field("Bar_Value"), length=Mul(Variable("Bar_Length"), Number(8)), ), ], { Field("Foo_Length"): length, Field("Foo_Value"): Opaque(), Field("Bar_Length"): length, Field("Bar_Value"): Opaque(), }, ) derived_message = DerivedMessage("Message_In_Message.Derived_Message", message) assert_messages_files( [f"{TESTDIR}/message_in_message.rflx"], [length_value, derived_length_value, message, derived_message], )
def create_array_messages_message() -> Message: structure = [ Link(INITIAL, Field("Length")), Link(Field("Length"), Field("Messages"), length=Mul(Variable("Length"), Number(8))), Link(Field("Messages"), FINAL), ] types = { Field("Length"): ModularInteger("Arrays.Length", Pow(Number(2), Number(8))), Field("Messages"): Array("Arrays.Inner_Messages", Reference("Arrays.Inner_Message")), } return Message("Arrays.Messages_Message", structure, types)
def test_field_after_message_start(self) -> None: foo_type = ModularInteger("P.Foo", Pow(Number(2), Number(32))) structure = [ Link(INITIAL, Field("F1")), Link(Field("F1"), Field("F2"), first=Sub(First("Message"), Number(1000))), Link(Field("F2"), FINAL), ] types = {Field("F1"): foo_type, Field("F2"): foo_type} with mock.patch("rflx.model.Message._Message__verify_conditions", lambda x: None): with self.assertRaisesRegex( ModelError, '^start of field "F2" on path F1 -> F2 before' " message start"): Message("P.M", structure, types)
def enumeration_types(enum: Enumeration) -> List[TypeDeclaration]: types: List[TypeDeclaration] = [] types.append(ModularType(enum.base_name, Pow(Number(2), enum.size))) types.append( EnumerationType(enum.enum_name if enum.always_valid else enum.name, enum.literals, enum.size)) if enum.always_valid: types.append( VariantRecordType( enum.name, Discriminant('Known', 'Boolean', 'False'), [ VariantItem('True', [ComponentItem('Enum', enum.enum_name)]), VariantItem('False', [ComponentItem('Raw', enum.base_name)]) ])) return types
def test_message_nonexistent_variable() -> None: mod_type = ModularInteger("P.MT", Pow(Number(2), Number(32))) enum_type = Enumeration("P.ET", [("Val1", Number(0)), ("Val2", Number(1))], Number(8), True) structure = [ Link(INITIAL, Field("F1")), Link( Field("F1"), Field("F2"), Equal(Variable("F1"), Variable("Val3", location=Location((444, 55)))), ), Link(Field("F2"), FINAL), ] types = {Field("F1"): enum_type, Field("F2"): mod_type} assert_message_model_error( structure, types, '^<stdin>:444:55: model: error: undefined variable "Val3" referenced$', )
def parse_mathematical_expression(string: str, location: int, tokens: ParseResults) -> Expr: result: List[Expr] = tokens[0] while len(result) > 1: left = result.pop(0) operator = result.pop(0) right = result.pop(0) expression: Expr if operator == "+": expression = Add(left, right) elif operator == "-": expression = Sub(left, right) elif operator == "*": expression = Mul(left, right) elif operator == "/": expression = Div(left, right) elif operator == "**": expression = Pow(left, right) else: raise ParseFatalException(string, location, "unexpected mathematical operator") result.insert(0, expression) return result[0]
def parse_mathematical_expression(string: str, location: int, tokens: list) -> MathExpr: result: List[MathExpr] = tokens[0] while len(result) > 1: left = result.pop(0) operator = result.pop(0) right = result.pop(0) expression: MathExpr if operator == '+': expression = Add(left, right) elif operator == '-': expression = Sub(left, right) elif operator == '*': expression = Mul(left, right) elif operator == '/': expression = Div(left, right) elif operator == '**': expression = Pow(left, right) else: raise ParseFatalException(string, location, 'unexpected mathematical operator') result.insert(0, expression) return result[0]
def test_modular_invalid_modulus_limit(self) -> None: with self.assertRaises(ModelError): ModularInteger('X', Pow(Number(2), Number(128)))
def test_modular_invalid_modulus_variable(self) -> None: with self.assertRaises(ModelError): ModularInteger('X', Pow(Number(2), Value('X')))
def test_pdu_fields_ethernet(self) -> None: expected = OrderedDict([ ('Destination', Field('Destination', ModularInteger('UINT48', Pow(Number(2), Number(48))), TRUE, { '0': Variant( [], TRUE, { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47) }) })), ('Source', Field('Source', ModularInteger('UINT48', Pow(Number(2), Number(48))), TRUE, { '00': Variant( [ ('Destination', '0') ], TRUE, { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95) }) })), ('TPID', Field('TPID', RangeInteger('UINT16', Number(0), Sub(Pow(Number(2), Number(16)), Number(1)), Number(16)), Or(NotEqual(Value('TPID'), Number(0x8100)), Equal(Value('TPID'), Number(0x8100))), { '000': Variant( [ ('Destination', '0'), ('Source', '00') ], TRUE, { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111) }) })), ('TCI', Field('TCI', RangeInteger('UINT16', Number(0), Sub(Pow(Number(2), Number(16)), Number(1)), Number(16)), TRUE, { '0000': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000') ], Equal(Value('TPID'), Number(0x8100)), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('TCI'): Number(16), First('TCI'): Number(112), Last('TCI'): Number(127) }) })), ('EtherType', Field('EtherType', RangeInteger('UINT16', Number(0), Sub(Pow(Number(2), Number(16)), Number(1)), Number(16)), Or(GreaterEqual(Value('EtherType'), Number(1536)), LessEqual(Value('EtherType'), Number(1500))), { '00000': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('TCI', '0000') ], TRUE, { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('TCI'): Number(16), First('TCI'): Number(112), Last('TCI'): Number(127), Length('EtherType'): Number(16), First('EtherType'): Number(128), Last('EtherType'): Number(143) }), '0001': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000') ], NotEqual(Value('TPID'), Number(0x8100)), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('EtherType'): Number(16), First('EtherType'): Number(96), Last('EtherType'): Number(111) }) })), ('Payload', Field('Payload', Array('Payload_Array'), And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)), LessEqual(Div(Length('Payload'), Number(8)), Number(1500))), { '000000': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('TCI', '0000'), ('EtherType', '00000') ], LessEqual(Value('EtherType'), Number(1500)), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('TCI'): Number(16), First('TCI'): Number(112), Last('TCI'): Number(127), Length('EtherType'): Number(16), First('EtherType'): Number(128), Last('EtherType'): Number(143), Length('Payload'): Mul(LengthValue('EtherType'), Number(8)), First('Payload'): Number(144), Last('Payload'): Add(Mul(LengthValue('EtherType'), Number(8)), Number(143)) }), '000001': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('TCI', '0000'), ('EtherType', '00000') ], GreaterEqual(Value('EtherType'), Number(1536)), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('TCI'): Number(16), First('TCI'): Number(112), Last('TCI'): Number(127), Length('EtherType'): Number(16), First('EtherType'): Number(128), Last('EtherType'): Number(143), Length('Payload'): Add(Last('Message'), Number(-143)), First('Payload'): Number(144), Last('Payload'): Last('Message') }), '00010': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('EtherType', '0001') ], LessEqual(Value('EtherType'), Number(1500)), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('EtherType'): Number(16), First('EtherType'): Number(96), Last('EtherType'): Number(111), Length('Payload'): Mul(LengthValue('EtherType'), Number(8)), First('Payload'): Number(112), Last('Payload'): Add(Mul(LengthValue('EtherType'), Number(8)), Number(111)) }), '00011': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('EtherType', '0001') ], GreaterEqual(Value('EtherType'), Number(1536)), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('EtherType'): Number(16), First('EtherType'): Number(96), Last('EtherType'): Number(111), Length('Payload'): Add(Last('Message'), Number(-111)), First('Payload'): Number(112), Last('Payload'): Last('Message') }) })), ('FINAL', Field('FINAL', Null(), TRUE, { '0000000': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('TCI', '0000'), ('EtherType', '00000'), ('Payload', '000000') ], And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)), LessEqual(Div(Length('Payload'), Number(8)), Number(1500))), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('TCI'): Number(16), First('TCI'): Number(112), Last('TCI'): Number(127), Length('EtherType'): Number(16), First('EtherType'): Number(128), Last('EtherType'): Number(143), Length('Payload'): Mul(LengthValue('EtherType'), Number(8)), First('Payload'): Number(144), Last('Payload'): Add(Mul(LengthValue('EtherType'), Number(8)), Number(143)) }), '0000010': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('TCI', '0000'), ('EtherType', '00000'), ('Payload', '000001') ], And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)), LessEqual(Div(Length('Payload'), Number(8)), Number(1500))), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('TCI'): Number(16), First('TCI'): Number(112), Last('TCI'): Number(127), Length('EtherType'): Number(16), First('EtherType'): Number(128), Last('EtherType'): Number(143), Length('Payload'): Add(Last('Message'), Number(-143)), First('Payload'): Number(144), Last('Payload'): Last('Message') }), '000100': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('EtherType', '0001'), ('Payload', '00010') ], And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)), LessEqual(Div(Length('Payload'), Number(8)), Number(1500))), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('EtherType'): Number(16), First('EtherType'): Number(96), Last('EtherType'): Number(111), Length('Payload'): Mul(LengthValue('EtherType'), Number(8)), First('Payload'): Number(112), Last('Payload'): Add(Mul(LengthValue('EtherType'), Number(8)), Number(111)) }), '000110': Variant( [ ('Destination', '0'), ('Source', '00'), ('TPID', '000'), ('EtherType', '0001'), ('Payload', '00011') ], And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)), LessEqual(Div(Length('Payload'), Number(8)), Number(1500))), { Length('Destination'): Number(48), First('Destination'): Number(0), Last('Destination'): Number(47), Length('Source'): Number(48), First('Source'): Number(48), Last('Source'): Number(95), Length('TPID'): Number(16), First('TPID'): Number(96), Last('TPID'): Number(111), Length('EtherType'): Number(16), First('EtherType'): Number(96), Last('EtherType'): Number(111), Length('Payload'): Add(Last('Message'), Number(-111)), First('Payload'): Number(112), Last('Payload'): Last('Message') }) })) ]) self.assertEqual(ETHERNET_PDU.fields(), expected)
def test_modular_size(self) -> None: self.assertEqual(ModularInteger('UINT64', Pow(Number(2), Number(64))).size, Number(64))
RangeInteger, Refinement, Sequence, Session, State, Transition, UnprovenMessage, ) NULL_MESSAGE = Message("Null::Message", [], {}, skip_proof=True) NULL_MODEL = Model([NULL_MESSAGE]) TLV_TAG = Enumeration( "TLV::Tag", [("Msg_Data", Number(1)), ("Msg_Error", Number(3))], Number(8), always_valid=False ) TLV_LENGTH = ModularInteger("TLV::Length", Pow(Number(2), Number(16))) TLV_MESSAGE = Message( "TLV::Message", [ Link(INITIAL, Field("Tag")), Link(Field("Tag"), Field("Length"), Equal(Variable("Tag"), Variable("Msg_Data"))), Link(Field("Tag"), FINAL, Equal(Variable("Tag"), Variable("Msg_Error"))), Link(Field("Length"), Field("Value"), size=Mul(Variable("Length"), Number(8))), Link(Field("Value"), FINAL), ], {Field("Tag"): TLV_TAG, Field("Length"): TLV_LENGTH, Field("Value"): OPAQUE}, skip_proof=True, ) TLV_MODEL = Model([TLV_TAG, TLV_LENGTH, TLV_MESSAGE]) TLV_MESSAGES = Sequence("TLV::Messages", TLV_MESSAGE)
def test_pow() -> None: assert Pow(Number(6), Number(2)).z3expr() == z3.IntVal(6) ** z3.IntVal(2)