2012-10-21 20 views
1

我想加載一個主題我正在建立一個CMS ..我正在考慮有一個名爲name_of_theme.themespec的文件..我會加載這個..類似於Bundler與gemspecs會費..我在想,這個文件中我會是這樣的:如何從紅寶石加載中獲取返回值?

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

我想加載腳本..如果我只是搶了文件的內容和eval後,他們捕捉到這個主題的實例?這導致我後續的問題是加載文件..和閱讀內容和評估之間有任何區別..我知道'eval'通常被認爲是毀滅的先兆...也許這個用例好嗎?

跟進基於選擇的答案

..那爲什麼我得到:

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

回答

3

嗯,有一些差別,但如果你已經接受外部代碼時,間隙安全孔與evalrequire的尺寸相同。在這種情況下,實際上,eval可能是更多安全,因爲它可以讓您控制代碼執行的名稱空間和安全級別。這很重要,因爲你的應用處理某人的電子郵件密碼。如果讓主題在主名稱空間(require)中執行,它可以做一些卑鄙的事情,如重新定義Kernel#gets以將數據記錄到惡意服務器等。儘管聽起來很遙遠,但最好是安全。因此,這裏是你如何能做到這種類型的安全負荷:

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

注:任何從主題叫代碼將在$ SAFE 4被執行,因此,儘管對於大多數情況,這是很好的(他們不能打電話如果有一小部分$ SAFE 0代碼需要從主題中調用,代碼必須在lambda表達式中創建,而您仍然處於安全級別0,然後傳遞給安全級別的代碼4(因爲lambda保持其安全價值)。

編輯:嘗試用這種替代EVAL行:

theme = eval(File.read("blahblahba"), evaluationContext) 
+0

感謝@Linuxios,你給了我足夠的信息,到這裏開始,我覺得夠了概念我不知道,以瞭解更多的這個領域..我沒有意識到線程的安全級別..欣賞它。 – Inc1982

+0

@ Inc1982:當然。如果您有任何問題,請留下評論。這是一個很難的話題,而我實際上在嘗試編寫沙箱代碼時發現了這一點。 – Linuxios

+0

我根據你的回答添加了一個跟進問題..想知道你是否可以看看它。爲什麼$ SAFE的提示是說0,儘管從Fibre的綁定上下文執行? – Inc1982