1

作成しているcmsのテーマをロードしたいと思います。name_of_theme.themespecというファイルを作成することを考えていました。これをロードします。これは、Bundlerがgemspecsで支払うのと同じです。ファイル私は次のようなものを持っているでしょう:

Theme.new do |t|
  t.value = 'hi'
end

スクリプトをロードした後にこのテーマインスタンスをキャプチャしたいのですが、ファイルの内容を取得して評価する必要がありますか?これにより、フォローアップの質問につながります。ファイルの読み込みと内容の読み取りおよび評価の間に違いはありますか。「eval」は破壊の前兆と見なされることが多いことを知っています...おそらくこのユースケース大丈夫ですか?

ファローアップ

選択した回答に基づいて..なぜ私はそれを得るのですか?

evaluationContext = Fiber.new {$SAFE = 4; Fiber.yield binding}.resume
 => #<Binding:0x007f85fc8a0fc8> 
a = evaluationContext.eval('puts $SAFE')
=> 0
4

1 に答える 1

3

いくつかの違いがありますが、既に外部コードを受け入れている場合、ギャップ セキュリティ ホールは、 または のいずれかと同じサイズevalですrequire。この場合、コードが実行される名前空間と安全なレベルを制御できるため、実際にはよりeval安全かもしれません。これは重要です。たとえば、あなたのアプリは誰かの電子メール パスワードを扱うからです。テーマをメインの名前空間 ( ) で実行させると、再定義して悪意のあるサーバーにデータを記録するなど、卑劣なことを行うことができます。このタイプの安全なロードを行う方法は次のとおりです。requireKernel#gets

evaluationContext = Fiber.new {$SAFE = 4; Fiber.yield binding}.resume
theme = evaluationContext.eval(File.read("GrayTheme.themespec"))

注: テーマから呼び出されるコードはすべて $SAFE 4 の下で実行されるため、ほとんどの場合、これで問題ありません ( を呼び出すことはできませんsystem("rm -rf /")) が、テーマから呼び出す必要がある少量の $SAFE 0 コードがありますテーマでは、安全なレベル 0 にいる間にコードをラムダで作成し、安全なレベル 4 のコードに渡す必要があります (ラムダは安全な値を保持するため)。

編集: eval 行を次のように置き換えてみてください:

theme = eval(File.read("blahblahba"), evaluationContext)
于 2012-10-21T13:58:16.430 に答える