r - R - 从字符串创建函数
问题描述
我在 Advanced R 的 Expressions 章节的 Parlist 部分遇到了以下函数:
make_function <- function(args, body, env = parent.frame()) {
args <- as.pairlist(args)
eval(call("function", args, body), env)
}
该函数允许用户从其组成部分构造函数:形式参数列表、主体和环境。例如
add <- make_function(alist(a = 1, b = 2), quote(a + b))
add
function (a = 1, b = 2)
a + b
class(add)
[1] "function"
我想知道是否可以修改函数以允许用户为body
参数输入字符串?我已经尝试过parse(text = 'a + b')
,但这会返回 a而expression
不是 a :call
quote(a + b)
class(quote(a + b))
[1] "call"
class(parse(text = 'x^m'))
[1] "expression"
有没有办法call
从字符串构造对象?
解决方案
您通常应该避免解析来自用户的任意字符串输入。通常,这可以通过适当的软件设计来避免。
无论如何,只需从表达式中提取语言:
make_function(alist(a = 1, b = 2), parse(text = 'a^b')[[1]])
编辑:
只是为了展示如何检查白名单(不涉及正则表达式):
whitelist <- c("+", "*", "-", "/", "^", "**", "%%", "%/%", "sin", "cos", "tan", "abs") #etc.
expr <- parse(text = "cos(x)^sin(x)*abs(x)")
foo <- function(e) if (length(e) > 1) lapply(as.list(e), foo) else return(e)
funs <- unlist(foo(expr[[1]]))
funs <- funs[vapply(funs, function(x) {x <- eval(x); is.function(x) | is.primitive(x)}, FUN.VALUE = TRUE)]
all(vapply(funs, function(x) as.character(x) %in% whitelist, FUN.VALUE = TRUE))
在公共闪亮应用程序中解析和评估任意代码是一种安全风险。此检查确保只能使用一组预定义的函数。如果您不回避较小的风险,则可以使用黑名单代替(禁止使用system
,system2
等功能shell
)。
推荐阅读
- typescript - 如何在firebase函数中打开http url?
- c# - 如何在已发布的 c# Visual Studio 构建中按路径引用文件
- assembly - 如何在字符串中添加特定字符?
- python - 我在完成在线教程时收到 OSError,但我自己无法弄清楚
- .net - TokenAcquisition 失败时如何处理 MicrosoftIdentityWebChallengeUserException?
- hash - 为什么我的程序会错误地计算 MD2 哈希?
- sql - 我怎样才能更有效地编写这个嵌套查询?
- python - 如何附加来自多个 csv 文件的值?
- python - Django-Auth-App 的 app_secret_key 和 secret_key 之间的区别
- php - 如何在 MySQL 中为 PHP 中的电子商店制作正确的事务和/或锁定表?