def _solve(self):
import_aliases = (self.context._context['import_aliases'] if self.context else None)
cursor_node = self.tainted_node.parent
while cursor_node != self.target_node:
test_node = cursor_node
cursor_node = cursor_node.parent
if isinstance(test_node, ast.BinOp):
continue
elif isinstance(test_node, ast.Call):
if isinstance(test_node.func, ast.Attribute) and isinstance(test_node.func.value, ast.Str) and test_node.func.attr == 'format':
return True
function = s_utils.get_call_function(test_node, import_aliases=import_aliases)
if function in ('os.path.abspath', 'os.path.join', 'str'):
continue
elif function == 'os.path.relpath' and s_utils.node_is_child_of_parent(test_node.args[0], self.tainted_node):
continue
elif isinstance(test_node, ast.Subscript):
continue
return False
return True
python类Call()的实例源码
def test_dump(self):
node = ast.parse('spam(eggs, "and cheese")')
self.assertEqual(ast.dump(node),
"Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
"args=[Name(id='eggs', ctx=Load()), Str(s='and cheese')], "
"keywords=[], starargs=None, kwargs=None))])"
)
self.assertEqual(ast.dump(node, annotate_fields=False),
"Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
"Str('and cheese')], [], None, None))])"
)
self.assertEqual(ast.dump(node, include_attributes=True),
"Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
"lineno=1, col_offset=0), args=[Name(id='eggs', ctx=Load(), "
"lineno=1, col_offset=5), Str(s='and cheese', lineno=1, "
"col_offset=11)], keywords=[], starargs=None, kwargs=None, "
"lineno=1, col_offset=0), lineno=1, col_offset=0)])"
)
def test_call(self):
func = ast.Name("x", ast.Load())
args = [ast.Name("y", ast.Load())]
keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
stararg = ast.Name("p", ast.Load())
kwarg = ast.Name("q", ast.Load())
call = ast.Call(ast.Name("x", ast.Store()), args, keywords, stararg,
kwarg)
self.expr(call, "must have Load context")
call = ast.Call(func, [None], keywords, stararg, kwarg)
self.expr(call, "None disallowed")
bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
call = ast.Call(func, args, bad_keywords, stararg, kwarg)
self.expr(call, "must have Load context")
call = ast.Call(func, args, keywords, ast.Name("z", ast.Store()), kwarg)
self.expr(call, "must have Load context")
call = ast.Call(func, args, keywords, stararg,
ast.Name("w", ast.Store()))
self.expr(call, "must have Load context")
def _get_ast_name_node(node):
while True:
# only accept '*var'
if isinstance(node, ast.Starred):
# '*var = value' => 'var'
node = node.value
elif isinstance(node, ast.Subscript):
# 'obj[slice] = value' => 'obj'
node = node.value
elif isinstance(node, ast.Attribute):
# 'obj.attr = value' => 'obj'
node = node.value
elif (isinstance(node, ast.Call)
and isinstance(node.func, ast.Attribute)):
# 'obj.method().attr = value' => 'obj.method'
node = node.func
else:
return node
def NAME(self, node):
"""
Handle occurrence of Name (which can be a load/store/delete access.)
"""
# Locate the name in locals / function / globals scopes.
if isinstance(node.ctx, (ast.Load, ast.AugLoad)):
self.handleNodeLoad(node)
if (node.id == 'locals' and isinstance(self.scope, FunctionScope)
and isinstance(node.parent, ast.Call)):
# we are doing locals() call in current scope
self.scope.usesLocals = True
elif isinstance(node.ctx, (ast.Store, ast.AugStore)):
self.handleNodeStore(node)
elif isinstance(node.ctx, ast.Del):
self.handleNodeDelete(node)
else:
# must be a Param context -- this only happens for names in function
# arguments, but these aren't dispatched through here
raise RuntimeError("Got impossible expression context: %r" % (node.ctx,))
def parse_decorator(node: ast.AST):
if isinstance(node, ast.Name):
ret = Decorator()
ret.name = node.id
return ret
elif isinstance(node, ast.Call):
ret = Decorator()
ret.name = node.func.id
for arg in node.args:
if isinstance(arg, ast.Num):
ret.args.append(str(arg.n))
elif isinstance(arg, ast.Str):
ret.args.append(str(arg.n))
elif isinstance(arg, ast.Name):
ret.args.append(arg.id)
else:
v = eval_numeric_constexpr(arg)
if v:
ret.args.append(str(v))
else:
error(loc(node), "Unsupported decorator type")
return ret
else:
error(loc(node), "Supported decorators are Name and Call")
return None
def parse_for_range(node: ast.Call) -> (str, str, str):
if len(node.args) != 3:
error(loc(node), "Expected 3 integer arguments in range(start, end, stop) found: {0}".format(len(node.args)))
return ('ERR', 'ERR', 'ERR')
if isinstance(node.args[0], ast.Name):
ok1, v1 = True, node.args[0].id
else:
ok1, v1 = TO_INT(node.args[0])
if isinstance(node.args[1], ast.Name):
ok2, v2 = True, node.args[1].id
else:
ok2, v2 = TO_INT(node.args[1])
if isinstance(node.args[2], ast.Name):
ok3, v3 = True, node.args[2].id
else:
ok3, v3 = TO_INT(node.args[2])
if ok1 and ok2 and ok3:
return (str(v1), str(v2), str(v3))
return ('ERR', 'ERR', 'ERR')
def PYSL_tl_decl(node: ast.AnnAssign):
"""Parses a specific top-level declaration"""
if not isinstance(node.annotation, ast.Call) or (node.annotation.func.id != 'register' or
len(node.annotation.args) != 2 or
not isinstance(node.annotation.args[0], ast.Name) or
not isinstance(node.annotation.args[1], ast.Num)):
error(loc(node), "Invalid top level resource declaration, see docs. <name> : register(<type>, <slot>) = (...)")
res_name = node.target.id
res_type = node.annotation.args[0].id
res_slot = node.annotation.args[1].n
if res_type in pysl.Language.Sampler.TYPES:
emitter.sampler(parse_sampler(node, res_name, res_type[7:], res_slot, node.value))
else:
error((node), "Unrecognized top-level resource declaration {0} : {1}".format(res_name, res_type))
def _Call(self, t):
if isinstance(t, ast.Call):
super()._Call(t)
return
self.dispatch(t.func)
self.write("(")
comma = False
for e in t.args:
if comma:
self.write(", ")
else:
comma = True
self.dispatch(e)
for e in t.keywords:
if comma:
self.write(", ")
else:
comma = True
self.dispatch(e)
self.write(")")
def parse_factor_expression(call_or_name_node):
if isinstance(call_or_name_node, ast.Name): # a.set_to(b) is shorthand for a.set_to(Copy(b))
name_node = call_or_name_node
return None, [name_node.id]
elif isinstance(call_or_name_node, ast.Call): # a.set_to(f(b))
call_node = call_or_name_node
return call_node.func.id, [name_or_number(node) for node in call_node.args]
elif isinstance(call_or_name_node, ast.Num): # a.observe_value(0)
num_node = call_or_name_node
return None, [int(num_node.n)]
elif isinstance(call_or_name_node, ast.Subscript):
print ast.dump(call_or_name_node)
pdb.set_trace()
else:
assert False, "Can't parse factor " + ast.dump(call_or_name_node)
def parse(self, assign_node):
if len(assign_node.targets) > 1: return False
if u.is_constant_definition(assign_node):
return None
self.name = assign_node.targets[0].id
rhs = assign_node.value
if isinstance(rhs, ast.Call):
call_node = u.cast(rhs, ast.Call)
self.parse_call(call_node)
self.array_size = None
elif isinstance(rhs, ast.Subscript):
subscript_node = u.cast(rhs, ast.Subscript)
call_node = u.cast(subscript_node.value, ast.Call)
self.parse_call(call_node)
self.array_size = u.get_index(subscript_node)
def visit_For(self, forstmt):
s = ""
if isinstance(forstmt.iter, ast.Call) \
and isinstance(forstmt.iter.func, ast.Name) \
and forstmt.iter.func.id == "range":
iter_var = self.visit(forstmt.target)
if len(forstmt.iter.args) == 1:
iter_len = self.visit(forstmt.iter.args[0])
s += "for (int %s = 0; %s < %s; %s++) {\n" % (iter_var, iter_var,
iter_len, iter_var)
else:
iter_start = self.visit(forstmt.iter.args[0])
iter_len = self.visit(forstmt.iter.args[1])
s += "for (int %s = %s; %s < %s; %s++) {\n" % (iter_var, iter_start,
iter_var, iter_len,
iter_var)
s += self.visit_block(forstmt.body)
s += "}\n"
return s
else:
raise "only for var in range(a) loops supported currently"
def check_reshape(node):
if not isinstance(node, ast.Call):
return
if not isinstance(node.func, ast.Attribute):
return
if isinstance(node.func.value, ast.Name) and \
node.func.value.id in {'np', 'cupy', 'F'}:
return
if not node.func.attr == 'reshape':
return
if len(node.args) > 1:
yield (node.lineno, 'reshape(A, B, ...)')
if len(node.args) == 1 and \
isinstance(node.args[0], ast.Tuple) and \
len(node.args[0].elts) == 1:
yield (node.lineno, 'reshape((A,))')
def check_transpose(node):
if not isinstance(node, ast.Call):
return
if not isinstance(node.func, ast.Attribute):
return
if isinstance(node.func.value, ast.Name) and \
node.func.value.id in {'np', 'cupy', 'F'}:
return
if not node.func.attr == 'transpose':
return
if len(node.args) > 1:
yield (node.lineno, 'transpose(A, B, ...)')
if len(node.args) == 1 and \
isinstance(node.args[0], ast.Tuple) and \
len(node.args[0].elts) == 1:
yield (node.lineno, 'transpose((A,))')
def Call(fn, args):
return ast.Call(fn, args, [], None, None)
def visit_Assert(self, t):
return ast.If(t.test,
[],
[ast.Raise(Call(ast.Name('AssertionError', load),
[] if t.msg is None else [t.msg]),
None)])
def visit_FunctionDef(self, t):
fn = Function(t.name, t.args, t.body)
for d in reversed(t.decorator_list):
fn = Call(d, [fn])
return ast.Assign([ast.Name(t.name, store)], fn)
def visit_ListComp(self, t):
result_append = ast.Attribute(ast.Name('.0', load), 'append', load)
body = ast.Expr(Call(result_append, [t.elt]))
for loop in reversed(t.generators):
for test in reversed(loop.ifs):
body = ast.If(test, [body], [])
body = ast.For(loop.target, loop.iter, [body], [])
fn = [body,
ast.Return(ast.Name('.0', load))]
args = ast.arguments([ast.arg('.0', None)], None, [], None, [], [])
return Call(Function('<listcomp>', args, fn),
[ast.List([], load)])
def visit_Assert(self, t):
t = self.generic_visit(t)
result = ast.If(t.test,
[],
[ast.Raise(Call(ast.Name('AssertionError', load),
[] if t.msg is None else [t.msg]),
None)])
return ast.copy_location(result, t)
def visit_ListComp(self, t):
t = self.generic_visit(t)
add_element = ast.Attribute(ast.Name('.elements', load), 'append', load)
body = ast.Expr(Call(add_element, [t.elt]))
for loop in reversed(t.generators):
for test in reversed(loop.ifs):
body = ast.If(test, [body], [])
body = ast.For(loop.target, loop.iter, [body], [])
fn = [body,
ast.Return(ast.Name('.elements', load))]
args = ast.arguments([ast.arg('.elements', None)], None, [], None, [], [])
result = Call(Function('<listcomp>', args, fn),
[ast.List([], load)])
return ast.copy_location(result, t)