Skip to content

Commit

Permalink
Use modern inspect.signature
Browse files Browse the repository at this point in the history
While at it, drop the hard-to-maintain code.
We lose the signature in py2, but its support is second-class anyway.

Fixes Gallopsled#2145
Closes Gallopsled#2148
  • Loading branch information
Arusekk authored and vboxuser committed Sep 10, 2023
1 parent e4fc518 commit 079ee78
Showing 1 changed file with 11 additions and 43 deletions.
54 changes: 11 additions & 43 deletions pwnlib/shellcraft/internal.py
Expand Up @@ -2,6 +2,7 @@
from __future__ import division

import os
import sys

from pwnlib.context import context

Expand Down Expand Up @@ -109,47 +110,17 @@ def get_context_from_dirpath(directory):
return {'os': osys, 'arch': arch}

def make_function(funcname, filename, directory):
import functools
import inspect
path = os.path.join(directory, filename)
template = lookup_template(path)

args, varargs, keywords, defaults = inspect.getargspec(template.module.render_body)

defaults = defaults or []

if len(defaults) < len(args) and args[0] == 'context':
args.pop(0)

args_used = args[:]

for n, default in enumerate(defaults, len(args) - len(defaults)):
args[n] = '%s = %r' % (args[n], default)

if varargs:
args.append('*' + varargs)
args_used.append('*' + varargs)

if keywords not in ['pageargs', None]:
args.append('**' + keywords)
args_used.append('**' + keywords)

docstring = inspect.cleandoc(template.module.__doc__ or '')
args = ', '.join(args)
args_used = ', '.join(args_used)
local_ctx = get_context_from_dirpath(directory)

# This is a slight hack to get the right signature for the function
# It would be possible to simply create an (*args, **kwargs) wrapper,
# but what would not have the right signature.
# While we are at it, we insert the docstring too
T = r'''
def wrap(template, render_global):
import pwnlib
def %(funcname)s(%(args)s):
%(docstring)r
def res(*args, **kwargs):
with render_global.go_inside() as was_inside:
with pwnlib.context.context.local(**%(local_ctx)s):
lines = template.render(%(args_used)s).split('\n')
with context.local(**local_ctx):
lines = template.render(*args, **kwargs).split('\n')
for i, line in enumerate(lines):
def islabelchar(c):
return c.isalnum() or c == '.' or c == '_'
Expand All @@ -168,19 +139,16 @@ def islabelchar(c):
return s
else:
return s + '\n'
return %(funcname)s
''' % locals()

g = {}
exec(T, g, g)
wrap = g['wrap']

# Setting _relpath is a slight hack only used to get better documentation
res = wrap(template, render_global)
res._relpath = path
res.__module__ = 'pwnlib.shellcraft.' + os.path.dirname(path).replace('/','.')

import sys, functools
res.__name__ = res.__qualname__ = funcname
res.__doc__ = inspect.cleandoc(template.module.__doc__ or '')
if hasattr(inspect, 'signature'):
sig = inspect.signature(template.module.render_body)
sig = sig.replace(parameters=list(sig.parameters.values())[1:-1])
res.__signature__ = sig

@functools.wraps(res)
def function(*a):
Expand Down

0 comments on commit 079ee78

Please sign in to comment.