Skip to content

Commit bb9eabe

Browse files
princejwesleylance
authored andcommitted
repl: Mitigate vm nodejs#548 function redefinition issue
```js node 🙈 ₹ git:(upstream ⚡ repl-tmp-548) ./node > function name() { return "node"; }; undefined > name() 'node' > function name() { return "nodejs"; }; undefined > name() 'nodejs' > ``` Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Lance Ball <[email protected]>
1 parent 5aac4c4 commit bb9eabe

File tree

3 files changed

+64
-13
lines changed

3 files changed

+64
-13
lines changed

lib/repl.js

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -472,19 +472,7 @@ function REPLServer(prompt,
472472
}
473473

474474
var evalCmd = self.bufferedCommand + cmd;
475-
if (/^\s*\{/.test(evalCmd) && /\}\s*$/.test(evalCmd)) {
476-
// It's confusing for `{ a : 1 }` to be interpreted as a block
477-
// statement rather than an object literal. So, we first try
478-
// to wrap it in parentheses, so that it will be interpreted as
479-
// an expression.
480-
evalCmd = '(' + evalCmd + ')\n';
481-
self.wrappedCmd = true;
482-
} else {
483-
// otherwise we just append a \n so that it will be either
484-
// terminated, or continued onto the next expression if it's an
485-
// unexpected end of input.
486-
evalCmd = evalCmd + '\n';
487-
}
475+
evalCmd = preprocess(evalCmd);
488476

489477
debug('eval %j', evalCmd);
490478
self.eval(evalCmd, self.context, 'repl', finish);
@@ -539,6 +527,26 @@ function REPLServer(prompt,
539527
// Display prompt again
540528
self.displayPrompt();
541529
}
530+
531+
function preprocess(code) {
532+
let cmd = code;
533+
if (/^\s*\{/.test(cmd) && /\}\s*$/.test(cmd)) {
534+
// It's confusing for `{ a : 1 }` to be interpreted as a block
535+
// statement rather than an object literal. So, we first try
536+
// to wrap it in parentheses, so that it will be interpreted as
537+
// an expression.
538+
cmd = `(${cmd})`;
539+
self.wrappedCmd = true;
540+
} else {
541+
// Mitigate https://github.com/nodejs/node/issues/548
542+
cmd = cmd.replace(/^\s*function\s+([^(]+)/,
543+
(_, name) => `var ${name} = function ${name}`);
544+
}
545+
// Append a \n so that it will be either
546+
// terminated, or continued onto the next expression if it's an
547+
// unexpected end of input.
548+
return `${cmd}\n`;
549+
}
542550
});
543551

544552
self.on('SIGCONT', function() {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Reference: https://github.com/nodejs/node/pull/7624
2+
'use strict';
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const repl = require('repl');
6+
const stream = require('stream');
7+
8+
common.globalCheck = false;
9+
10+
const r = initRepl();
11+
12+
r.input.emit('data', 'function a() { return 42; } (1)\n');
13+
r.input.emit('data', 'a\n');
14+
r.input.emit('data', '.exit');
15+
16+
const expected = '1\n[Function a]\n';
17+
const got = r.output.accumulator.join('');
18+
assert.strictEqual(got, expected);
19+
20+
function initRepl() {
21+
const input = new stream();
22+
input.write = input.pause = input.resume = () => {};
23+
input.readable = true;
24+
25+
const output = new stream();
26+
output.writable = true;
27+
output.accumulator = [];
28+
29+
output.write = (data) => output.accumulator.push(data);
30+
31+
return repl.start({
32+
input,
33+
output,
34+
useColors: false,
35+
terminal: false,
36+
prompt: ''
37+
});
38+
}

test/parallel/test-repl.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,11 @@ function error_test() {
328328
// or block comment. https://github.com/nodejs/node/issues/3611
329329
{ client: client_unix, send: 'a = 3.5e',
330330
expect: /^SyntaxError: Invalid or unexpected token/ },
331+
// Mitigate https://github.com/nodejs/node/issues/548
332+
{ client: client_unix, send: 'function name(){ return "node"; };name()',
333+
expect: "'node'\n" + prompt_unix },
334+
{ client: client_unix, send: 'function name(){ return "nodejs"; };name()',
335+
expect: "'nodejs'\n" + prompt_unix },
331336
]);
332337
}
333338

0 commit comments

Comments
 (0)