nest-server: BadRequest: 400 Bad Request: name '<function name>' is not defined#3592
nest-server: BadRequest: 400 Bad Request: name '<function name>' is not defined#3592med-ayssar wants to merge 3 commits intonest:mainfrom
Conversation
|
@med-ayssar Thanks for the PR! Have you confirmed that the problem still exists with NEST 3.9? It was originally reported against 3.4 and a number of things have happened in NEST Server since then, I believe. Adding @Helveg as a reviewer who has discovered security issues in the server earlier, as I am concerned about potential risks in making globals to locals. @babsey I started NEST server on my computer (Auth disabled) and confirmed that I can connect to it. But when I then try to run a script from file, I just get the content of the file displayed and What am I doing wrong? |
|
Yeah, I tested it yesterday with the current master, and it did not work. The To make it work, you need to set ( Export ) one environment variable, check the |
|
Example: >>> source = """
... def y():
... return 5
...
... def z():
... return y()
...
... print(z())
... """
>>> exec(source)
5
>>> exec(source, {})
5
>>> exec(source, {}, {})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 8, in <module>
File "<string>", line 6, in z
NameError: name 'y' is not definedWhich is explained by the note in the docs on
The solution proposed by @med-ayssar is essentially summarized as follows: globals_ = get_restricted_globals() # Create a safe dictionary
locals_ = globals_
exec(source, globals_, locals_)which is actually equivalent to So why are we even passing in globals_ = ...
locals_ = {}
exec(source, globals_, locals_)
response["stdout"] = "".join(locals_["_print"].txt)The purpose of this seems to be to capture stdout while inside of the exec("x = 5") # which is equivalent to exec(code, globals(), locals())
print(locals()["x"]) # prints 5: `exec(code)` occurs within current namespace, and would mutate/pollute it.this breaks in Python 3.13 after the change of the semantics (see python/cpython#118888). Given all this information, I think the safest and clearest way to achieve the desired behavior here is to simply not create any def do_exec(args, kwargs):
source_code = kwargs.get("source", "")
source_cleaned = clean_code(source_code)
response = dict()
if RESTRICTION_DISABLED:
with Capturing() as stdout:
globals_ = globals().copy()
globals_.update(get_modules_from_env())
get_or_error(exec)(source_cleaned, globals_)
if len(stdout) > 0:
response["stdout"] = "\n".join(stdout)
else:
code = RestrictedPython.compile_restricted(source_cleaned, "<inline>", "exec") # noqa
globals_ = get_restricted_globals()
globals_.update(get_modules_from_env())
get_or_error(exec)(code, globals_)
if "_print" in globals_:
response["stdout"] = "".join(globals_["_print"].txt)The only possible change that might occur compared to the current source code (which is also a caveat of @med-ayssar's proposal) is if |
|
I agree with @Helveg. As he suggested that you just remove Let review simple samples: and with locals: To me, it looks that locals arg in exec function causes this issue #2666. |
|
Pull request automatically marked stale! |
|
@ayssar100 Friendly ping! |
babsey
left a comment
There was a problem hiding this comment.
Remove locals_ variable at line 195 and rename locals_ to globals_ at lines 215 - 218
1610b57 to
87308e8
Compare
|
Sorry, here you go! |
I wonder how did you get that account ID there. |
I apologize, I wrote your last name and took the first suggestion without checking it. |
|
@med-ayssar I tried to create a PR to your branch So, I write here what you need to change these lines before I give a LGTM! sign.
|
|
It should be correct now. |
Helveg
left a comment
There was a problem hiding this comment.
I think this still does not do what reviewers agreed on:
locals_on line 195 should be removed- The
get_or_error(exec)(code, globals_, locals_)calls should be changed toget_or_error(exec)(code, globals_)
|
@heplesser @Helveg Friendly ping! |
|
main needs to be merged for the macos build to succeed. (i think, @heplesser sent an email on this) |
Done |
|
Friendly ping! |
|
Friendly ping! Why is it still open? 2 reviewers approved the changes. |
Fixes #2666
exec(script: string|bytes, globals: dict, locals: dict):here, we must set
localstoglobals, to be able to call the defined functions within other defined functions.