Skip to content

Commit

Permalink
Clean up usages of getattr/__getattr__
Browse files Browse the repository at this point in the history
  • Loading branch information
Arusekk committed Feb 1, 2022
1 parent 1238fc3 commit 29c8c0e
Show file tree
Hide file tree
Showing 18 changed files with 73 additions and 57 deletions.
5 changes: 4 additions & 1 deletion pwnlib/adb/adb.py
Expand Up @@ -384,6 +384,9 @@ def __getattr__(self, name):
>>> adb.getprop(property) == device.getprop(property)
True
"""
if name.startswith('_'):
raise AttributeError(name)

with context.local(device=self):
g = globals()

Expand Down Expand Up @@ -1513,7 +1516,7 @@ def __iter__(self):
return iter(names)

def __getattr__(self, attr):
if attr.startswith("_"):
if attr.startswith('_'):
raise AttributeError(attr)

for name in self:
Expand Down
8 changes: 4 additions & 4 deletions pwnlib/adb/bootimg.py
Expand Up @@ -46,7 +46,7 @@ def __init__(self, data):
self.kernel = self.data[PAGE:PAGE+self.kernel_size]

def __getattr__(self, name):
value = getattr(self.header, name, None)
if value is not None:
return value
return getattr(super(BootImage, self), name)
if name.startswith('_'):
raise AttributeError(name)

return getattr(self.header, name)
9 changes: 5 additions & 4 deletions pwnlib/adb/bootloader.py
Expand Up @@ -114,10 +114,11 @@ def __str__(self):
return '\n'.join(rv)

def __getattr__(self, name):
value = getattr(self.header, name, None)
if value is not None:
return value
return getattr(super(BootImage, self), name)
if name.startswith('_'):
raise AttributeError(name)

return getattr(self.header, name)


if __name__ == '__main__':
# Easy sanity checking
Expand Down
2 changes: 2 additions & 0 deletions pwnlib/args.py
Expand Up @@ -62,6 +62,8 @@

class PwnlibArgs(collections.defaultdict):
def __getattr__(self, attr):
if attr.startswith('_'):
raise AttributeError(attr)
return self[attr]

args = PwnlibArgs(str)
Expand Down
4 changes: 2 additions & 2 deletions pwnlib/data/useragents/download-useragents.py
@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
"""Script for downloading lists of user agent strings."""
from __future__ import division
import os
Expand Down Expand Up @@ -43,7 +43,7 @@ def loop(xml):
l.success()

with log.waitfor('Parsing list') as l:
for item in soup.__getattr__('user-agents'):
for item in getattr(soup, 'user-agents'):
if item.name == 'user-agent':
ua = item.select('string')[0].string.strip()
try:
Expand Down
11 changes: 5 additions & 6 deletions pwnlib/elf/corefile.py
Expand Up @@ -1184,14 +1184,13 @@ def debug(self):
pwnlib.gdb.attach(self, exe=self.exe.path)

def __getattr__(self, attribute):
if self.prstatus:
if hasattr(self.prstatus, attribute):
return getattr(self.prstatus, attribute)
if attribute.startswith('_') or not self.prstatus:
raise AttributeError(attribute)

if hasattr(self.prstatus.pr_reg, attribute):
return getattr(self.prstatus.pr_reg, attribute)
if hasattr(self.prstatus, attribute):
return getattr(self.prstatus, attribute)

return super(Corefile, self).__getattribute__(attribute)
return getattr(self.prstatus.pr_reg, attribute)

# Override routines which don't make sense for Corefiles
def _populate_got(*a): pass
Expand Down
3 changes: 2 additions & 1 deletion pwnlib/elf/datatypes.py
Expand Up @@ -604,7 +604,8 @@ def lr(self):
def __getattr__(self, name):
if name.startswith('r'):
name = 'x' + name[1:]
return getattr(name) & 0xffffffff
return getattr(self, name) & 0xffffffff
raise AttributeError(name)

class elf_prstatus_i386(ctypes.Structure):
_fields_ = generate_prstatus_common(32, user_regs_struct_i386)
Expand Down
3 changes: 1 addition & 2 deletions pwnlib/elf/elf.py
Expand Up @@ -167,8 +167,7 @@ def __getattr__(self, name):

if subkeys:
return dotdict(subkeys)

return getattr(super(dotdict, self), name)
raise AttributeError(name)

class ELF(ELFFile):
"""Encapsulates information about an ELF file.
Expand Down
19 changes: 7 additions & 12 deletions pwnlib/filepointer.py
Expand Up @@ -176,24 +176,19 @@ def __setattr__(self,item,value):
def __repr__(self):
structure=[]
for i in self.vars_:
structure.append(" %s: %s" % (i,hex(self.__getattr__(i))))
structure.append(" %s: %s" % (i,hex(getattr(self, i))))
return "{"+ "\n".join(structure)+"}"

def __getattr__(self,item):
if item in FileStructure.__dict__ or item in self.vars_:
return object.__getattribute__(self,item)
log.error("Unknown variable %r" % item)

def __len__(self):
return len(bytes(self))

def __bytes__(self):
structure = b''
for val in self.vars_:
if isinstance(self.__getattr__(val), bytes):
structure += self.__getattr__(val).ljust(context.bytes, b'\x00')
if isinstance(getattr(self, val), bytes):
structure += getattr(self, val).ljust(context.bytes, b'\x00')
else:
structure += pack(self.__getattr__(val), self.length[val]*8)
structure += pack(getattr(self, val), self.length[val]*8)
return structure

def struntil(self,v):
Expand All @@ -218,10 +213,10 @@ def struntil(self,v):
return b''
structure = b''
for val in self.vars_:
if isinstance(self.__getattr__(val), bytes):
structure += self.__getattr__(val).ljust(context.bytes, b'\x00')
if isinstance(getattr(self, val), bytes):
structure += getattr(self, val).ljust(context.bytes, b'\x00')
else:
structure += pack(self.__getattr__(val), self.length[val]*8)
structure += pack(getattr(self, val), self.length[val]*8)
if val == v:
break
return structure[:-1]
Expand Down
2 changes: 1 addition & 1 deletion pwnlib/rop/rop.py
Expand Up @@ -1274,7 +1274,7 @@ def write(self, s):
pass

def __getattr__(self, k):
return self._fd.__getattribute__(k)
return getattr(self._fd, k)

gadgets = {}
for elf in self.elfs:
Expand Down
4 changes: 3 additions & 1 deletion pwnlib/rop/srop.py
Expand Up @@ -391,7 +391,9 @@ def __setattr__(self, attr, value):
self.set_regvalue(attr, value)

def __getattr__(self, attr):
return self[attr]
if attr in self:
return self[attr]
raise AttributeError(attr)

def __bytes__(self):
frame = b""
Expand Down
2 changes: 1 addition & 1 deletion pwnlib/term/readline.py
Expand Up @@ -486,7 +486,7 @@ def __init__(self, fd):
def readline(self, size = None):
return readline(size)
def __getattr__(self, k):
return self._fd.__getattribute__(k)
return getattr(self._fd, k)
sys.stdin = Wrapper(sys.stdin)

if six.PY2:
Expand Down
2 changes: 1 addition & 1 deletion pwnlib/term/term.py
Expand Up @@ -139,7 +139,7 @@ def __init__(self, fd):
def write(self, s):
output(s, frozen = True)
def __getattr__(self, k):
return self._fd.__getattribute__(k)
return getattr(self._fd, k)
if sys.stdout.isatty():
sys.stdout = Wrapper(sys.stdout)
if sys.stderr.isatty():
Expand Down
3 changes: 3 additions & 0 deletions pwnlib/term/text.py
Expand Up @@ -89,6 +89,9 @@ def f(self, s, when = None):
return functools.partial(f, self)

def __getattr__(self, desc):
if desc.startswith('_'):
raise AttributeError(desc)

try:
ds = desc.replace('gray', 'bright_black').split('_')
init = ''
Expand Down
21 changes: 12 additions & 9 deletions pwnlib/tubes/listen.py
Expand Up @@ -159,15 +159,18 @@ def wait_for_connection(self):
self.sock
return self

def __getattr__(self, key):
if key == 'sock':
self._accepter.join(timeout = self.timeout)
if 'sock' in self.__dict__:
return self.sock
else:
return None
else:
return getattr(super(listen, self), key)
@property
def sock(self):
try:
return self.__dict__['sock']
except KeyError:
pass
self._accepter.join(timeout=self.timeout)
return self.__dict__.get('sock')

@sock.setter
def sock(self, s):
self.__dict__['sock'] = s

def close(self):
# since `close` is scheduled to run on exit we must check that we got
Expand Down
2 changes: 1 addition & 1 deletion pwnlib/tubes/process.py
Expand Up @@ -608,7 +608,7 @@ def __getattr__(self, attr):
"""Permit pass-through access to the underlying process object for
fields like ``pid`` and ``stdin``.
"""
if hasattr(self.proc, attr):
if not attr.startswith('_') and hasattr(self.proc, attr):
return getattr(self.proc, attr)
raise AttributeError("'process' object has no attribute '%s'" % attr)

Expand Down
10 changes: 6 additions & 4 deletions pwnlib/tubes/sock.py
Expand Up @@ -72,8 +72,9 @@ def send_raw(self, data):
raise

def settimeout_raw(self, timeout):
if getattr(self, 'sock', None):
self.sock.settimeout(timeout)
sock = getattr(self, 'sock', None)
if sock:
sock.settimeout(timeout)

def can_recv_raw(self, timeout):
"""
Expand Down Expand Up @@ -161,14 +162,15 @@ def connected_raw(self, direction):
return True

def close(self):
if not getattr(self, 'sock', None):
sock = getattr(self, 'sock', None)
if not sock:
return

# Mark as closed in both directions
self.closed['send'] = True
self.closed['recv'] = True

self.sock.close()
sock.close()
self.sock = None
self._close_msg()

Expand Down
20 changes: 13 additions & 7 deletions pwnlib/tubes/ssh.py
Expand Up @@ -519,13 +519,19 @@ def wait_for_connection(self):
_ = self.sock
return self

def __getattr__(self, key):
if key == 'sock':
while self._accepter.is_alive():
self._accepter.join(timeout = 0.1)
return self.sock
else:
return getattr(super(ssh_listener, self), key)
@property
def sock(self):
try:
return self.__dict__['sock']
except KeyError:
pass
while self._accepter.is_alive():
self._accepter.join(timeout=0.1)
return self.__dict__.get('sock')

@sock.setter
def sock(self, s):
self.__dict__['sock'] = s


class ssh(Timeout, Logger):
Expand Down

0 comments on commit 29c8c0e

Please sign in to comment.