guydav commited on
Commit
9c016e9
1 Parent(s): ae3aa83

Fixing a bug

Browse files
Files changed (1) hide show
  1. restrictedpython_code_eval.py +48 -0
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