我要求用户可以提供任意语句,这些语句可以存储在函数中,稍后调用以获取返回值.这userInput可能是一个简单的例子
var x = 10;
x;
Run Code Online (Sandbox Code Playgroud)
我会存储这个
var callback = function() {
return eval(userInput);
}
Run Code Online (Sandbox Code Playgroud)
然后按预期运行callback()返回10.
但是,我还需要使用显式返回语句来支持该情况,即userInput可能是
var x = 10;
return x;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,上面的eval方法将失败SyntaxError: return not in function.相反,我可以将回调存储为
var callback = new Function(userInput);
Run Code Online (Sandbox Code Playgroud)
我的问题是我想根据规则'得到显式返回值来结合这两种方法,否则得到最后执行语句的结果'.特别是这不能通过在回调创建时分析代码来完成,因为用户可能会做一些奇怪的事情
if(envVar < 10)
return a;
b * 0.5;
Run Code Online (Sandbox Code Playgroud)
它结合了两者.
有关如何构建callback函数创建以适应这些可能输入的任何想法?不幸的是,不可能在用户上强制执行一种风格或另一种风格.
更新以回答下面的一些评论.
建议的一个解决方案是搜索返回令牌并在new Function和之间进行选择eval.这不适用于我的上一个示例,请参阅http://jsfiddle.net/ZGb6z/2/ - out4应该是"no"但最终未定义,因为最后执行的语句未返回.
另一个建议是修改用户输入,以便在最后一行添加显式返回(如果找不到).不幸的是,不可能知道最后会执行哪个语句.考虑
var x = 10;
switch(x) {
case 10:
100;
break;
default:
200;
break;
}
Run Code Online (Sandbox Code Playgroud)
当被调用它应该返回时100,但需要进行一些认真的分析来确定将任意代码的返回放在何处.
只需使用a try catch,操作输入对你来说将是非常痛苦的,并且try catch在这一点上无法使你的代码更加迟钝.
var failback = function () {
try {
return eval(userInput);
} catch (e) {
return Function(userInput);
}
};
Run Code Online (Sandbox Code Playgroud)
我真正建议的是投资一个解析器,就像Angular一样.这种事情会阻止你的用户做他们想做的事情,引入攻击向量,yadda,yadda,yadda.
要么管理您的期望,要么管理用户的期望。如果您需要在同一用户输入中混合使用显式和非显式语句,eval则不new Function()适合您的要求。return您将继续通过这两种途径发现问题。
仅仅搜索这个词return是不够的……var returning = true;或者var a = 'return';都会/* return true */ true;抛出误报。
管理您的期望:要做这样的事情,您需要某种形式的词法分析器和解析器,此时您可以eval完全取消并根据解析的输入执行您自己的安全函数。当无论如何都必须执行用户输入时,这是最好的方法,因为您可以确保不会执行您不希望允许的任何操作。如果您想涵盖这些边缘情况并允许奇怪的用户输入,那么您必须准备好增加应用程序的大小和开发时间。我已经构建了一些执行用户生成代码的应用程序,并且始终得出结论,这是正确的路线。
管理用户的期望:提供指导,告诉他们不要将显式返回与非显式返回混合在一起,无论如何,这些都是奇怪的编码实践。更好的是明确告诉他们包含或省略 return 语句。要求您的用户关注他们并没有什么可耻的,特别是如果它可以让您在其他地方改善他们的体验。
| 归档时间: |
|
| 查看次数: |
425 次 |
| 最近记录: |