Skip to content

Commit 8f42bef

Browse files
committed
Use modern inspect.signature
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
1 parent 020143f commit 8f42bef

File tree

1 file changed

+11
-43
lines changed

1 file changed

+11
-43
lines changed

pwnlib/shellcraft/internal.py

Lines changed: 11 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from __future__ import division
33

44
import os
5+
import sys
56

67
from pwnlib.context import context
78

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

111112
def make_function(funcname, filename, directory):
113+
import functools
112114
import inspect
113115
path = os.path.join(directory, filename)
114116
template = lookup_template(path)
115117

116-
args, varargs, keywords, defaults = inspect.getargspec(template.module.render_body)
117-
118-
defaults = defaults or []
119-
120-
if len(defaults) < len(args) and args[0] == 'context':
121-
args.pop(0)
122-
123-
args_used = args[:]
124-
125-
for n, default in enumerate(defaults, len(args) - len(defaults)):
126-
args[n] = '%s = %r' % (args[n], default)
127-
128-
if varargs:
129-
args.append('*' + varargs)
130-
args_used.append('*' + varargs)
131-
132-
if keywords not in ['pageargs', None]:
133-
args.append('**' + keywords)
134-
args_used.append('**' + keywords)
135-
136-
docstring = inspect.cleandoc(template.module.__doc__ or '')
137-
args = ', '.join(args)
138-
args_used = ', '.join(args_used)
139118
local_ctx = get_context_from_dirpath(directory)
140119

141-
# This is a slight hack to get the right signature for the function
142-
# It would be possible to simply create an (*args, **kwargs) wrapper,
143-
# but what would not have the right signature.
144-
# While we are at it, we insert the docstring too
145-
T = r'''
146-
def wrap(template, render_global):
147-
import pwnlib
148-
def %(funcname)s(%(args)s):
149-
%(docstring)r
120+
def res(*args, **kwargs):
150121
with render_global.go_inside() as was_inside:
151-
with pwnlib.context.context.local(**%(local_ctx)s):
152-
lines = template.render(%(args_used)s).split('\n')
122+
with context.local(**local_ctx):
123+
lines = template.render(*args, **kwargs).split('\n')
153124
for i, line in enumerate(lines):
154125
def islabelchar(c):
155126
return c.isalnum() or c == '.' or c == '_'
@@ -168,19 +139,16 @@ def islabelchar(c):
168139
return s
169140
else:
170141
return s + '\n'
171-
return %(funcname)s
172-
''' % locals()
173-
174-
g = {}
175-
exec(T, g, g)
176-
wrap = g['wrap']
177142

178143
# Setting _relpath is a slight hack only used to get better documentation
179-
res = wrap(template, render_global)
180144
res._relpath = path
181145
res.__module__ = 'pwnlib.shellcraft.' + os.path.dirname(path).replace('/','.')
182-
183-
import sys, functools
146+
res.__name__ = res.__qualname__ = funcname
147+
res.__doc__ = inspect.cleandoc(template.module.__doc__ or '')
148+
if hasattr(inspect, 'signature'):
149+
sig = inspect.signature(template.module.render_body)
150+
sig = sig.replace(parameters=list(sig.parameters.values())[1:-1])
151+
res.__signature__ = sig
184152

185153
@functools.wraps(res)
186154
def function(*a):

0 commit comments

Comments
 (0)