Ok, since there seems to be a lot of confusion, I\'m going to simplify the question a little. You can try to answer the original question below, or you can ta
I'd take a slightly different approach to defining the safe functions and the environment in which you evaluate arbitrary code, but it's really just some style changes. This technique is provably safe, provided all of the functions in safe_f
are safe, i.e. they don't allow you to perform arbitrary code execution. I'd be pretty confident the functions in list are safe, but you'd need to inspect the individual source code to be sure.
safe_f <- c(
getGroupMembers("Math"),
getGroupMembers("Arith"),
getGroupMembers("Compare"),
"<-", "{", "("
)
safe_env <- new.env(parent = emptyenv())
for (f in safe_f) {
safe_env[[f]] <- get(f, "package:base")
}
safe_eval <- function(x) {
eval(substitute(x), env = safe_env)
}
# Can't access variables outside of that environment
a <- 1
safe_eval(a)
# But you can create in that environment
safe_eval(a <- 2)
# And retrieve later
safe_eval(a)
# a in the global environment is not affected
a
# You can't access dangerous functions
safe_eval(cat("Hi!"))
# And because function isn't included in the safe list
# you can't even create functions
safe_eval({
log <- function() {
stop("Danger!")
}
log()
})
This is a much simpler problem than the rapporter sandbox because you're not trying to create an useful R environment, just a useful calculator environment, and the set of functions to check is much much smaller.