Skip to content

Commit 6ea8d81

Browse files
authored
Improve error handling in abacus-eval (cloudfoundry-attic#610)
1 parent f02280b commit 6ea8d81

File tree

2 files changed

+26
-10
lines changed

2 files changed

+26
-10
lines changed

lib/utils/eval/src/index.js

+16-5
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,12 @@ const xeval = (s, c) => {
4242
}
4343
}
4444
catch (ex) {
45-
edebug('Evaluating expression %s with context %o and timeout %d' +
46-
' using %s failed with %s', s, context, timeout, vmtype, ex);
45+
if (s === 'f(...args)' && c.f && c.args)
46+
edebug('Calling function %s with arguments %o and timeout %d using %s' +
47+
' failed with %s', c.f.toString(), c.args, timeout, vmtype, ex);
48+
else
49+
edebug('Evaluating expression %s with context %o and timeout %d' +
50+
' using %s failed with %s', s, context, timeout, vmtype, ex);
4751
throw ex;
4852
}
4953
};
@@ -66,9 +70,16 @@ const check = (s) => {
6670
// using strict mode, and return a new function that calls the above function,
6771
// also in a sandbox
6872
const xevalfn = (s, c) => {
69-
check(s);
70-
const f = xeval('"use strict"; (' + s + ')', c);
71-
return (...args) => xeval('f(...args)', { f: f, args: args });
73+
try {
74+
check(s);
75+
const f = xeval('"use strict"; (' + s + ')', c);
76+
return (...args) => xeval('f(...args)', { f: f, args: args });
77+
}
78+
catch (ex) {
79+
return (...args) => {
80+
throw ex;
81+
};
82+
}
7283
};
7384

7485
// Export our public functions

lib/utils/eval/src/test/test.js

+10-5
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,12 @@ async.each(['vm', 'vm2'], (vmtype, cb) => {
5050
});
5151

5252
it('prevents asynchronus execution with Promises', () => {
53-
expect(() => xeval(`() => {
53+
const f = xeval(`() => {
5454
return new Promise((resolve, reject) => resolve())
5555
.then(function(value) { while(true); })
56-
}`)).to.throw('Promises not supported');
56+
}`);
57+
expect(typeof f).to.equal('function');
58+
expect(f).to.throw('Promises not supported');
5759
});
5860

5961
it('prevents direct usage of built-in modules and globals', () => {
@@ -63,8 +65,9 @@ async.each(['vm', 'vm2'], (vmtype, cb) => {
6365
});
6466

6567
it('prevents requiring modules', () => {
66-
expect(xeval('() => require("console").log("Hi")')).to.throw(
67-
'require is not defined');
68+
const f = xeval('() => require("console").log("Hi")');
69+
expect(typeof f).to.equal('function');
70+
expect(f).to.throw('require is not defined');
6871
});
6972

7073
vm2it('prevents escaping via this.constructor.constructor', () => {
@@ -87,7 +90,9 @@ async.each(['vm', 'vm2'], (vmtype, cb) => {
8790
});
8891

8992
it('rejects arguments.callee', () => {
90-
expect(xeval('function (x) { return arguments.callee; }')).to.throw(
93+
const f = xeval('function (x) { return arguments.callee; }');
94+
expect(typeof f).to.equal('function');
95+
expect(f).to.throw(
9196
'\'caller\', \'callee\', and \'arguments\' properties ' +
9297
'may not be accessed on strict mode functions or the arguments ' +
9398
'objects for calls to them');

0 commit comments

Comments
 (0)