我有我想在沙箱環境中使用特殊的(虛擬)功能:作用域(功能)的定製環境
disable.system.call <- function(...) {
mc <- match.call()
if (grepl('system', deparse(mc[[2]])))
stop('NONO')
eval(mc, env = .GlobalEnv)
}
它確實沒有什麼特別的只是檢查,如果第一個參數已在system
字其名稱。這只是一個POC的例子。
我後來做了什麼:我將這個簡單的函數分配給某些base
和stats
函數,以查看評估的表達式是否包含作爲第一個參數的system
字。例如:
e <- new.env()
eval(parse(text = 'model.frame <- disable.system.call'), envir = e)
這工作很酷,因爲電話沒有system
裏面用得好好的,但過濾器的工作原理:
> eval(parse(text = 'model.frame("1 ~ 1")'), envir = e)
1
1 1
> eval(parse(text = 'model.frame(\'1 ~ system("ls -la")\')'), envir = e)
Error in model.frame("1 ~ system(\"ls -la\")") : NONO
它甚至有lm
調用它調用model.frame
工作的內部發現了一個公式像字符串:
> eval(parse(text = 'lm(\'1 ~ system("ls -la")\')'), envir = e)
Error in model.frame(formula = "1 ~ system(\"ls -la\")", drop.unused.levels = TRUE) :
NONO
我試圖去一點,並分配一個非常簡單的函數(disable.system.call
)至as.formula
,其從model.frame
調用。不幸的是我沒有走到這一步:
> e <- new.env()
> eval(parse(text = 'as.formula <- disable.system.call'), envir = e)
> eval(parse(text = 'as.formula("1 ~ 1")'), envir = e)
1 ~ 1
> eval(parse(text = 'as.formula(\'1 ~ system("ls -la")\')'), envir = e)
Error in as.formula("1 ~ system(\"ls -la\")") : NONO
> eval(parse(text = 'model.frame(\'1 ~ system("ls -la")\')'), envir = e)
1 system("ls -la")
1 1 0
> eval(parse(text = 'lm(\'1 ~ system("ls -la")\')'), envir = e)
Call:
lm(formula = "1 ~ system(\"ls -la\")")
Coefficients:
(Intercept) system("ls -la")
1 NA
據我所知model.frame
呼籲as.formula
但這不起作用(你可以從上面的輸出中看到)。我很確定這不是因爲model.frame
在自定義環境中調用stats::as.formula
爲lm
以上model.frame
。
任何提示和想法都會非常受歡迎!
謝謝,這個答案是很方便的太(+1)!事實上,我不想禁止所有的「系統」調用,它只是一個簡單的POC示例,但我確實需要實現沙箱環境。請參閱:http://sandboxr.no-ip.org/無論如何,'assignInNamespace'看起來很有希望,我需要一些時間在復活節後做一些實驗,並且肯定會給出更詳細的反饋。 – daroczig 2012-04-09 09:07:40
不錯的項目。你見過Live-R,它有類似的事情嗎? http://live-analytics.com – 2012-04-09 15:22:28
從來沒有聽說過Live-R,感謝把我的注意力集中在那個整潔的軟件上!我很喜歡類似的東西,但是有特殊的(預期的)觀衆。我們將看到:)無論如何,關於你的回答:因爲'?assignInNamespace'建議不要在包中使用這個特性(就像我想的那樣)並且不允許我啓用/禁用沙箱環境,似乎我有找到另一種停用這些通話的方式。像grep's R來源類似的功能:)我想要做的是在特殊環境中運行調用,除此之外允許任何事情(用於系統端調用)。 – daroczig 2012-04-09 19:17:30