diff --git a/bindings/python/capstone/__init__.py b/bindings/python/capstone/__init__.py index 45ea979485..843a8413f7 100755 --- a/bindings/python/capstone/__init__.py +++ b/bindings/python/capstone/__init__.py @@ -1099,8 +1099,11 @@ def disasm(self, code, offset, count=0): print(code)''' # Pass a bytearray by reference size = len(code) - if isinstance(code, bytearray): - code = ctypes.byref(ctypes.c_char.from_buffer(code)) + view = memoryview(code) + if not view.readonly: + code = ctypes.byref(ctypes.c_char.from_buffer(view)) + elif not isinstance(code, bytes): + code = view.tobytes() res = _cs.cs_disasm(self.csh, code, size, offset, count, ctypes.byref(all_insn)) if res > 0: try: @@ -1127,8 +1130,11 @@ def disasm_lite(self, code, offset, count=0): all_insn = ctypes.POINTER(_cs_insn)() size = len(code) # Pass a bytearray by reference - if isinstance(code, bytearray): - code = ctypes.byref(ctypes.c_char.from_buffer(code)) + view = memoryview(code) + if not view.readonly: + code = ctypes.byref(ctypes.c_char.from_buffer(view)) + elif not isinstance(code, bytes): + code = view.tobytes() res = _cs.cs_disasm(self.csh, code, size, offset, count, ctypes.byref(all_insn)) if res > 0: try: diff --git a/bindings/python/test_basic.py b/bindings/python/test_basic.py index 22007c5654..a580f05d85 100755 --- a/bindings/python/test_basic.py +++ b/bindings/python/test_basic.py @@ -81,6 +81,22 @@ def test_cs_disasm_quick(): print() +def test_different_data_formats(): + data = bytes.fromhex('4831C948F7E1043B48BB0A2F62696E2F2F736852530A545F5257545E0F05') + mnemonics = ['xor', 'mul', 'add', 'movabs', 'push', 'pop', 'push', 'push', 'push', 'pop', 'syscall'] + disassembler = Cs(CS_ARCH_X86, CS_MODE_64) + for name, code in ( + ('bytearray', bytearray(data)), + ('memoryview of bytearray', memoryview(bytearray(data))), + ('memoryview of data', memoryview(data)), + ('raw data', data) + ): + if mnemonics != [op for _, _, op, _ in disassembler.disasm_lite(code, 0)]: + print('failure in disassemble-lite for %s.' % name) + if mnemonics != [instruction.mnemonic for instruction in disassembler.disasm(code, 0)]: + print('failure in disassemble-full for %s.' % name) + + # ## Test class Cs def test_class(): for arch, mode, code, comment, syntax in all_tests: @@ -110,3 +126,4 @@ def test_class(): # print ("*" * 40) if __name__ == '__main__': test_class() + test_different_data_formats()