Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
rhs_pointer = rhs_type.is_pointer_operand()
if rhs_pointer:
rhs_sizeof = cast(PointerType, rhs_type).type.sizeof()
if ((lhs_pointer and rhs_pointer and lhs_sizeof != rhs_sizeof) or
(lhs_pointer and not rhs_pointer and not rhs_type.is_integer()) or
(rhs_pointer and not lhs_pointer) or
(not lhs_pointer and not rhs_pointer and
(not lhs_type.is_arithmetic() or not rhs_type.is_arithmetic()))):
raise TypeError(f'invalid operands to binary - ({lhs_type.name!r} and {rhs_type.name!r})')
lhs_type = lhs_type.operand_type()
rhs_type = rhs_type.operand_type()
if lhs_pointer and rhs_pointer:
return Object(self.prog_, self.prog_._type_index._ptrdiff_t(),
value=(lhs - rhs) // lhs_sizeof)
elif lhs_pointer:
return Object(self.prog_, lhs_type, value=lhs - lhs_sizeof * rhs)
else:
type_, lhs, rhs = self._usual_arithmetic_conversions(lhs, lhs_type,
rhs, rhs_type)
return Object(self.prog_, type_, value=lhs - rhs)
(lhs_pointer and not rhs_pointer and not rhs_type.is_integer()) or
(rhs_pointer and not lhs_pointer) or
(not lhs_pointer and not rhs_pointer and
(not lhs_type.is_arithmetic() or not rhs_type.is_arithmetic()))):
raise TypeError(f'invalid operands to binary - ({lhs_type.name!r} and {rhs_type.name!r})')
lhs_type = lhs_type.operand_type()
rhs_type = rhs_type.operand_type()
if lhs_pointer and rhs_pointer:
return Object(self.prog_, self.prog_._type_index._ptrdiff_t(),
value=(lhs - rhs) // lhs_sizeof)
elif lhs_pointer:
return Object(self.prog_, lhs_type, value=lhs - lhs_sizeof * rhs)
else:
type_, lhs, rhs = self._usual_arithmetic_conversions(lhs, lhs_type,
rhs, rhs_type)
return Object(self.prog_, type_, value=lhs - rhs)
lhs_pointer = lhs_type.is_pointer_operand()
if lhs_pointer:
lhs_sizeof = cast(PointerType, lhs_type).type.sizeof()
rhs_pointer = rhs_type.is_pointer_operand()
if rhs_pointer:
rhs_sizeof = cast(PointerType, rhs_type).type.sizeof()
if ((lhs_pointer and rhs_pointer and lhs_sizeof != rhs_sizeof) or
(lhs_pointer and not rhs_pointer and not rhs_type.is_integer()) or
(rhs_pointer and not lhs_pointer) or
(not lhs_pointer and not rhs_pointer and
(not lhs_type.is_arithmetic() or not rhs_type.is_arithmetic()))):
raise TypeError(f'invalid operands to binary - ({lhs_type.name!r} and {rhs_type.name!r})')
lhs_type = lhs_type.operand_type()
rhs_type = rhs_type.operand_type()
if lhs_pointer and rhs_pointer:
return Object(self.prog_, self.prog_._type_index._ptrdiff_t(),
value=(lhs - rhs) // lhs_sizeof)
elif lhs_pointer:
return Object(self.prog_, lhs_type, value=lhs - lhs_sizeof * rhs)
else:
type_, lhs, rhs = self._usual_arithmetic_conversions(lhs, lhs_type,
rhs, rhs_type)
return Object(self.prog_, type_, value=lhs - rhs)
self.assertEqual(container_of(obj, point_type, 'y'),
Object(self.prog, pointer_type(8, point_type),
value=0xffff0008))
self.assertEqual(container_of(obj, line_segment_type, 'a.x'),
Object(self.prog, pointer_type(8, line_segment_type),
value=0xffff000c))
self.assertEqual(container_of(obj, line_segment_type, 'b.x'),
Object(self.prog, pointer_type(8, line_segment_type),
value=0xffff0004))
polygon_type = struct_type('polygon', 0, (
(array_type(None, point_type), 'points'),
))
self.assertEqual(container_of(obj, polygon_type, 'points[3].x'),
Object(self.prog, pointer_type(8, polygon_type),
value=0xfffefff4))
small_point_type = struct_type('small_point', 1, (
(int_type('int', 4, True), 'x', 0, 4),
(int_type('int', 4, True), 'y', 4, 4),
))
self.assertRaisesRegex(ValueError,
r'container_of\(\) member is not byte-aligned',
container_of, obj, small_point_type, 'y')
self.assertRaisesRegex(TypeError,
r'container_of\(\) argument must be a pointer',
container_of, obj[0], point_type, 'x')
self.assertRaisesRegex(TypeError, 'not a structure, union, or class',
container_of, obj, obj.type_, 'x'),
def test_member(self):
reference = Object(self.prog, point_type, address=0xffff0000)
unnamed_reference = Object(self.prog, struct_type('point', 8, (
(struct_type(None, 8, point_type.members), None),
)), address=0xffff0000)
ptr = Object(self.prog, pointer_type(8, point_type), value=0xffff0000)
for obj in [reference, unnamed_reference, ptr]:
self.assertEqual(obj.member_('x'),
Object(self.prog, 'int', address=0xffff0000))
self.assertEqual(obj.member_('x'), obj.x)
self.assertEqual(obj.member_('y'),
Object(self.prog, 'int', address=0xffff0004))
self.assertEqual(obj.member_('y'), obj.y)
self.assertRaisesRegex(LookupError, "'struct point' has no member 'z'",
obj.member_, 'z')
self.assertRaisesRegex(AttributeError, "'struct point' has no member 'z'",
getattr, obj, 'z')
def test_bit_field_member(self):
segment = b'\x07\x10\x5e\x5f\x1f\0\0\0'
prog = mock_program(segments=[
MockMemorySegment(segment, virt_addr=0xffff0000),
])
type_ = struct_type('bits', 8, (
(int_type('int', 4, True), 'x', 0, 4),
(int_type('int', 4, True, Qualifiers.CONST), 'y', 4, 28),
(int_type('int', 4, True), 'z', 32, 5),
))
obj = Object(prog, type_, address=0xffff0000)
self.assertEqual(obj.x,
Object(prog, int_type('int', 4, True),
address=0xffff0000, bit_field_size=4))
self.assertEqual(
obj.y,
Object(prog, int_type('int', 4, True, Qualifiers.CONST),
address=0xffff0000, bit_field_size=28, bit_offset=4))
self.assertEqual(obj.z,
Object(prog, int_type('int', 4, True),
address=0xffff0004, bit_field_size=5))
def test_add(self):
self._test_arithmetic(operator.add, 1, 2, 3, floating_point=True)
ptr = Object(self.prog, 'int *', value=0xffff0000)
arr = Object(self.prog, 'int [2]', address=0xffff0000)
ptr1 = Object(self.prog, 'int *', value=0xffff0004)
self.assertEqual(ptr + self.int(1), ptr1)
self.assertEqual(self.unsigned_int(1) + ptr, ptr1)
self.assertEqual(arr + self.int(1), ptr1)
self.assertEqual(ptr1 + self.int(-1), ptr)
self.assertEqual(self.int(-1) + ptr1, ptr)
self.assertEqual(ptr + 1, ptr1)
self.assertEqual(1 + ptr, ptr1)
self.assertRaises(TypeError, operator.add, ptr, ptr)
self.assertRaises(TypeError, operator.add, ptr, 2.0)
self.assertRaises(TypeError, operator.add, 2.0, ptr)
void_ptr = Object(self.prog, 'void *', value=0xffff0000)
void_ptr1 = Object(self.prog, 'void *', value=0xffff0001)
self.assertEqual(void_ptr + self.int(1), void_ptr1)
self.assertEqual(self.unsigned_int(1) + void_ptr, void_ptr1)
])
strings = [
(Object(prog, 'char *', address=0xfffefff8), b'hello'),
(Object(prog, 'char [2]', address=0xffff0000), b'he'),
(Object(prog, 'char [8]', address=0xffff0000), b'hello'),
]
for obj, expected in strings:
with self.subTest(obj=obj):
self.assertEqual(obj.string_(), expected)
self.assertEqual(obj.read_().string_(), expected)
strings = [
Object(prog, 'char []', address=0xffff0000),
Object(prog, 'int []', address=0xffff0000),
Object(prog, 'int [2]', address=0xffff0000),
Object(prog, 'int *', value=0xffff0000),
]
for obj in strings:
self.assertEqual(obj.string_(), b'hello')
self.assertRaisesRegex(TypeError, 'must be an array or pointer',
Object(prog, 'int', value=1).string_)
def test_extended_integer(self):
self.assertEqual(+Object(self.prog, int_type('byte', 1, True), value=1),
Object(self.prog, 'int', value=1))
self.assertEqual(+Object(self.prog, int_type('ubyte', 1, False), value=-1),
Object(self.prog, 'int', value=0xff))
self.assertEqual(+Object(self.prog, int_type('qword', 8, True), value=1),
Object(self.prog, int_type('qword', 8, True), value=1))
self.assertEqual(+Object(self.prog, int_type('qword', 8, False), value=1),
Object(self.prog, int_type('qword', 8, False), value=1))
def test_multiple_piped():
line = 'echo'
objs = [
drgn.Object(MOCK_PROGRAM, 'void *', value=0),
drgn.Object(MOCK_PROGRAM, 'int', value=1),
]
ret = invoke(MOCK_PROGRAM, objs, line)
assert len(ret) == 2
assert ret[0].value_() == 0
assert ret[0].type_ == MOCK_PROGRAM.type('void *')
assert ret[1].value_() == 1
assert ret[1].type_ == MOCK_PROGRAM.type('int')