回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我正在尝试限制用户提供的脚本,并使用以下访问者:</p>
<pre><code>class SyntaxChecker(ast.NodeVisitor):
def check(self, syntax):
tree = ast.parse(syntax)
print(ast.dump(tree), syntax)
self.visit(tree)
def visit_Call(self, node):
print('Called for Call', ast.dump(node))
if isinstance(node.func, ast.Call) and node.func.id not in allowed_functions:
raise CodeError("%s is not an allowed function!"%node.func.id)
elif isinstance(node.func, ast.Attribute) and node.func.value.id not in allowed_classes:
raise CodeError('{0} is not calling an allowed class'.format(node.func.value.id))
elif isinstance(node.func, ast.Name) and node.func.id in allowed_classes:
raise CodeError('You are not allowed to instantiate any class, {0}'.format(node.func.id))
else:
ast.NodeVisitor.generic_visit(self, node)
def visit_Assign(self, node):
print('Called for Assign', ast.dump(node))
ast.NodeVisitor.generic_visit(self, node)
def visit_Attribute(self, node):
print('Called for Attribute', ast.dump(node))
if node.value.id not in allowed_classes:
raise CodeError('"{0}" is not an allowed class'.format(node.value.id))
elif node.value.id in allowed_classes and isinstance(node.ctx, ast.Store):
raise CodeError('Trying to change something in a pre-defined class, "{0}" in "{1}"'.format(node.attr, node.value.id))
else:
ast.NodeVisitor.generic_visit(self, node)
def visit_Expr(self, node):
print('Called for Expr', ast.dump(node))
ast.NodeVisitor.generic_visit(self, node)
def visit_Name(self, node):
print('Called for Name', ast.dump(node))
if isinstance(node.ctx, ast.Store) and node.id in allowed_classes:
raise CodeError('Trying to change a pre-defined class, {0}'.format(node.id))
elif isinstance(node.ctx, ast.Load) and node.id not in safe_names and node.id not in allowed_functions and node.id not in allowed_classes:
raise CodeError('"{0}" function is not allowed'.format(node.id))
else:
ast.NodeVisitor.generic_visit(self, node)
def generic_visit(self, node):
print('Called for generic', ast.dump(node))
if type(node).__name__ not in allowed_node_types:
raise CodeError("%s is not allowed!"%type(node).__name__)
else:
ast.NodeVisitor.generic_visit(self, node)
if __name__ == '__main__':
# Check whole file
x = SyntaxChecker()
code = open(sys.argv[1], 'r').read()
try:
x.check(code)
except CodeError as e:
print(repr(e))
# Or check line by line, considering multiline statements
code = ''
for line in open(sys.argv[1], 'r'):
line = line.strip()
if line:
code += line
try:
print('[{0}]'.format(code))
x.check(code)
code = ''
except CodeError as e:
print(repr(e))
break
except SyntaxError as e:
print('********Feeding next line', repr(e))
</code></pre>
<p>它目前运行良好,我将对其进行更多的调优,但问题是,在解析类似这样的东西时,它总是抛出<code>SyntaxError('unexpected EOF while parsing', ('<unknown>', 1, 15, 'for j in A.b():'))</code></p>
^{pr2}$
<p>因此,不会解析<code>for</code>或{<cd3>}。在</p>
<p>编辑:我添加了一个代码来检查整个代码,或者检查多行语句。在</p>