【问题标题】:Avoiding loop when at run-time parse a javascript code在运行时解析 javascript 代码时避免循环
【发布时间】:2013-03-21 09:28:37
【问题描述】:

我实现了一个内置在网页中的 javascript 解析器。 用户可以将 javascript 代码放在文本区域中,例如:

var i = 0;
i++;
var y = i * 10;
document.write(y);

被解析以生成一些输出(例如,document.write 流等)。

parse函数在textareachange事件产生时被调用。

function parse(text) {
    try {
        ....
        eval(text);
    } catch (e) {
        ....
        return {
            status : false, output : ..., ... : ...
        };
    }
    return {
        status : true, output : ...., ... : ...
    };
}

一切正常,但是当用户在文本区域中编写循环时出现问题(例如,for(var i=0; i<10; )while(true)) 因为应用程序进入了循环。

为了避免这个问题,我想问大家一些关于这个问题的问题/解决方案:

  1. 是否有一些 javascript 库或函数允许 eval 一个 javascript 代码但没有循环?
  2. 我可以要求在固定时间执行我的解析函数吗?在这段时间之后,我会生成一个停止 eval 函数的异常。
  3. 在调用eval(text) 之前,我可以调用checkIfThereAreLoops 函数来分析寻找for(var i=0; i<10; )while(true) 等模式的文本。这是一个好的解决方案吗?我可以使用正则表达式来寻找这些模式吗?

【问题讨论】:

  • 尽量避免eval,它说你的坏话
  • 为什么不简单地验证输入并禁止(忽略或通知用户)这些恶意行为?
  • @EliranMalka — “简单”?!
  • @EliranMalka - 代码的“简单验证”就像我在第 3 点中描述的那样?
  • 我可以在超时后强制停止eval 方法吗?

标签: javascript parsing loops eval


【解决方案1】:

如果您想查看任意代码是否会终止,您将在the Halting ProblemNP-Hard 之间度过一段艰难时期。

因此,您认为您需要对解析函数采取预防措施以超时或消除不安全的输入是正确的。

我不知道在浏览器不施加“此脚本运行时间过长”限制的情况下中断eval 的方法,因此您需要清理输入而不使用循环评估任何内容:这将是很棘手,因为您不能只搜索 for, while 等结构并避免递归函数调用。

这是一个很难解决的问题……

一个“hacky”解决方案可能是将一个 unique 变量声明插入到输入代码的顶部(当然是隐藏的),并从输入代码中每隔一行递增这个变量(再次, 隐藏这些插入并允许语法结构被破坏。还在每个增量 if unique_var > 99999 exit; 处插入完整性检查(其中 99999 是您施加的一些限制)。

这至少应该停止无限循环。

【讨论】:

  • 所以我知道停机问题,所以我试图找到一个有效的解决方案来避免这个基本循环。因此,如果我在调用eval 函数之前有一个变量_op_counter = 0,我可以将代码incrementOpCounter()function incrementOpCounter(){ if _op_counter > 99999 throw "There is a loop."; _op_counter++; } 添加到每一行我可以解决问题。之前要解析的新代码是(见例子)var i = 0; incrementOpCounter(); i++; incrementOpCounter(); var y = i * 10; incrementOpCounter(); document.write(y); incrementOpCounter();
  • 但是我可以在没有{} 的情况下使用 [if, while, for] 有一些问题,但可能是一个解决方案......
猜你喜欢
  • 1970-01-01
  • 2014-09-20
  • 2016-03-24
  • 2012-06-24
  • 1970-01-01
  • 2023-01-29
  • 1970-01-01
  • 1970-01-01
  • 2016-03-06
相关资源
最近更新 更多