题 如何检测我在eval()调用中?


是否存在字符串 s 这样的

(new Function(s))();

eval(s);

表现不同?我正试图“检测”字符串的评估方式。


18
2017-09-01 12:05


起源


你能解释一下为什么要这么做吗?我很好奇。 - some
@some:如果你使用Chrome进行远程调试,调用过程中会有一个函数调用 RuntimeAgent.evaluate() 其中第一个参数是将要执行的字符串。我试图找出幕后发生的事情,以便在调试过程中模拟该功能。 - Randomblue
它是一个webkit功能而不是Chrome - mc_fish
@mc_fish:你知道我在哪里可以找到它的文档吗? - Randomblue
webkit文档或者如果你想要源代码...... code.google.com/p/webkit-mirror/source/browse/Source/WebCore/... - mc_fish


答案:


检查 arguments 目的。如果它存在,那么你就在这个功能中。如果不是这样的话 eval编辑。

请注意,您必须进行检查 arguments 在一个 try...catch 阻止这样:

var s = 'try {document.writeln(arguments ? "Function" : "Eval") } catch(e) { document.writeln("Eval!") }';
(new Function(s))();
eval(s);

演示

解决方案 nnnnnn关心。 为此,我编辑了eval函数本身:

var _eval = eval;
eval = function (){
    // Your custom code here, for when it's eval
    _eval.apply(this, arguments);
};

function test(x){
    eval("try{ alert(arguments[0]) } catch(e){ alert('Eval detected!'); }");
}
test("In eval, but it wasn't detected");​

31
2017-09-01 12:09



如果eval语句在另一个函数内部怎么办? jsfiddle.net/yA4dL - nnnnnn
@nnnnnn好点。我不确定现在有办法了。如果我找到方法,我会将它添加到我的答案中。 - Some Guy
@nnnnnn添加了一个解决方案。 - Some Guy
凉。你能解释为什么这个新小提琴有效吗? (注意:eval需要返回一个值。并且 MDN 建议不要间接调用eval。) - nnnnnn
@nnnnnn当然可以。使其通过另一个函数会更改它可以访问的范围。这种休息 eval的功能,如果 eval 需要访问当前范围中的变量。从现在开始你的字符串 eval,新功能, _eval 可以访问全局范围内的变量。在这种情况下,没有 window.arguments,所以它抛出一个错误,让我们检测到它已经存在 eval编辑。 - Some Guy


由于您无法重新定义eval,因此当前答案在严格模式下不起作用。而且,重新定义 eval 由于许多其他原因而存在问题。

区分它们的方法是基于这样一个事实......其中一个创造了一个功能,哪个没有。功能有什么作用?他们能 return 东东 :)

我们可以简单地利用它并做一些事情 return

// is in function
try {
     return true;
} catch(e) { // in JS you can catch syntax errors
     false; //eval returns the return of the expression.
}

所以在例子中:

var s = "try{ return true; }catch(e){ false; }";
eval(s); // false
Function(s)(); // true
(new Function(s))(); // true, same as line above
(function(){ return eval(s); })(); // the nested 'problematic' case - false

14
2017-12-19 19:59



好。这是一种有趣的方法,但是如果想要检测一个是否在eval中,则会失败,如果没有,则会执行某些操作 - 返回将返回并且不会执行任何操作。 - Michael
哼。实际上这在任何情况下都无效...甚至将“返回”放在“尝试”中,尝试eval会给我“SyntaxError:Illegal return statement” - Michael