Когда метод вызывается потоком с $SAFE = 4, этот метод запускается с тем же уровнем $SAFE:
def test_method
raise "value of $SAFE inside the method: #{$SAFE}"
end
t = Thread.new{$SAFE = 4; self.test_method}; t.join
=> RuntimeError: value of $SAFE inside the method: 4
Однако при вызове блока кажется, что он использует $SAFE из вместо этого исходный контекст:
test_lambda = lambda do
raise "value of $SAFE inside the lambda: #{$SAFE}"
end
t = Thread.new{$SAFE = 4; test_lambda.call}; t.join
=> RuntimeError: value of $SAFE inside the lambda: 0
Кто-нибудь может объяснить, почему это работает именно так? Похоже на проблему с безопасностью.
(причина, по которой я использую raise
вместо puts
, заключается в том, что puts
не работает при $SAFE = 4)
Это может использоваться для оценки испорченной строки в, казалось бы, безопасном контексте:
test_lambda = lambda{|s| puts "Tainted: #{s.tainted?}"; eval s}
t = Thread.new{$SAFE = 4; test_lambda.call("puts `date`")}; t.join
=> Tainted: true
=> Fri Mar 30 03:15:33 UTC 2012