From b565ff8fc0b180ac76a891f25bb31b8e0d003fcf Mon Sep 17 00:00:00 2001 From: Disconnect3d Date: Mon, 17 Apr 2017 22:32:38 +0200 Subject: [PATCH] Fix big with enums OR operation in Python 3 (#222) The bug can be reproduced using such code: ``` pwndbg> py import re; re.DOTALL | re.MULTILINE Traceback (most recent call last): File "", line 1, in File "/usr/lib/python3.6/enum.py", line 794, in __or__ result = self.__class__(self._value_ | self.__class__(other)._value_) File "/usr/lib/python3.6/enum.py", line 291, in __call__ return cls.__new__(cls, value) File "/usr/lib/python3.6/enum.py", line 533, in __new__ return cls._missing_(value) File "/usr/lib/python3.6/enum.py", line 760, in _missing_ new_member = cls._create_pseudo_member_(value) File "/usr/lib/python3.6/enum.py", line 786, in _create_pseudo_member_ pseudo_member._name_ = None AttributeError: 'int' object has no attribute '_name_' Error while executing Python code. ``` The fix seems to work with Python 2 as well: http://asciinema.org/a/czopcwobjwt2dk9vzif0zk49u --- pwndbg/inthook.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/pwndbg/inthook.py b/pwndbg/inthook.py index 923d7c100..3bc43b222 100644 --- a/pwndbg/inthook.py +++ b/pwndbg/inthook.py @@ -18,18 +18,20 @@ from future.utils import with_metaclass import pwndbg.typeinfo -if sys.version_info < (3,0): +if sys.version_info < (3, 0): import __builtin__ as builtins else: import builtins _int = builtins.int + # We need this class to get isinstance(7, xint) to return True class IsAnInt(type): def __instancecheck__(self, other): return isinstance(other, _int) + class xint(with_metaclass(IsAnInt, builtins.int)): def __new__(cls, value, *a, **kw): if isinstance(value, gdb.Value): @@ -37,11 +39,16 @@ class xint(with_metaclass(IsAnInt, builtins.int)): value = value.cast(pwndbg.typeinfo.ulong) else: value = value.cast(pwndbg.typeinfo.long) - if isinstance(value, gdb.Symbol): + + elif isinstance(value, gdb.Symbol): symbol = value - value = symbol.value() + value = symbol.value() if symbol.is_function: value = value.cast(pwndbg.typeinfo.ulong) + + else: + return _int.__new__(cls, value, *a, **kw) + return _int(_int(value, *a, **kw)) # Do not hook 'int' if we are just generating documentation @@ -49,6 +56,6 @@ if os.environ.get('SPHINX', None) is None: builtins.int = xint globals()['int'] = xint - if sys.version_info >= (3,0): + if sys.version_info >= (3, 0): builtins.long = xint globals()['long'] = xint