-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow modules to optionally import nothing at all #40110
Conversation
See: https://discourse.julialang.org/t/even-more-bare-baremodule/56156/ A module that imports nothing at all can be used to build a sandbox. Sandboxes are useful for defining smaller teaching languages (see Racket and the HTDP2e book) and, if they can be made secure, for evaluating untrusted code in a capability programming paradigm. This commit changes the API of libjulia: Old: JL_DLLEXPORT jl_value_t *jl_f_new_module(jl_sym_t *name, uint8_t std_imports) New: JL_DLLEXPORT jl_value_t *jl_f_new_module(jl_sym_t *name, uint8_t std_imports, uint8_t using_core) Co-authored-by: Simeon Schaub <simeondavidschaub99@gmail.com>
@@ -36,7 +36,7 @@ JL_DLLEXPORT jl_module_t *jl_new_module(jl_sym_t *name) | |||
htable_new(&m->bindings, 0); | |||
arraylist_new(&m->usings, 0); | |||
JL_GC_PUSH1(&m); | |||
if (jl_core_module) { | |||
if (jl_core_module && using_core) { | |||
jl_module_using(m, jl_core_module); | |||
} | |||
// export own name, so "using Foo" makes "Foo" itself visible |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want to omit this as well, just so you can get a truly truly empty module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Triage seconds this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And then I guess using_core
should be renamed default_names
or something like that? Maybe not important.
Here's one of probably many ways to escape the sandbox:
|
@@ -11,7 +11,7 @@ | |||
extern "C" { | |||
#endif | |||
|
|||
JL_DLLEXPORT jl_module_t *jl_new_module(jl_sym_t *name) | |||
JL_DLLEXPORT jl_module_t *jl_new_module_(jl_sym_t *name, uint8_t using_core) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to put this into julia.h
as well?
Yeah, this'll never be an actual approach to making a sandbox (for example, you can also use Also, ref #39114 |
If we wanted to gradually strengthen the sandbox, probably the next step is to make all identifiers that come from syntax (e.g. |
Thanks for the review, everyone! Perhaps I should have been clearer in the first post, I don't think that this feature on its own makes a sandbox, this is just part of what you'd need to do it nicely. You can see my experiments in the discourse thread linked at the top and in https://github.com/cmcaine/Sandboxes.jl The strategy I'm using there takes an Expr and rewrites it to be safe (or just errors). That covers most of @vtjnash's issues (I don't yet rewrite GlobalRefs, but that's possible with this approach, and I wrote code to control what literals can be created (in the discourse thread), too). I think rewriting |
I think it's a bit weird that we allow users to say yes to Perhaps a better interface would be to accept a symbol or enum or something as the second argument, at least on the Julia side? function Module(name::Symbol, type::Symbol)
if type == :module ...
elseif type == :baremodule ...
elseif type == :emptymodule ...
else error()
end
end ? Edit: Jeff suggested passing |
Since this is a pretty internal method, I think it's fine to just have two boolean arguments. I don't really have strong opinions on how to name this option. |
I see some use cases for applying the proposed import rules to the Main module as well. While this is not directly related to this pull request, it is something that could be considered for the future. |
@simeonschaub CI is all green now. Is this good to merge? |
Thanks @cmcaine for the contribution! Sorry it took so long to get merged. |
See: https://discourse.julialang.org/t/even-more-bare-baremodule/56156/ A module that imports nothing at all can be used to build a sandbox. Sandboxes are useful for defining smaller teaching languages (see Racket and the HTDP2e book) and, if they can be made secure, for evaluating untrusted code in a capability programming paradigm. This commit changes the API of libjulia: Old: JL_DLLEXPORT jl_value_t *jl_f_new_module(jl_sym_t *name, uint8_t std_imports) New: JL_DLLEXPORT jl_value_t *jl_f_new_module(jl_sym_t *name, uint8_t std_imports, uint8_t using_core) Co-authored-by: Simeon Schaub <simeondavidschaub99@gmail.com>
See: https://discourse.julialang.org/t/even-more-bare-baremodule/56156/
A module that imports nothing at all can be used to build a sandbox. Sandboxes are useful for defining smaller teaching languages (see Racket and the HTDP2e book) and, if they can be made secure, for evaluating untrusted code in a capability programming paradigm.
This commit changes the API of libjulia:
Old:
New:
With thanks to Simeon Schaub and Mason Protter.
Questions for triage:
I came up with slightly better docs, too, but to save CI energy I haven't pushed them yet. But if anyone wants to bikeshed the docs, here they are:
In NEWS.md:
In doc/src/manual/modules.md: