Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_state_expr(self):
change = StateChange()
self.assertEqual(str(change), "none")
change = StateChange(m=0)
self.assertEqual(str(change), "m=0")
change = StateChange(x=1)
self.assertEqual(str(change), "x=1")
change = StateChange(m=0, x=1)
self.assertEqual(str(change), "m=0,x=1")
def test_apply_inference(self):
change = StateChange(m=1, x=1)
inference = StateChange(m=1, x=None)
change.apply_inference(inference)
self.assertEqual(change.m, None)
self.assertEqual(change.x, 1)
def test_repr(self):
change = StateChange()
self.assertEqual(repr(change), "")
change = StateChange(unknown=True)
self.assertEqual(repr(change), "")
change = StateChange(m=1)
self.assertEqual(repr(change), "")
change = StateChange(m=1, x=1)
self.assertEqual(repr(change), "")
def test_repr(self):
change = StateChange()
self.assertEqual(repr(change), "")
change = StateChange(unknown=True)
self.assertEqual(repr(change), "")
change = StateChange(m=1)
self.assertEqual(repr(change), "")
change = StateChange(m=1, x=1)
self.assertEqual(repr(change), "")
def test_from_state_expr(self):
change = StateChange.from_expr("none")
self.assertEqual(change, StateChange())
change = StateChange.from_expr("m=0")
self.assertEqual(change, StateChange(m=0))
change = StateChange.from_expr("x=1")
self.assertEqual(change, StateChange(x=1))
change = StateChange.from_expr("m=0,x=1")
self.assertEqual(change, StateChange(m=0, x=1))
change = StateChange.from_expr("x=0,m=1")
self.assertEqual(change, StateChange(x=0, m=1))
def test_assert_state_change(self):
# Assertion.
unknown = self.log.subroutines[0x800B]
self.log.assert_subroutine_state_change(unknown, 0x800B, StateChange())
self.assertTrue(self.log.dirty)
self.log.analyze()
self.assertFalse(self.log.dirty)
reset = self.log.subroutines_by_label["reset"]
unknown = self.log.subroutines[0x800B]
self.assertIn(0x8005, reset.instructions)
self.assertIn(0x8008, reset.instructions)
self.assertTrue(unknown.indirect_jumps)
self.assertTrue(unknown.has_asserted_state_change)
self.assertFalse(unknown.has_unknown_return_state)
# Deassertion.
self.log.deassert_subroutine_state_change(0x800B, 0x800B)
self.assertTrue(self.log.dirty)
def test_simplify(self):
state = State(m=0, x=1)
change = StateChange()
self.assertEqual(change.simplify(state), StateChange())
change = StateChange(m=0)
self.assertEqual(change.simplify(state), StateChange())
change = StateChange(m=0, x=1)
self.assertEqual(change.simplify(state), StateChange())
change = StateChange(m=0, x=0)
self.assertEqual(change.simplify(state), StateChange(x=0))
change = StateChange(unknown=True)
self.assertEqual(change.simplify(state), StateChange(unknown=True))
def test_apply_inference(self):
change = StateChange(m=1, x=1)
inference = StateChange(m=1, x=None)
change.apply_inference(inference)
self.assertEqual(change.m, None)
self.assertEqual(change.x, 1)
def _unknown_subroutine_state(
self,
instruction: Instruction,
unknown_reason: Optional[UnknownReason] = None,
stack_manipulator: Optional[Instruction] = None,
) -> bool:
# Check if the user defined a state assertion for the current instruction.
if instruction.pc in self.log.instruction_assertions:
return True # Execution can proceed.
# No custom assertion, we need to stop here.
unknown_reason = unknown_reason or UnknownReason.UNKNOWN
self.state_change = StateChange(unknown_reason=unknown_reason)
self.log.add_subroutine_state(
self.subroutine_pc, instruction.pc, copy(self.state_change)
)
# If the unknown state is due to stack manipulation:
if unknown_reason == UnknownReason.STACK_MANIPULATION:
# If we know which instruction performed the
# manipulation, we flag it.
if stack_manipulator:
self.subroutine.has_stack_manipulation = True
stack_manipulator.stack_manipulation = (
StackManipulation.CAUSES_UNKNOWN_STATE
)
return False