Javascript 中算术表达式的安全评估

新手上路,请多包涵

我需要在 Javascript 中评估用户输入的算术表达式,如“2 * (3 + 4)”,但出于安全原因,我不想使用 eval

我可以去掉所有不是数字或运算符的字符,但我不确定这是否安全,如果用户可以使用像 cossqrt 这样的函数就好了 --- 等等…

有没有做算术表达式评估的 Javascript 库?

原文由 Giuseppe Ottaviano 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 288
2 个回答

您可以尝试 JavaScript Expression Evaluator

这个库是 Raphael Graf 的 ActionScript Expression Parser 的修改版本。当我编写 JavaScript Function Plotter 时,我想要一个 更好的替代方法来使用 JavaScript 的 eval 函数。目前没有安全风险,因为您只能在自己的浏览器中运行代码,但它对数学并不方便(Math.pow(2^x) 而不是 2^x 等)。

那么你的代码将是这样的:

 console.info ( Parser.evaluate( "2 * (3 + 4)" ) ); //prints 14

源代码位于 GitHub 上,并在 npm 上发布为 expr-eval 。可以这样使用:

 import { Parser } from 'expr-eval';

console.log(Parser.evaluate("2 * (3 + 4)")); // 14

原文由 Maxym 发布,翻译遵循 CC BY-SA 4.0 许可协议

如前所述,任何用户可能造成的最大损害几乎就是他们已经可以使用任何主要浏览器中的内置控制台所做的事情。但是,如果您想限制用户使用 Math 属性/方法,您可以编写一个简单的正则表达式来为您处理这个问题。这样的事情应该有效:

 function mathEval (exp) {
    var reg = /(?:[a-z$_][a-z0-9$_]*)|(?:[;={}\[\]"'!&<>^\\?:])/ig,
        valid = true;

    // Detect valid JS identifier names and replace them
    exp = exp.replace(reg, function ($0) {
        // If the name is a direct member of Math, allow
        if (Math.hasOwnProperty($0))
            return "Math."+$0;
        // Otherwise the expression is invalid
        else
            valid = false;
    });

    // Don't eval if our replace function flagged as invalid
    if (!valid)
        alert("Invalid arithmetic expression");
    else
        try { alert(eval(exp)); } catch (e) { alert("Invalid arithmetic expression"); };
}

我知道你不想使用 eval 出于安全原因,但正则表达式应该使它非常安全,因为它排除了任何不是 Math 对象的 直接 属性的单词和大多数非数学 JS 运算符,包括赋值运算符( = )和二元运算符。更难的方法是编写分词器来解析数学表达式,因为它不是常规语言。

随意尝试打破我写的 工作示例,如果可以或者如果您发现问题,请发表评论,我会看看我能做些什么来解决它。


注意:Yi Jiang [在 JavaScript 聊天中](https://chat.stackoverflow.com/rooms/17/javascript) 提到,对于像 `Math.PI` 这样的东西允许小写可能也很有用。如果是这种情况,您可以在替换函数中添加以下“else if”语句:

 else if (Math.hasOwnProperty($0.toUpperCase())
    return "Math."+$0.toUpperCase();

ifelse 语句之间添加它( 示例)。

原文由 Andy E 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题