ruby ​​- почему блоки не наследуют уровень $SAFE вызывающего объекта, как методы?

Когда метод вызывается потоком с $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
7
задан rcrogers 14 June 2012 в 02:34
поделиться