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;
|
var evalCmd = self.bufferedCommand + cmd;
|
||||||
if (/^\s*\{/.test(evalCmd) && /\}\s*$/.test(evalCmd)) {
|
evalCmd = preprocess(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';
|
|
||||||
}
|
|
||||||
|
|
||||||
debug('eval %j', evalCmd);
|
debug('eval %j', evalCmd);
|
||||||
self.eval(evalCmd, self.context, 'repl', finish);
|
self.eval(evalCmd, self.context, 'repl', finish);
|
||||||
@ -539,6 +527,26 @@ function REPLServer(prompt,
|
|||||||
// Display prompt again
|
// Display prompt again
|
||||||
self.displayPrompt();
|
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() {
|
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
|
// or block comment. https://github.com/nodejs/node/issues/3611
|
||||||
{ client: client_unix, send: 'a = 3.5e',
|
{ client: client_unix, send: 'a = 3.5e',
|
||||||
expect: /^SyntaxError: Invalid or unexpected token/ },
|
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