Skip to content

Commit 72fc4eb

Browse files
princejwesleyevanlucas
authored andcommitted
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' > ``` PR-URL: #7794 Reviewed-By: Evan Lucas <[email protected]>
1 parent d3f0a6a commit 72fc4eb

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
@@ -471,19 +471,7 @@ function REPLServer(prompt,
471471
}
472472

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

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

543551
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+
constcommon=require('../common');
4+
constassert=require('assert');
5+
constrepl=require('repl');
6+
conststream=require('stream');
7+
8+
common.globalCheck=false;
9+
10+
constr=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+
constexpected='1\n[Function a]\n';
17+
constgot=r.output.accumulator.join('');
18+
assert.strictEqual(got,expected);
19+
20+
functioninitRepl(){
21+
constinput=newstream();
22+
input.write=input.pause=input.resume=()=>{};
23+
input.readable=true;
24+
25+
constoutput=newstream();
26+
output.writable=true;
27+
output.accumulator=[];
28+
29+
output.write=(data)=>output.accumulator.push(data);
30+
31+
returnrepl.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:UnexpectedtokenILLEGAL/},
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)