diff --git a/CHANGELOG.yaml b/CHANGELOG.yaml index ba3bb807..77ec69e2 100644 --- a/CHANGELOG.yaml +++ b/CHANGELOG.yaml @@ -1,3 +1,6 @@ +unreleased: + fixed bugs: + - GH-1023 Prevented invalid events from being executed 5.0.0: date: 2024-06-19 breaking changes: diff --git a/lib/postman-sandbox.js b/lib/postman-sandbox.js index bb4ed609..4efd8d03 100644 --- a/lib/postman-sandbox.js +++ b/lib/postman-sandbox.js @@ -83,12 +83,17 @@ class PostmanSandbox extends UniversalVM { !_.isObject(options) && (options = {}); !_.isFunction(callback) && (callback = _.noop); - // if the target is simple code, we make a generic event out of it - if (_.isString(target) || _.isArray(target)) { - target = new PostmanEvent({ script: target }); + if (!PostmanEvent.isEvent(target)) { + if (_.isString(target) || _.isArray(target)) { + target = new PostmanEvent({ script: target }); + } + else if (_.isObject(target)) { + target = new PostmanEvent(target); + } } - // if target is not a code and instead is not something that can be cast to an event, it is definitely an error - else if (!_.isObject(target)) { + + // This will bail out when the target is not a valid event with proper `script.exec` value + if (typeof target?.script?.toSource?.() !== 'string') { return callback(new Error('sandbox: no target provided for execution')); } diff --git a/lib/sandbox/execute.js b/lib/sandbox/execute.js index d1debb63..b06aded7 100644 --- a/lib/sandbox/execute.js +++ b/lib/sandbox/execute.js @@ -118,6 +118,10 @@ module.exports = function (bridge, glob) { // extract the code from event code = _.isFunction(event.script && event.script.toSource) && ((code) => { + if (typeof code !== 'string') { + return; + } + // wrap it in an async function to support top-level await const asyncCode = `;(async()=>{; ${code} diff --git a/test/unit/sandbox-sanity.test.js b/test/unit/sandbox-sanity.test.js index 52884eaf..6e775927 100644 --- a/test/unit/sandbox-sanity.test.js +++ b/test/unit/sandbox-sanity.test.js @@ -16,6 +16,59 @@ describe('sandbox', function () { }); }); + describe('invalid target', function () { + let context; + + function tester (input, done) { + context.on('error', done); + context.execute(input, function (err) { + expect(err).to.be.ok; + expect(err).to.have.property('message', 'sandbox: no target provided for execution'); + + done(); + }); + context.off('error', done); + } + + + before(function (done) { + Sandbox.createContext(function (err, ctx) { + if (err) { return done(err); } + context = ctx; + done(); + }); + }); + + it('should not execute `null`', function (done) { tester(null, done); }); + it('should not execute `undefined`', function (done) { tester(undefined, done); }); + it('should not execute `{}`', function (done) { tester({}, done); }); + it('should not execute `{ script: {} }`', function (done) { tester({ script: {} }, done); }); + }); + + describe('valid target', function () { + let context; + + function tester (input, done) { + context.on('error', done); + context.execute(input, done); + context.off('error', done); + } + + + before(function (done) { + Sandbox.createContext(function (err, ctx) { + if (err) { return done(err); } + context = ctx; + done(); + }); + }); + + it('should execute a \'\'', function (done) { tester('', done); }); + it('should execute a []', function (done) { tester([], done); }); + it('should execute a [\'\']', function (done) { tester([''], done); }); + it('should execute a { script: { exec: \'\' } }', function (done) { tester({ script: { exec: '' } }, done); }); + }); + it('should execute a piece of code', function (done) { Sandbox.createContext(function (err, ctx) { if (err) { return done(err); }