简体   繁体   English

在不使用 eval 的情况下断言 Javascript 中的简单条件

[英]Assert simple conditions in Javascript without using eval

I'm trying to build a Javascript program that can interpret simple conditions:我正在尝试构建一个可以解释简单条件的 Javascript 程序:

let condition = '5 + 6 > 10';
if( assert(condition) ){
  //... do something
} else {
  // ... do other thing
}

A simple but unsecure way to implement assert is to simply use eval .实现assert的一种简单但不安全的方法是简单地使用eval It works, but opens a security hole.它有效,但会打开一个安全漏洞。 How could I work around this?我该如何解决这个问题?

I need support for addition and substraction, string and numbers comparisons, and parenthesis management.我需要对加法和减法、字符串和数字比较以及括号管理的支持。

There are several options:有几种选择:

  • you can write a tokenizer and parser for your expressions by hand.您可以手动为表达式编写标记器和解析器。 For a simple grammar like this, this isn't complicated and is actually a very good exercise in programming.对于这样一个简单的语法,这并不复杂,实际上是一个很好的编程练习。 Look up "shunting yard algorithm" or "recursive descent parser".查找“分流码算法”或“递归下降解析器”。

  • alternatively, you can use a parser generator like peg or nearley .或者,您可以使用解析器生成器,如pegNearley With a generator, you write your grammar in their specific language and let the generator create a parsing function for you.使用生成器,您可以使用特定语言编写语法,并让生成器为您创建解析函数。 Check out their examples: https://pegjs.org/online ,https://github.com/kach/nearley/tree/master/examples/calculator查看他们的示例: https : //pegjs.org/onlinehttps ://github.com/kach/nearley/tree/master/examples/calculator

  • finally, you can use a full-blown Javascript parser like esprima or acorn .最后,您可以使用成熟的 Javascript 解析器,如esprimaacorn This way you'll get a complete javascript AST, which you can walk and perform calculations as you go.通过这种方式,您将获得一个完整的 javascript AST,您可以边走边走和执行计算。 This method is far more complicated that the others, but gives you the full power of javascript in your expressions, eg functions, regexes etc.这种方法比其他方法复杂得多,但在表达式中为您提供了 javascript 的全部功能,例如函数、正则表达式等。

If the interpreter supports toString() on functions, you can do this for example:如果解释器支持函数上的 toString() ,您可以这样做,例如:

function test (f) {
  let source = f.toString().replace(/^\(\) => /,'');
  if (f()) {
    console.log(source+" succeeded");
  } else {
    console.log(source+" failed");
  }
}
let condition = () => 5 + 6 > 10;
test(condition)
test(() => 5 + 4 > 10)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM