def test_div_simplified(self) -> None: self.assertEqual( Div(Value('X'), Number(1)).simplified(), Div(Value('X'), Number(1))) self.assertEqual(Div(Number(6), Number(2)).simplified(), Number(3)) self.assertEqual( Div(Number(9), Number(2)).simplified(), Div(Number(9), Number(2)))
def test_mul_simplified(self) -> None: self.assertEqual( Mul(Value('X'), Number(2)).simplified(), Mul(Value('X'), Number(2))) self.assertEqual(Mul(Value('X'), Number(1)).simplified(), Value('X')) self.assertEqual( Mul(Number(2), Number(3), Number(5)).simplified(), Number(30))
def __init__(self, name: str, first: MathExpr, last: MathExpr, size: MathExpr) -> None: first_num = first.simplified() if not isinstance(first_num, Number): raise ModelError(f'first of "{name}" contains variable') last_num = last.simplified() if not isinstance(last_num, Number): raise ModelError(f'last of "{name}" contains variable') if first_num < Number(0): raise ModelError(f'first of "{name}" negative') if first_num > last_num: raise ModelError(f'range of "{name}" negative') size_num = size.simplified() if not isinstance(size_num, Number): raise ModelError(f'size of "{name}" contains variable') if log(int(last_num) + 1) / log(2) > int(size_num): raise ModelError(f'size for "{name}" too small') super().__init__(name) self.__first = first self.__last = last self.__size = size constraints: LogExpr = TRUE if self.first.simplified() != self.base_first.simplified(): constraints = GreaterEqual(Value(self.name), self.first) if self.last.simplified() != self.base_last.simplified(): constraints = And(constraints, LessEqual(Value(self.name), self.last)) self.__constraints = constraints.simplified()
def field_accessor_functions(field: Field, package_name: str) -> List[Subprogram]: precondition = Precondition( And(COMMON_PRECONDITION, LogCall(f'Valid_{field.name} (Buffer)'))) functions: List[Subprogram] = [] if isinstance(field.type, Array): for attribute in ['First', 'Last']: functions.append( ExpressionFunction( f'Get_{field.name}_{attribute}', 'Types.Index_Type', [('Buffer', 'Types.Bytes')], IfExpression([( LogCall(f'Valid_{field.name}_{variant_id} (Buffer)'), LogCall( f'Get_{field.name}_{variant_id}_{attribute} (Buffer)' )) for variant_id in field.variants], 'Unreachable_Types_Index_Type'), [precondition])) body: List[Statement] = [ Assignment('First', MathCall(f'Get_{field.name}_First (Buffer)')), Assignment('Last', MathCall(f'Get_{field.name}_Last (Buffer)')) ] postcondition = Postcondition( And( Equal(Value('First'), MathCall(f'Get_{field.name}_First (Buffer)')), Equal(Value('Last'), MathCall(f'Get_{field.name}_Last (Buffer)')))) if 'Payload' not in field.type.name: predicate = f'{package_name}.{field.type.name}.Is_Contained (Buffer (First .. Last))' body.append(PragmaStatement('Assume', [predicate])) postcondition.expr = And(postcondition.expr, LogCall(predicate)) functions.append( Procedure(f'Get_{field.name}', [('Buffer', 'Types.Bytes'), ('First', 'out Types.Index_Type'), ('Last', 'out Types.Index_Type')], [], body, [precondition, postcondition])) else: functions.append( ExpressionFunction( f'Get_{field.name}', field.type.name, [('Buffer', 'Types.Bytes')], IfExpression( [(LogCall(f'Valid_{field.name}_{variant_id} (Buffer)'), MathCall(f'Get_{field.name}_{variant_id} (Buffer)')) for variant_id in field.variants], f'Unreachable_{field.type.name}'), [precondition])) return functions
def value_to_call_facts( previous: List[Tuple[str, str]]) -> Dict[Attribute, MathExpr]: result: Dict[Attribute, MathExpr] = {} for field_name, vid in previous: get_call = MathCall(f'Get_{field_name}_{vid} (Buffer)') result[Value(field_name)] = get_call result[LengthValue(field_name)] = Cast('Types.Length_Type', get_call) return result
def parse_term(string: str, location: int, tokens: list) -> Union[Attribute, Number]: if isinstance(tokens[0], str): return Value(tokens[0]) if isinstance(tokens[0], (Attribute, Number)): return tokens[0] raise ParseFatalException(string, location, 'expected identifier, attribute or number')
def test_distributivity_simplified(self) -> None: self.assertEqual( Add(Sub(Value('X'), Add(Value('X'), Number(1))), Add(Value('X'), Number(1))).simplified(), Value('X')) self.assertEqual( Div(Add(Mul(Value('X'), Number(8)), Number(144)), Number(8)).simplified(), Add(Value('X'), Number(18))) self.assertEqual( Div(Sub(Mul(Value('X'), Number(8)), Number(148)), Number(8)).simplified(), Add(Value('X'), Div(Number(-148), Number(8))))
def test_sub_simplified(self) -> None: self.assertEqual( Sub(Number(1), Value('X')).simplified(), Add(Value('X'), Number(-1))) self.assertEqual( Sub(Value('X'), Number(1)).simplified(), Add(Value('X'), Number(-1))) self.assertEqual(Sub(Number(6), Number(2)).simplified(), Number(4)) self.assertEqual( Sub(Value('X'), Value('Y')).simplified(), Add(Value('X'), Value('Y', True)))
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 __process_refinements(self, refinements: List[Refinement]) -> None: for refinement in refinements: if refinement.package not in self.__units: context = COMMON_CONTEXT package = Package(refinement.package, [], []) self.__units[refinement.package] = Unit(context, package) contains_package = f'{refinement.package}.Contains' if contains_package in self.__units: context = self.__units[contains_package].context package = self.__units[contains_package].package else: context = [] package = Package(contains_package, [], []) self.__units[contains_package] = Unit(context, package) pdu_package = refinement.pdu.rsplit('.', 1)[0] if pdu_package != refinement.package: pdu_top_level_context = [ WithClause([pdu_package]), UsePackageClause([pdu_package]) ] if pdu_top_level_context not in context: context.extend(pdu_top_level_context) pdu_context = WithClause([refinement.pdu]) if pdu_context not in context: context.append(pdu_context) if refinement.sdu != 'null': sdu_context = WithClause([refinement.sdu]) if sdu_context not in context: context.append(sdu_context) package.subprograms.append( contains_function( refinement.unqualified_name, refinement.pdu, refinement.field, refinement.sdu, refinement.condition.simplified({ Value(field): MathCall(f'{refinement.pdu}.Get_{field} (Buffer)') for field in self.__pdu_fields[refinement.pdu] })))
def variant_validation_function(field: Field, variant_id: str, variant: Variant) -> Subprogram: type_constraints: LogExpr = TRUE if field.type.constraints != TRUE or isinstance(field.type, Enumeration): first_byte, last_byte, offset = field_location(field.name, variant_id, variant) if field.type.constraints != TRUE: convert = Convert(field.type.base_name, 'Buffer', first_byte, last_byte, offset) type_constraints = field.type.constraints.simplified( {Value(field.type.name): convert}) if isinstance(field.type, Enumeration): type_constraints = And( type_constraints, LogCall((f'Valid_{field.type.name} (Buffer ({first_byte}' f' .. {last_byte}), {offset})'))) value_to_call = value_to_call_facts([(field.name, variant_id)] + variant.previous) return ExpressionFunction( f'Valid_{field.name}_{variant_id}', 'Boolean', [('Buffer', 'Types.Bytes')], And( LogCall( f'Valid_{variant.previous[-1][0]}_{variant.previous[-1][1]} (Buffer)' ) if variant.previous else TRUE, And( And( buffer_constraints(variant.facts[Last( field.name)].to_bytes()).simplified(value_to_call), variant.condition.simplified( variant.facts).simplified(value_to_call)), type_constraints)).simplified(), [Precondition(COMMON_PRECONDITION)])
def array_functions(array: Array, package: str) -> List[Subprogram]: common_precondition = LogCall(f'Is_Contained (Buffer)') return [ Function('Valid_First', 'Boolean', [('Buffer', 'Types.Bytes')], [], [ ReturnStatement( LogCall('Valid_Next (Buffer, Offset_Type (Buffer\'First))')) ], [Precondition(common_precondition)]), Procedure('Get_First', [ ('Buffer', 'Types.Bytes'), ('Offset', 'out Offset_Type'), ('First', 'out Types.Index_Type'), ('Last', 'out Types.Index_Type') ], [], [ Assignment('Offset', Value('Offset_Type (Buffer\'First)')), CallStatement('Get_Next', ['Buffer', 'Offset', 'First', 'Last']) ], [ Precondition( And(common_precondition, LogCall('Valid_First (Buffer)'))), Postcondition( And( And(GreaterEqual(Value('First'), First('Buffer')), LessEqual(Value('Last'), Last('Buffer'))), LogCall(f'{package}.{array.element_type}.Is_Contained ' '(Buffer (First .. Last))'))) ]), Function('Valid_Next', 'Boolean', [ ('Buffer', 'Types.Bytes'), ('Offset', 'Offset_Type') ], [], [ PragmaStatement('Assume', [ (f'{package}.{array.element_type}.Is_Contained ' '(Buffer (Types.Index_Type (Offset) .. Buffer\'Last))') ]), ReturnStatement( LogCall( f'{package}.{array.element_type}.Is_Valid ' '(Buffer (Types.Index_Type (Offset) .. Buffer\'Last))')) ], [Precondition(common_precondition)]), Procedure( 'Get_Next', [('Buffer', 'Types.Bytes'), ('Offset', 'in out Offset_Type'), ('First', 'out Types.Index_Type'), ('Last', 'out Types.Index_Type')], [], [ Assignment('First', Value('Types.Index_Type (Offset)')), Assignment( 'Last', Add( Value('First'), Cast( 'Types.Length_Type', MathCall(f'{package}.{array.element_type}.' 'Message_Length (Buffer (First ' '.. Buffer\'Last))')), Number(-1))), Assignment('Offset', Value('Offset_Type (Last + 1)')), PragmaStatement( 'Assume', [(f'{package}.{array.element_type}.Is_Contained ' '(Buffer (First .. Last))')]) ], [ Precondition( And(common_precondition, LogCall('Valid_Next (Buffer, Offset)'))), Postcondition( And( And(GreaterEqual(Value('First'), First('Buffer')), LessEqual(Value('Last'), Last('Buffer'))), LogCall(f'{package}.{array.element_type}.Is_Contained ' '(Buffer (First .. Last))'))) ]) ]
def test_less_equal_simplified(self) -> None: self.assertEqual( LessEqual(Value('X'), Add(Number(21), Number(21))).simplified(), LessEqual(Value('X'), Number(42)))
def test_term_simplified(self) -> None: self.assertEqual( Add(Mul(Number(1), Number(6)), Sub(Value('X'), Number(10)), Add(Number(1), Number(3))).simplified(), Value('X'))
def enumeration_functions(enum: Enumeration) -> List[Subprogram]: common_precondition = And( Less(Value('Offset'), Number(8)), Equal( Length('Buffer'), Add( Div(Add(Size(enum.base_name), Value('Offset'), Number(-1)), Number(8)), Number(1)))) control_expression = LogCall( f'Convert_To_{enum.base_name} (Buffer, Offset)') validation_expression: Expr if enum.always_valid: validation_expression = Value('True') else: validation_cases: List[Tuple[Expr, Expr]] = [] validation_cases.extend( (value, Value('True')) for value in enum.literals.values()) validation_cases.append((Value('others'), Value('False'))) validation_expression = CaseExpression(control_expression, validation_cases) validation_function = ExpressionFunction( f'Valid_{enum.name}', 'Boolean', [('Buffer', 'Types.Bytes'), ('Offset', 'Natural')], validation_expression, [Precondition(common_precondition)]) function_name = f'Convert_To_{enum.name}' parameters = [('Buffer', 'Types.Bytes'), ('Offset', 'Natural')] precondition = Precondition( And(common_precondition, LogCall(f'Valid_{enum.name} (Buffer, Offset)'))) conversion_cases: List[Tuple[Expr, Expr]] = [] conversion_function: Subprogram if enum.always_valid: conversion_cases.extend((value, Aggregate(Value('True'), Value(key))) for key, value in enum.literals.items()) conversion_cases.append( (Value('others'), Aggregate(Value('False'), Value('Raw')))) conversion_function = Function( function_name, enum.name, parameters, [Declaration('Raw', enum.base_name, control_expression)], [ReturnStatement(CaseExpression(Value('Raw'), conversion_cases))], [precondition]) else: conversion_cases.extend( (value, Value(key)) for key, value in enum.literals.items()) conversion_cases.append( (Value('others'), LogCall(f'Unreachable_{enum.name}'))) conversion_function = ExpressionFunction( function_name, enum.name, parameters, CaseExpression(control_expression, conversion_cases), [precondition]) return [validation_function, conversion_function]
def test_add_neg(self) -> None: self.assertEqual(-Add(Value('X'), Number(1)), Add(Value('X', True), Number(-1)))
def test_add_simplified(self) -> None: self.assertEqual( Add(Value('X'), Number(1)).simplified(), Add(Value('X'), Number(1))) self.assertEqual(Add(Value('X'), Number(0)).simplified(), Value('X')) self.assertEqual( Add(Number(2), Number(3), Number(5)).simplified(), Number(10)) self.assertEqual( Add(Value('X'), Value('Y'), Value('X', True)).simplified(), Value('Y')) self.assertEqual( Add(Value('X'), Value('Y'), Value('X'), -Value('X')).simplified(), Add(Value('X'), Value('Y')))
def test_term_to_bytes(self) -> None: self.assertEqual( Add(Mul(Number(8), Number(48)), Sub(Value('X'), Number(80)), Div(Number(8), Number(24))).to_bytes(), Add(Mul(Number(1), Number(6)), Sub(Value('X'), Number(10)), Div(Number(1), Number(3))))
def test_range_invalid_last_variable(self) -> None: with self.assertRaises(ModelError): RangeInteger('X', Number(1), Add(Number(1), Value('X')), Number(4))
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_value_neg(self) -> None: self.assertEqual(-Value('X'), Value('X', True))
def test_value_simplified(self) -> None: self.assertEqual(Value('X').simplified(), Value('X')) self.assertEqual( Value('X').simplified({Value('X'): Number(42)}), Number(42))
def unreachable_function(type_name: str, base_name: str = None) -> Subprogram: return ExpressionFunction( f'Unreachable_{type_name}'.replace('.', '_'), type_name, [], First(type_name) if not base_name else Aggregate( Value('False'), First(base_name)), [Precondition(FALSE)])
def test_greater_equal_simplified(self) -> None: self.assertEqual( GreaterEqual(Value('X'), Add(Number(21), Number(21))).simplified(), GreaterEqual(Value('X'), Number(42)))
def test_pdu_fields_length_after_payload(self) -> None: int_type = ModularInteger('T', Number(256)) payload_type = Array('Payload_Type') initial = InitialNode() version = Node('Version', int_type) payload = Node('Payload', payload_type) length = Node('Length', int_type) initial.edges = [Edge(version, TRUE)] version.edges = [Edge(payload, length=Value('Length'))] payload.edges = [Edge(length, first=Add(Last('Buffer'), -Length('Length'), Number(1)))] length.edges = [Edge(FINAL)] pdu = PDU('Foo', initial) expected = OrderedDict([ ('Version', Field('Version', int_type, TRUE, { '0': Variant( [], TRUE, { Length('Version'): Number(8), First('Version'): Number(0), Last('Version'): Number(7) }) })), ('Payload', Field('Payload', payload_type, TRUE, { '00': Variant( [('Version', '0')], TRUE, { Length('Version'): Number(8), First('Version'): Number(0), Last('Version'): Number(7), Length('Payload'): Value('Length'), First('Payload'): Number(8), Last('Payload'): Add(Value('Length'), Number(7)) }) })), ('Length', Field('Length', int_type, TRUE, { '000': Variant( [('Version', '0'), ('Payload', '00')], TRUE, { Length('Version'): Number(8), First('Version'): Number(0), Last('Version'): Number(7), Length('Payload'): Value('Length'), First('Payload'): Number(8), Last('Payload'): Add(Value('Length'), Number(7)), Length('Length'): Number(8), First('Length'): Add(Last('Buffer'), Number(-7)), Last('Length'): Last('Buffer') }) })), ('FINAL', Field('FINAL', Null(), TRUE, { '0000': Variant( [('Version', '0'), ('Payload', '00'), ('Length', '000')], TRUE, { Length('Version'): Number(8), First('Version'): Number(0), Last('Version'): Number(7), Length('Payload'): Value('Length'), First('Payload'): Number(8), Last('Payload'): Add(Value('Length'), Number(7)), Length('Length'): Number(8), First('Length'): Add(Last('Buffer'), Number(-7)), Last('Length'): Last('Buffer') }) })) ]) self.assertEqual(pdu.fields(), expected)
def test_not_equal_simplified(self) -> None: self.assertEqual( NotEqual(Value('X'), Add(Number(21), Number(21))).simplified(), NotEqual(Value('X'), Number(42)))
def test_modular_invalid_modulus_variable(self) -> None: with self.assertRaises(ModelError): ModularInteger('X', Pow(Number(2), Value('X')))
def test_number_le(self) -> None: self.assertEqual(Number(1) <= Number(2), True) self.assertEqual(Number(2) <= Number(2), True) self.assertEqual(Number(3) <= Number(2), False) self.assertEqual(Value('X') <= Number(2), False) self.assertEqual(Number(2) <= Value('X'), False)
def test_range_invalid_size_variable(self) -> None: with self.assertRaises(ModelError): RangeInteger('X', Number(0), Number(256), Add(Number(8), Value('X')))
def test_number_ge(self) -> None: self.assertEqual(Number(1) >= Number(2), False) self.assertEqual(Number(2) >= Number(2), True) self.assertEqual(Number(3) >= Number(2), True) self.assertEqual(Value('X') >= Number(2), False) self.assertEqual(Number(2) >= Value('X'), False)