Vm2: 添加对“正确”堆栈跟踪的支持,以解决沙箱中的错误

创建于 2017-08-05  ·  13评论  ·  资料来源: patriksimek/vm2

如果从沙箱抛出错误时vm2可以显示“正确的”堆栈跟踪信息,那就太好了。

例如,这是当前显示的内容:

/home/user/box-js/node_modules/vm2/lib/main.js:213
                        throw this._internal.Decontextify.value(e);
                        ^

Error: foobar
    at Object.log (/home/user/box-js/analyze.js:248:10)
    at Object.apply (/home/user/box-js/node_modules/vm2/lib/contextify.js:288:34)
    at vm.js:491:9
    at ContextifyScript.Script.runInContext (vm.js:53:29)
    at VM.run (/home/user/box-js/node_modules/vm2/lib/main.js:207:72)
    at Object.<anonymous> (/home/user/box-js/analyze.js:383:5)
    at Module._compile (module.js:569:30)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)

有没有办法找出(在沙盒代码中)哪一行负责引发该错误的函数?

feature request help wanted

最有用的评论

只是发表评论以通知订阅此问题的人-我打开了PR,因此您可以跟踪那里的进度。

所有13条评论

太棒了我现在正在尝试查找编码错误,并且在没有行号的情况下经历了非常艰难的时光

如果您运行的测试用例很安全,则可以将vm2临时替换为本地vm,以跟踪错误。

我也想要这个功能。 如果有人指出我正确的方向,我很乐意投稿。

由于此问题最近没有活动,因此已被自动标记为陈旧。 如果没有其他活动发生,它将关闭。 感谢你的贡献。

事实证明,用api不兼容将vm2替换为Native vm并非易事,希望它能保持打开状态!

@patriksimek ,我设计了一个基于异常解析器/重写器的简单实现。 我认为将其集成到vm2中作为​​可选错误处理程序是值得的。

const StackTracey = require ('stacktracey');
const { VM } = require('vm2');

const sourceCode = `function f() {
    throw Exception('e');
}
f();`;
const scriptName = "hello_world.js";

process.on("uncaughtException",  e => {
    if (!e.stack.includes("/node_modules/vm2/")) {
        // This is not a vm2 error, so print it normally
        console.log(e);
        return;
    }
    const oldStack = new StackTracey(e);
    const newStack = [];
    for (const line of oldStack) {
        // Discard internal code
        if (line.file.includes("/cjs"))
            continue;
        if (line.thirdParty && line.file.includes("/node_modules/vm2/"))
            continue;
        if (line.callee == "Script.runInContext")
            continue;
        // Replace the default filename with the user-provided one
        if (line.fileName == "vm.js")
            line.fileRelative = line.fileShort = line.fileName = scriptName;
        newStack.push(line);
    }
    console.log("[vm2] A clean stack trace follows:");
    console.log(new StackTracey(newStack).pretty);
});

const vm = new VM();
vm.run(sourceCode, scriptName);

上面的代码将打印:

ReferenceError: Exception is not defined
    at f (vm.js:2:2)
    at vm.js:4:1
    at Script.runInContext (vm.js:135:20)
    at VM.run (/tmp/vm2-test/node_modules/vm2/lib/main.js:210:72)
    at Object.<anonymous> (/tmp/vm2-test/index.js:33:4)
    at Module._compile (internal/modules/cjs/loader.js:805:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:816:10)
    at Module.load (internal/modules/cjs/loader.js:672:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:612:12)
    at Function.Module._load (internal/modules/cjs/loader.js:604:3)
[vm2] A clean stack trace follows:
at f            hello_world.js:2
at              hello_world.js:4
at <anonymous>  index.js:33       vm.run(sourceCode, scriptName);

我没有机会测试该库,但是最近我使用了vm模块,并通过在创建新的vm.Script时设置适当的行偏移量来实现准确的堆栈跟踪号。

由于此问题最近没有活动,因此已被自动标记为陈旧。 如果没有其他活动发生,它将关闭。 感谢你的贡献。

想通了,我想发表评论,因为这个问题和建议仍然对我有用!

我也很重要

@patriksimek可以将@CapacitorSet的实现或类似的东西集成到项目中吗?
谢谢。

帕特里克(Patrik),实施草图总体上看起来还不错吗? 如果是这样,我可以进行公关,我们可以在那儿工作。

@CapacitorSet是的,我很乐意审查PR。 一些注意事项:

  • vm.run方法不接受第二个参数-这就是为什么脚本名称被忽略的原因。 当前,您需要使用首先指定的名称创建一个VMScript。 但这可以很容易地得到改善。
  • 有没有办法避免使用外部库? 坚持零下垂是很好的。

只是发表评论以通知订阅此问题的人-我打开了PR,因此您可以跟踪那里的进度。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

somebody1234 picture somebody1234  ·  4评论

seanc picture seanc  ·  3评论

unxcepted picture unxcepted  ·  11评论

KonradLinkowski picture KonradLinkowski  ·  10评论

wojpawlik picture wojpawlik  ·  4评论