repl: Mitigate vm #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 <thechargingvolcano@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Lance Ball <lball@redhat.com>
This commit is contained in:
parent
5aac4c42da
commit
bb9eabec40
34
lib/repl.js
34
lib/repl.js
@ -472,19 +472,7 @@ function REPLServer(prompt,
|
||||
}
|
||||
|
||||
var evalCmd = self.bufferedCommand + cmd;
|
||||
if (/^\s*\{/.test(evalCmd) && /\}\s*$/.test(evalCmd)) {
|
||||
// It's confusing for `{ a : 1 }` to be interpreted as a block
|
||||
// statement rather than an object literal. So, we first try
|
||||
// to wrap it in parentheses, so that it will be interpreted as
|
||||
// an expression.
|
||||
evalCmd = '(' + evalCmd + ')\n';
|
||||
self.wrappedCmd = true;
|
||||
} else {
|
||||
// otherwise we just append a \n so that it will be either
|
||||
// terminated, or continued onto the next expression if it's an
|
||||
// unexpected end of input.
|
||||
evalCmd = evalCmd + '\n';
|
||||
}
|
||||
evalCmd = preprocess(evalCmd);
|
||||
|
||||
debug('eval %j', evalCmd);
|
||||
self.eval(evalCmd, self.context, 'repl', finish);
|
||||
@ -539,6 +527,26 @@ function REPLServer(prompt,
|
||||
// Display prompt again
|
||||
self.displayPrompt();
|
||||
}
|
||||
|
||||
function preprocess(code) {
|
||||
let cmd = code;
|
||||
if (/^\s*\{/.test(cmd) && /\}\s*$/.test(cmd)) {
|
||||
// It's confusing for `{ a : 1 }` to be interpreted as a block
|
||||
// statement rather than an object literal. So, we first try
|
||||
// to wrap it in parentheses, so that it will be interpreted as
|
||||
// an expression.
|
||||
cmd = `(${cmd})`;
|
||||
self.wrappedCmd = true;
|
||||
} else {
|
||||
// Mitigate https://github.com/nodejs/node/issues/548
|
||||
cmd = cmd.replace(/^\s*function\s+([^(]+)/,
|
||||
(_, name) => `var ${name} = function ${name}`);
|
||||
}
|
||||
// Append a \n so that it will be either
|
||||
// terminated, or continued onto the next expression if it's an
|
||||
// unexpected end of input.
|
||||
return `${cmd}\n`;
|
||||
}
|
||||
});
|
||||
|
||||
self.on('SIGCONT', function() {
|
||||
|
@ -0,0 +1,38 @@
|
||||
// Reference: https://github.com/nodejs/node/pull/7624
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const repl = require('repl');
|
||||
const stream = require('stream');
|
||||
|
||||
common.globalCheck = false;
|
||||
|
||||
const r = initRepl();
|
||||
|
||||
r.input.emit('data', 'function a() { return 42; } (1)\n');
|
||||
r.input.emit('data', 'a\n');
|
||||
r.input.emit('data', '.exit');
|
||||
|
||||
const expected = '1\n[Function a]\n';
|
||||
const got = r.output.accumulator.join('');
|
||||
assert.strictEqual(got, expected);
|
||||
|
||||
function initRepl() {
|
||||
const input = new stream();
|
||||
input.write = input.pause = input.resume = () => {};
|
||||
input.readable = true;
|
||||
|
||||
const output = new stream();
|
||||
output.writable = true;
|
||||
output.accumulator = [];
|
||||
|
||||
output.write = (data) => output.accumulator.push(data);
|
||||
|
||||
return repl.start({
|
||||
input,
|
||||
output,
|
||||
useColors: false,
|
||||
terminal: false,
|
||||
prompt: ''
|
||||
});
|
||||
}
|
@ -328,6 +328,11 @@ function error_test() {
|
||||
// or block comment. https://github.com/nodejs/node/issues/3611
|
||||
{ client: client_unix, send: 'a = 3.5e',
|
||||
expect: /^SyntaxError: Invalid or unexpected token/ },
|
||||
// Mitigate https://github.com/nodejs/node/issues/548
|
||||
{ client: client_unix, send: 'function name(){ return "node"; };name()',
|
||||
expect: "'node'\n" + prompt_unix },
|
||||
{ client: client_unix, send: 'function name(){ return "nodejs"; };name()',
|
||||
expect: "'nodejs'\n" + prompt_unix },
|
||||
]);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user