• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Gallopsled / pwntools / 8912ca5a8c3a9725c3ba6d30561607150a6faebe-PR-2205

pending completion
8912ca5a8c3a9725c3ba6d30561607150a6faebe-PR-2205

Pull #2205

github-actions

web-flow
Merge 81f463e2c into 8b4cacf8b
Pull Request #2205: Fix stable Python 2 installation from a built wheel

3878 of 6371 branches covered (60.87%)

12199 of 16604 relevant lines covered (73.47%)

0.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.68
/pwnlib/shellcraft/internal.py
1
from __future__ import absolute_import
1✔
2
from __future__ import division
1✔
3

4
import os
1✔
5
import sys
1✔
6

7
from pwnlib.context import context
1✔
8

9
__all__ = ['make_function']
1✔
10

11
loaded = {}
1✔
12
lookup = None
1✔
13
def init_mako():
1✔
14
    global lookup, render_global
15
    from mako.lookup import TemplateLookup
1✔
16
    from mako.parsetree import Tag, Text
1✔
17
    from mako import ast
1✔
18
    import threading
1✔
19

20
    if lookup is not None:
1✔
21
        return
1✔
22

23
    class IsInsideManager(object):
1✔
24
        def __init__(self, parent):
1✔
25
            self.parent = parent
1✔
26
        def __enter__(self):
1✔
27
            self.oldval = self.parent.is_inside
1✔
28
            self.parent.is_inside = True
1✔
29
            return self.oldval
1✔
30
        def __exit__(self, *args):
1✔
31
            self.parent.is_inside = self.oldval
1✔
32

33
    class IsInside(threading.local):
1✔
34
        is_inside = False
1✔
35

36
        def go_inside(self):
1✔
37
            return IsInsideManager(self)
1✔
38

39
    render_global = IsInside()
1✔
40

41
    cache  = context.cache_dir
1✔
42
    if cache:
1!
43
        cache = os.path.join(cache, 'mako')
1✔
44

45
    curdir = os.path.dirname(os.path.abspath(__file__))
1✔
46
    lookup = TemplateLookup(
1✔
47
        directories      = [os.path.join(curdir, 'templates')],
48
        module_directory = cache
49
    )
50

51
    # The purpose of this definition is to create a new Tag.
52
    # The Tag has a metaclass, which saves this definition even
53
    # though to do not use it here.
54
    class pwn_docstring(Tag):
1✔
55
        __keyword__ = 'docstring'
1✔
56

57
        def __init__(self, *args, **kwargs):
1✔
58
            super(pwn_docstring, self).__init__('docstring', (), (), (), (), **kwargs)
1✔
59
            self.ismodule = True
1✔
60

61
        @property
1✔
62
        def text(self):
63
            children = self.get_children()
1✔
64
            if len(children) != 1 or not isinstance(children[0], Text):
1!
65
                raise Exception("docstring tag only supports text")
×
66

67
            docstring = children[0].content
1✔
68

69
            return '__doc__ = %r' % docstring
1✔
70

71
        @property
1✔
72
        def code(self):
73
            return ast.PythonCode(self.text)
×
74

75
        def accept_visitor(self, visitor):
1✔
76
            method = getattr(visitor, "visitCode", lambda x: x)
1!
77
            method(self)
1✔
78

79
def lookup_template(filename):
1✔
80
    init_mako()
1✔
81

82
    if filename not in loaded:
1!
83
        loaded[filename] = lookup.get_template(filename)
1✔
84

85
    return loaded[filename]
1✔
86

87
def get_context_from_dirpath(directory):
1✔
88
    """
89
    >>> get_context_from_dirpath('common')
90
    {}
91
    >>> get_context_from_dirpath('i386')
92
    {'arch': 'i386'}
93
    >>> get_context_from_dirpath('amd64/linux') == {'arch': 'amd64', 'os': 'linux'}
94
    True
95
    """
96
    parts = directory.split(os.path.sep)
1✔
97

98
    arch = osys = None
1✔
99

100
    if len(parts) > 0:
1!
101
        arch = parts[0]
1✔
102
    if len(parts) > 1:
1✔
103
        osys = parts[1]
1✔
104

105
    if osys == 'common':
1!
106
        osys = None
×
107
    if arch == 'common':
1✔
108
        arch = None
1✔
109

110
    return {'os': osys, 'arch': arch}
1✔
111

112
def make_function(funcname, filename, directory):
1✔
113
    import functools
1✔
114
    import inspect
1✔
115
    path       = os.path.join(directory, filename)
1✔
116
    template   = lookup_template(path)
1✔
117

118
    local_ctx = get_context_from_dirpath(directory)
1✔
119

120
    def res(*args, **kwargs):
1✔
121
        with render_global.go_inside() as was_inside:
1✔
122
            with context.local(**local_ctx):
1✔
123
                lines = template.render(*args, **kwargs).split('\n')
1✔
124
        for i, line in enumerate(lines):
1✔
125
            def islabelchar(c):
1✔
126
                return c.isalnum() or c == '.' or c == '_'
1✔
127
            if ':' in line and islabelchar(line.lstrip()[0]):
1✔
128
                line = line.lstrip()
1✔
129
            elif line.startswith(' '):
1✔
130
                 line = '    ' + line.lstrip()
1✔
131
            lines[i] = line
1✔
132
        while lines and not lines[-1]: lines.pop()
1✔
133
        while lines and not lines[0]:  lines.pop(0)
1✔
134
        s = '\n'.join(lines)
1✔
135
        while '\n\n\n' in s:
1!
136
            s = s.replace('\n\n\n', '\n\n')
×
137

138
        if was_inside:
1✔
139
            return s
1✔
140
        else:
141
            return s + '\n'
1✔
142

143
    # Setting _relpath is a slight hack only used to get better documentation
144
    res._relpath = path
1✔
145
    res.__module__ = 'pwnlib.shellcraft.' + os.path.dirname(path).replace('/','.')
1✔
146
    res.__name__ = res.__qualname__ = funcname
1✔
147
    res.__doc__ = inspect.cleandoc(template.module.__doc__ or '')
1✔
148
    if hasattr(inspect, 'signature'):
1!
149
        sig = inspect.signature(template.module.render_body)
×
150
        sig = sig.replace(parameters=list(sig.parameters.values())[1:-1])
×
151
        res.__signature__ = sig
×
152

153
    @functools.wraps(res)
1✔
154
    def function(*a):
155
        return sys.modules[res.__module__].function(res.__name__, res, *a)
×
156
    @functools.wraps(res)
1✔
157
    def call(*a):
158
        return sys.modules[res.__module__].call(res.__name__, *a)
×
159

160
    res.function = function
1✔
161
    res.call     = call
1✔
162

163
    return res
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc