Skip to content

Commit ed1ba45

Browse files
committed
repl: remove REPLServer.createContext side effects
The internal method `REPLServer.createContext()` had unexpected side effects. When called, the value for the `underscoreAssigned` and `lines` properties were reset. This change ensures that those properties are not modified when a context is created. Fixes: #14226 Refs: #7619 PR-URL: #14331 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Prince John Wesley <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
1 parent 676522f commit ed1ba45

File tree

2 files changed

+48
-10
lines changed

2 files changed

+48
-10
lines changed

lib/repl.js

+8-10
Original file line numberDiff line numberDiff line change
@@ -644,14 +644,18 @@ REPLServer.prototype.createContext = function() {
644644
context.module = module;
645645
context.require = require;
646646

647+
internalModule.addBuiltinLibsToObject(context);
648+
649+
return context;
650+
};
647651

652+
REPLServer.prototype.resetContext = function() {
653+
this.context = this.createContext();
648654
this.underscoreAssigned = false;
649655
this.lines = [];
650656
this.lines.level = [];
651657

652-
internalModule.addBuiltinLibsToObject(context);
653-
654-
Object.defineProperty(context, '_', {
658+
Object.defineProperty(this.context, '_', {
655659
configurable: true,
656660
get: () => this.last,
657661
set: (value) => {
@@ -663,12 +667,6 @@ REPLServer.prototype.createContext = function() {
663667
}
664668
});
665669

666-
return context;
667-
};
668-
669-
REPLServer.prototype.resetContext = function() {
670-
this.context = this.createContext();
671-
672670
// Allow REPL extensions to extend the new context
673671
this.emit('reset', this.context);
674672
};
@@ -784,7 +782,7 @@ function complete(line, callback) {
784782
var flat = new ArrayStream(); // make a new "input" stream
785783
var magic = new REPLServer('', flat); // make a nested REPL
786784
replMap.set(magic, replMap.get(this));
787-
magic.context = magic.createContext();
785+
magic.resetContext();
788786
flat.run(tmp); // eval the flattened code
789787
// all this is only profitable if the nested REPL
790788
// does not have a bufferedCommand

test/parallel/test-repl-context.js

+40
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
const common = require('../common');
33
const assert = require('assert');
44
const repl = require('repl');
5+
const vm = require('vm');
56

67
// Create a dummy stream that does nothing
78
const stream = new common.ArrayStream();
@@ -23,4 +24,43 @@ function testContext(repl) {
2324

2425
// ensure that the repl console instance does not have a setter
2526
assert.throws(() => context.console = 'foo', TypeError);
27+
repl.close();
28+
}
29+
30+
testContextSideEffects(repl.start({ input: stream, output: stream }));
31+
32+
function testContextSideEffects(server) {
33+
assert.ok(!server.underscoreAssigned);
34+
assert.strictEqual(server.lines.length, 0);
35+
36+
// an assignment to '_' in the repl server
37+
server.write('_ = 500;\n');
38+
assert.ok(server.underscoreAssigned);
39+
assert.strictEqual(server.lines.length, 1);
40+
assert.strictEqual(server.lines[0], '_ = 500;');
41+
assert.strictEqual(server.last, 500);
42+
43+
// use the server to create a new context
44+
const context = server.createContext();
45+
46+
// ensure that creating a new context does not
47+
// have side effects on the server
48+
assert.ok(server.underscoreAssigned);
49+
assert.strictEqual(server.lines.length, 1);
50+
assert.strictEqual(server.lines[0], '_ = 500;');
51+
assert.strictEqual(server.last, 500);
52+
53+
// reset the server context
54+
server.resetContext();
55+
assert.ok(!server.underscoreAssigned);
56+
assert.strictEqual(server.lines.length, 0);
57+
58+
// ensure that assigning to '_' in the new context
59+
// does not change the value in our server.
60+
assert.ok(!server.underscoreAssigned);
61+
vm.runInContext('_ = 1000;\n', context);
62+
63+
assert.ok(!server.underscoreAssigned);
64+
assert.strictEqual(server.lines.length, 0);
65+
server.close();
2666
}

0 commit comments

Comments
 (0)