Lambda is a $SAFEcracker #
MenTaL sends this one in:
pr = lambda { puts "Safelevel: #$SAFE" } $SAFE = 4 pr.call 1.times(&pr)
Bug or feature? Anyone want to help us out here? Globals are thread-local, so it’s not the case with other globals. So what makes $SAFE
so special? (Seen on ~sasada.)
MenTaLguY
More intriguing, why does it work via Proc#call, but never when passing a block (even after it’s been lambda-ized)?
flgr
Isn’t this related to the lambda being created before setting $SAFE? Regarding the block use: I guess that could be related to instance_eval(&pr).
MenTaLguY
flgr: That’s the point—the lambda seems to capture the current value of
$SAFE
as part of its environment.Though, only if you call it via
Proc#call
object—not if youyield
to it. Which is the weird thing.Could you elaborate on the
instance_eval
thing?Fixnum#times
justyields
.matz
the feature. the code wrapped in the lambda is trusted in the level of $SAFE at the time of creation, so that it preserves $SAFE level. If you have found a hole in my logic, enlighten me, please.
MenTaLguY
Hi matz. That seems reasonable.
However, why does yield ignore saved $SAFE level?
matz
two reasons: a) yield sometimes tweak the environment (e.g. self) so that the execution might not be safe anymore. b) it is far more difficult to make it work properly (even if there could be a proper behavior) by the implementation issue.
why
Good answers. Thankyou, Matz.
I like this. It’s a great way of straddling two or more security levels at once without needling to split threads.
Wondering. Are there Railsers who use
$SAFE
?KirinDave
I have an IRC bot that allows users to update modules and channel protection code. I trust them to admin my channel, but not to run arbitrary code on my computer.
$SAFE lets me run their code with a relative degree of safety.
MenTaLguY
I am least surprised that
Continuation
also captures$SAFE
:Lucas
I have tried it in the past and Rails got really mad at me.
Comments are closed for this entry.