Skip to content

Commit 0b56fa4

Browse files
committed
Allow require to be shared across executions
1 parent a36bff5 commit 0b56fa4

File tree

2 files changed

+61
-19
lines changed

2 files changed

+61
-19
lines changed

lib/sandbox/execute-context.js

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
11
const { isNonLegacySandbox } = require('./non-legacy-codemarkers');
22
const _ = require('lodash'),
3-
legacy = require('./postman-legacy-interface'),
4-
5-
DEPRECATED_LIBS = {
6-
atob: 'global "atob" function',
7-
btoa: 'global "btoa" function',
8-
'crypto-js': 'global "crypto" object',
9-
tv4: '"ajv" library',
10-
backbone: null
11-
};
3+
legacy = require('./postman-legacy-interface');
124

135
module.exports = function (scope, code, execution, console, timers, pmapi, onAssertion, options) {
146
// if there is no code, then no point bubbling anything up
@@ -52,21 +44,36 @@ module.exports = function (scope, code, execution, console, timers, pmapi, onAss
5244
setImmediate: timers.setImmediate,
5345
clearTimeout: timers.clearTimeout,
5446
clearInterval: timers.clearInterval,
55-
clearImmediate: timers.clearImmediate,
47+
clearImmediate: timers.clearImmediate
48+
});
5649

57-
require: (...args) => {
58-
const key = args?.[0],
50+
const wrappedCode = `
51+
;((originalRequire) => {
52+
require = (...args) => {
53+
const key = args?.[0],
54+
DEPRECATED_LIBS = {
55+
atob: 'global "atob" function',
56+
btoa: 'global "btoa" function',
57+
'crypto-js': 'global "crypto" object',
58+
tv4: '"ajv" library',
59+
backbone: null
60+
},
5961
alt = DEPRECATED_LIBS[key];
6062
61-
if (alt !== undefined) {
62-
console.warn(`Using "${key}" library is deprecated.${alt !== null ? ` Use ${alt} instead.` : ''}`);
63-
}
63+
if (alt !== undefined) {
64+
console.warn(
65+
\`Using "\${key}" library is deprecated.\${alt !== null ? \` Use \${alt} instead.\` : ''}\`
66+
);
67+
}
6468
65-
return require(...args);
66-
}
67-
});
6869
69-
scope.exec(code, { async: true }, function (err) {
70+
return originalRequire(...args);
71+
}
72+
})(require);
73+
${code}
74+
`;
75+
76+
scope.exec(wrappedCode, { async: true }, function (err) {
7077
// we check if the execution went async by determining the timer queue length at this time
7178
execution.return.async = (timers.queueLength() > 0);
7279

test/unit/sandbox-sanity.test.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,41 @@ describe('sandbox', function () {
387387
});
388388
});
389389

390+
it('should persist overridden `require` across executions', function (done) {
391+
const consoleSpy = sinon.spy();
392+
393+
Sandbox.createContext(function (err, ctx) {
394+
if (err) { return done(err); }
395+
396+
ctx.on('error', done);
397+
ctx.on('console', consoleSpy);
398+
399+
ctx.execute(`
400+
require = (...args) => {
401+
if (args[0] === 'utils') {
402+
return () => console.log('utils');
403+
}
404+
405+
return require(...args);
406+
}
407+
408+
require('utils')();
409+
`, function (err) {
410+
if (err) { return done(err); }
411+
412+
ctx.execute('require(\'utils\')();', function (err) {
413+
if (err) { return done(err); }
414+
415+
expect(consoleSpy).to.be.calledTwice;
416+
expect(consoleSpy.firstCall.args[2]).to.equal('utils');
417+
expect(consoleSpy.secondCall.args[2]).to.equal('utils');
418+
419+
done();
420+
});
421+
});
422+
});
423+
});
424+
390425
(IS_NODE ? it : it.skip)('should have missing globals as subset of explicitly ignored globals', function (done) {
391426
Sandbox.createContext(function (err, ctx) {
392427
if (err) { return done(err); }

0 commit comments

Comments
 (0)