Closed manziman closed 1 year ago
do_something()
has to be called inside your source_code
. Calling exec
does not push its definition to the outer (global) namespace.
do_something()
has to be called inside yoursource_code
. Callingexec
does not push its definition to the outer (global) namespace.
That's not true for exec in general, do you mean for how it is being used here specifically? For instance, if I use regular compile
and exec
I can get it to define a function:
source_code = """
def do_something2():
return 'foobar'
"""
try:
byte_code = compile(
source_code,
filename='<inline code>',
mode='exec'
)
exec(byte_code)
except SyntaxError as e:
pass
print(do_something2())
Try it out, this will print foobar
.
This also works as I would expect, using restricted compile the function is defined but is unable to make a call to print
as it has been overridden during compilation:
source_code = """
def do_something():
print('foobar')
"""
byte_code = compile_restricted(
source_code,
filename='<inline code>',
mode='exec'
)
exec(byte_code)
print(type(do_something))
do_something()
This will output:
<class 'function'>
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[8], line 13
11 exec(byte_code)
12 print(type(do_something))
---> 13 do_something()
File <inline code>:2, in do_something()
NameError: name '_print_' is not defined
So, it is defined but does not work.
However if you take the same exact example and override globals in exec
, the function is not defined (as shown in the example above).
I am thinking that I just don't quite understand how the restricted execution works. Does it prevent the executed code from defining functions by default?
@manziman Try assigning the function to a local variable and then access that outside the scope.
Something like this:
source_code = """
def do_something():
return "Something"
result = do_something
"""
locals = {}
try:
byte_code = compile_restricted(
source_code,
filename='<inline code>',
mode='exec'
)
exec(byte_code, {'__builtins__': safe_builtins}, locals)
except SyntaxError as e:
pass
locals['result']()
@bborn I was just wondering if something like that would work - thanks for the tip!
BUG/PROBLEM REPORT / FEATURE REQUEST
Perhaps I don't understand how this is supposed to work, but I cannot get this code to work properly.
I am trying to use RestrictedPython to 'safely' (relatively) execute untrusted code in the form of functions defined in strings.
What I did:
I tried to run the example from the docs, the following code:
What I expect to happen:
do_something()
is defined and executesWhat actually happened:
do_something
is not defined.What version of Python and Zope/Addons I am using:
Python: 3.10 RestrictedPython: 6.0 WSL2 - ubuntu