【发布时间】:2012-04-08 20:38:47
【问题描述】:
我有一个特殊的(虚拟)函数,我想在沙盒环境中使用它:
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 调用,该调用在内部找到一个类似字符串的公式:
> 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) 分配给从 model.frame 调用的 as.formula。不幸的是,我还没有做到这一点:
> 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 就像在model.frame 上面调用的lm。
非常欢迎任何提示和想法!
【问题讨论】: