gpt4 book ai didi

javascript - 安全地解析和评估用户输入

转载 作者:行者123 更新时间:2023-11-30 17:25:42 25 4
gpt4 key购买 nike

我正在从事一个项目,该项目本质上是一种模板化领域特定语言。在我的项目中,我接受以下形式的用户输入行:

'{{index(1, 5)}}'
'{{firstName()}} X. {{lastName()}}'
'{{floating(-0.5, 0.5)}}'
'{{text(5, "words")}}'

双花括号 ({{ }}) 之间的任何命令都有相应的 Javascript 方法,在遇到该命令时应调用该方法。 (例如,function index(min, max) {...} 在第一个的情况下)。

我很难弄清楚如何安全地接受输入并调用适当的函数。我知道我现在这样做的方式并不安全。我只是 eval() 两组花括号之间的任何东西。

我如何解析这些输入字符串,以便我可以灵活地匹配花括号之间的函数调用并使用给定的任何参数执行该函数,同时仍然不会盲目地用代码调用 eval()

我考虑过做一个映射(如果命令是 index(),调用 function index() {}),但这似乎不太灵活;我如何收集和传递任何参数(例如 {{index(2, 5)}})(如果存在)?

这是用 Node.js 编写的。

最佳答案

这个问题分解为:

  1. 解析字符串

  2. 评估生成的函数图

  3. 分派(dispatch)到每个函数(作为上面 #2 的一部分)

解析字符串

不幸的是,根据您的要求,解析 {{...}} 字符串非常复杂。您至少有这些问题需要处理:

  1. 函数可以嵌套{{function1(function2(), 2, 3)}}

  2. 字符串可以包含(转义的)引号,也可以包含逗号,因此即使没有上述第 1 条要求,查找离散参数(以逗号分隔)的简单方法也不会奏效。

所以...您需要一个合适的解析器。您可以尝试临时拼凑一个,但这是解析器生成器发挥作用的地方,例如 PEG.jsJison (这些只是示例,不一定是建议——我确实注意到 Jison 示例之一是 JSON parser ,这大约是成功的一半)。恐怕编写解析器超出了回答 SO 问题的范围。 :-)

评估生成的函数图

根据您使用的工具,您的解析器生成器可能会为您处理这个问题。 (例如,我很确定 PEG.js 和 Jison 都会。)

如果不是,那么在解析之后,您可能会得到某种对象图,它为您提供函数及其参数(可能是带参数的函数……可能是……)。

  • 函数A
    • 1
    • “两个”
    • 函数B
      • “一个”
      • 函数C
        • 42
    • 功能D
    • 27

functionA 有五个参数,第三个是有两个参数的 functionB,依此类推。

然后,您的下一个任务是评估那些首先最深(并且在相同深度,从左到右)的函数,并用它们的结果替换相关参数列表中的它们,这样您需要一个 depth-first traversal algorithm .通过最深优先和从左到右(在上面的项目符号列表中从上到下)我的意思是在上面的列表中,你必须先调用 functionC,然后是 functionB,然后是 functionD,然后最终函数A。

调度到每个函数

再次取决于您使用的工具,它也可能会处理这一点。我再次怀疑 PEG.js 会这样做,如果 Jison 也这样做我也不会感到惊讶。

当您准备好调用一个(不再)将函数调用作为参数的函数时,您可能会得到函数名和参数数组。假设您将函数存储在 map 中:

var functions = {
index: function() { /* ... */ },
firstName: function() { /* ... */ },
// ...
};

...调用它们很简单:

functionResult = functions[functionName].apply(undefined, functionArguments);

很抱歉不能说“只做 X,你就在那里”,但这确实不是一个微不足道的问题。我会向它扔工具,我不会自己发明这个轮子。

关于javascript - 安全地解析和评估用户输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24326614/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com