我有一个特殊的(虚拟)函数,我想在沙盒环境中使用它:
disable.system.call <- function(...) {
mc <- match.call()
if (grepl('system', deparse(mc[[2]])))
stop('NONO')
eval(mc, env = .GlobalEnv)
}
它没有做任何特别的事情,只是检查第一个参数的system
名称中是否包含单词。这只是一个 POC 示例。
我稍后要做的:我将这个简单的函数分配给 somebase
和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
任何提示和想法都会受到欢迎!