Make `$SAFE` process global state and allow to set 0 again
$SAFE > 1 is removed from Ruby 2.3 and there are some opinion to remove
$SAFE feature ([Feature #5455]).
There are several reason, but the biggest reason I think is nobody use
$SAFE is thread/proc local information and it hurts performance (we need to restore
$SAFE information just after returning proc, even if returning by exception).
$SAFE == 1 is similar to warning and it is not a security feature, but one of the programming tool we can use to improve our program (
$SAFE == 3 was for sandbox, security feature).
From this perspective, Matz approved us the followings:
$SAFEis process global, not a Proc local state.
- We can set
$SAFE == 0when
$SAFE == 1.
I think we can't make big project with the above changes (how to make multi-thread programming with this
$SAFE seems for small project (so-called scripting). Anyway if nobody use it, no problem on these changes.
I will commit this change soon.
Please try new spec and point out any problem you got.
Updated by shevegen (Robert A. Heiler) over 2 years ago
Can not comment on $SAFE but I personally have not used $SAFE so far in
like +10 years or so. I can only remember the pickaxe mentioning it, but
I have not used it in any of my ruby code.
A bit off-topic but does anyone remember if _why's old ruby sandbox (the
online irb, I think), made use of it? For such projects, trivial ways
to control how "safe" the ruby is, may be more useful. E. g. in any
restricted environment such as that.
Updated by mame (Yusuke Endoh) over 2 years ago
FYI: by using gem-codesearch, I have briefly searched the gems using $SAFE:
$ csearch -f '.*\.rb' '^\s*[^\s#].*\$SAFE *=' | wc -l 147
Much less than I thought... The full list is attached.
Updated by ko1 (Koichi Sasada) over 2 years ago
- Status changed from Open to Closed
Applied in changeset trunk|r61510.
$SAFE as a process global state. [Feature #14250]
vm_core.h (rb_vm_t): move
$SAFEis a process (VM) global state.
vm_core.h (rb_proc_t): remove
objects don't need to keep
$SAFEat the creation.
is_lambdaas 1 bit fields.
cont.c (cont_restore_thread): no need to keep
eval.c (ruby_cleanup): use
rb_set_safe_level_force()instead of access
eval_jump.c: End procs
proc.c (proc_dup): removed and introduce
safe.c (rb_set_safe_level): don't check
$SAFE1 -> 0 changes.
safe.c (safe_setter): use
It should be obsolete.
0 or 1 so that this check is not needed.
vm.c (vm_proc_create_from_captured): don't need to keep
vm.c (rb_proc_create): renamed to
vm.c (rb_proc_dup): moved from proc.c.
vm.c (vm_invoke_proc): do not need to set and restore
vm_eval.c (rb_eval_cmd): rename a local variable to represent clearer
$SAFE == 0at the end of tests.
test/rubygems/test_gem.rb: do not set
$SAFE = 1.
bootstraptest/test_proc.rb: catch up this change.