2012-10-21 1 views
1

나는 건물에있는 Cms에 대한 테마를로드하고 싶습니다. name_of_theme.themespec이라는 파일을 가지고 있다고 생각했습니다.이 파일을로드 할 것이고 Bundler가 gemspecs와 회비를 지불하는 것과 비슷합니다. 이 파일 안에 내가 좋아하는 뭔가를 할 것이다 :루비로드에서 반환 값을 캡처하려면 어떻게해야합니까?

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

내가 스크립트 .. 난 그냥 파일의 내용을 잡아 그들을 평가 후면 하는가를로드 한 후이 주제 인스턴스를 캡처하고 싶습니다? 이것은 파일을로드하는 것과 .. eval'ing을 읽는 것 사이에 어떤 차이가 있는지에 대한 후속 질문으로 이어집니다. 나는 'eval'이 종종 파괴의 선구자로 여겨진다는 것을 알고 있습니다. 아마도이 유스 케이스 괜찮아?

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

답변

3

글쎄, 당신은 이미 외부 코드를 허용하는 경우 거기에 약간의 차이가 있지만의 :

이 UP 선택한 답변을 바탕으로

따르 .. 왜 내가 얻을 즉 틈새 보안 구멍은 eval 또는 require과 동일한 크기입니다. 이 경우 실제로는 eval이상 일 수 있습니다. 코드가 실행되는 네임 스페이스와 안전한 수준을 제어 할 수 있으므로 안전합니다. 앱이 누군가 이메일 비밀번호를 다루기 때문에 이는 중요합니다. 메인 네임 스페이스 (require)에서 테마를 실행하게하면 악의적 인 서버에 데이터를 기록하기 위해 Kernel#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 (람다는 안전한 값을 유지하기 때문에).

편집 :이 함께 평가 후면 라인을 교체하십시오 :

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

감사 @Linuxios, 당신은 여기에서 시작하는 나에게 충분한 정보를 제공했고 나는 더 많은 내용을 알고하지 않았다 충분히 개념을 생각한다 이 영역 .. 나는 스레드의 안전 수준을 인식하지 못했습니다. 감사합니다. – Inc1982

+0

@ Inc1982 : 물론. 궁금한 점이 있으면 의견을 남기십시오. 해리 주제이며 실제로 샌드 박싱 코드를 작성하는 동안 이것을 발견했습니다. – Linuxios

+0

나는 당신의 대답에 기초하여 나의 질문에 후속 조치를 추가했다. 당신이 그것을 볼 수 있다면 궁금하다. 왜 $ SAFE가 광섬유의 바인딩 컨텍스트에서 실행 함에도 불구하고 0을 말하고 있는가? – Inc1982

관련 문제