Как я могу `Kernel.load` файл с определением класса в $ SAFE = 1 под Ruby 1.9.2-p180?

#ruby

#ruby

Вопрос:

Я пытаюсь использовать форму с двумя аргументами Kernel.load во время работы на безопасном уровне 1, чтобы загрузить определение класса внутри анонимного пространства имен. Например, файл, который я пытаюсь Kernel.load загрузить, выглядит следующим образом:

 # module.rb
class Foo < Superclass
    def bar
        puts "Bar!"
    end
end
  

И тестовый пример выглядит следующим образом:

 # loader.rb

BASEDIR = File.expand_path( File.dirname(__FILE__) )
MODULE_FILE = File.join( BASEDIR, 'module.rb' ).untaint

$stderr.puts "Module file name (%p) is %s" %
    [ MODULE_FILE, MODULE_FILE.tainted? ? "tainted" : "not tainted" ]

class Superclass
    @subclasses = []
    class << self; attr_reader :subclasses; end
    def self::inherited( subclass )
        super
        @subclasses << subclass
    end
end

$stderr.puts "Ruby version: #{RUBY_DESCRIPTION}"

$stderr.puts "In $SAFE = 0:"
Kernel.load( MODULE_FILE, true )
result = Superclass.subclasses.last
p result
$stderr.puts "Instantiating and calling its #bar method:"
result.new.bar

$stderr.puts "In $SAFE = 1:"
$SAFE = 1
Kernel.load( MODULE_FILE, true )
result = Superclass.subclasses.last
p result
$stderr.puts "Instantiating and calling its #bar method:"
result.new.bar
  

Когда я запускаю его под Ruby 1.8.7, результат выглядит следующим образом:

 Module file name ("/Users/mgranger/source/ruby/misc/safeload/module.rb") is not tainted
Ruby version: ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]
In $SAFE = 0:
#<Module:0x1001688d8>::Foo
Instantiating and calling its #bar method:
Bar!
In $SAFE = 1:
#<Module:0x100168090>::Foo
Instantiating and calling its #bar method:
Bar!
  

но под 1.9.2 я получаю SecurityError:

 Module file name ("/Users/mgranger/source/ruby/misc/safeload/module.rb") is not tainted
Ruby version: ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-darwin10.7.0]
In $SAFE = 0:
#<Module:0x0000010086b5b8>::Foo
Instantiating and calling its #bar method:
Bar!
In $SAFE = 1:
loader.rb:29:in `load': Insecure operation - load (SecurityError)
    from loader.rb:29:in `<main>'
  

Документация в последней версии Pickaxe и на ruby-doc.org скажем Kernel.load , выполняется следующее:

 load(filename, wrap=false) → true
  

Загружает и выполняет программу Ruby в имени файла. Если имя файла не преобразуется в абсолютный путь, файл ищется в каталогах библиотеки, перечисленных в $:. Если необязательный параметр wrap имеет значение true, загруженный скрипт будет выполнен в анонимном модуле, защищающем глобальное пространство имен вызывающей программы. Ни при каких обстоятельствах какие-либо локальные переменные в загруженном файле не будут распространяться в среду загрузки.

Если я заменю определение класса на puts или что-то еще, оно загрузится нормально, так что, похоже, в этом проблема. Я не уверен, что изменилось в 1.9.2 и что мне нужно сделать по-другому, чтобы добиться того же эффекта. Есть идеи?