Spaces:
Sleeping
Sleeping
Fixing a bug
Browse files
restrictedpython_code_eval.py
CHANGED
@@ -155,6 +155,54 @@ class AllowAugmentedAssignAndUnderscoreVariableNamesRestrictingTransformer(Allow
|
|
155 |
def __init__(self, *args, **kwargs):
|
156 |
super().__init__(*args, **kwargs)
|
157 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
def check_name(self, node, name, allow_magic_methods=False):
|
159 |
if name is None:
|
160 |
return
|
|
|
155 |
def __init__(self, *args, **kwargs):
|
156 |
super().__init__(*args, **kwargs)
|
157 |
|
158 |
+
def visit_Attribute(self, node):
|
159 |
+
"""Checks and mutates attribute access/assignment.
|
160 |
+
|
161 |
+
'a.b' becomes '_getattr_(a, "b")'
|
162 |
+
'a.b = c' becomes '_write_(a).b = c'
|
163 |
+
'del a.b' becomes 'del _write_(a).b'
|
164 |
+
|
165 |
+
The _write_ function should return a security proxy.
|
166 |
+
"""
|
167 |
+
# Overriding here to allow select underscore names
|
168 |
+
if node.attr.startswith('_') and node.attr != '_' and node.attr not in ALLOWED_UNDERSCORE_NAMES:
|
169 |
+
self.error(
|
170 |
+
node,
|
171 |
+
'"{name}" is an invalid attribute name because it starts '
|
172 |
+
'with "_".'.format(name=node.attr))
|
173 |
+
|
174 |
+
if node.attr.endswith('__roles__'):
|
175 |
+
self.error(
|
176 |
+
node,
|
177 |
+
'"{name}" is an invalid attribute name because it ends '
|
178 |
+
'with "__roles__".'.format(name=node.attr))
|
179 |
+
|
180 |
+
if isinstance(node.ctx, ast.Load):
|
181 |
+
node = self.node_contents_visit(node)
|
182 |
+
new_node = ast.Call(
|
183 |
+
func=ast.Name('_getattr_', ast.Load()),
|
184 |
+
args=[node.value, ast.Str(node.attr)],
|
185 |
+
keywords=[])
|
186 |
+
|
187 |
+
copy_locations(new_node, node)
|
188 |
+
return new_node
|
189 |
+
|
190 |
+
elif isinstance(node.ctx, (ast.Store, ast.Del)):
|
191 |
+
node = self.node_contents_visit(node)
|
192 |
+
new_value = ast.Call(
|
193 |
+
func=ast.Name('_write_', ast.Load()),
|
194 |
+
args=[node.value],
|
195 |
+
keywords=[])
|
196 |
+
|
197 |
+
copy_locations(new_value, node.value)
|
198 |
+
node.value = new_value
|
199 |
+
return node
|
200 |
+
|
201 |
+
else: # pragma: no cover
|
202 |
+
# Impossible Case only ctx Load, Store and Del are defined in ast.
|
203 |
+
raise NotImplementedError(
|
204 |
+
f"Unknown ctx type: {type(node.ctx)}")
|
205 |
+
|
206 |
def check_name(self, node, name, allow_magic_methods=False):
|
207 |
if name is None:
|
208 |
return
|