Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc206f8d

Browse files
meixgtargos
authored andcommitted
repl: add isValidParentheses check before wrap input
PR-URL:#59607Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent0718a70 commitc206f8d

File tree

4 files changed

+121
-4
lines changed

4 files changed

+121
-4
lines changed

‎lib/internal/repl/utils.js‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
301301
functiongetInputPreview(input,callback){
302302
// For similar reasons as `defaultEval`, wrap expressions starting with a
303303
// curly brace with parenthesis.
304-
if(!wrapped&&input[0]==='{'&&input[input.length-1]!==';'){
304+
if(!wrapped&&input[0]==='{'&&input[input.length-1]!==';'&&isValidSyntax(input)){
305305
input=`(${input})`;
306306
wrapped=true;
307307
}
@@ -754,6 +754,25 @@ function setupReverseSearch(repl) {
754754

755755
conststartsWithBraceRegExp=/^\s*{/;
756756
constendsWithSemicolonRegExp=/;\s*$/;
757+
functionisValidSyntax(input){
758+
try{
759+
AcornParser.parse(input,{
760+
ecmaVersion:'latest',
761+
allowAwaitOutsideFunction:true,
762+
});
763+
returntrue;
764+
}catch{
765+
try{
766+
AcornParser.parse(`_=${input}`,{
767+
ecmaVersion:'latest',
768+
allowAwaitOutsideFunction:true,
769+
});
770+
returntrue;
771+
}catch{
772+
returnfalse;
773+
}
774+
}
775+
}
757776

758777
/**
759778
* Checks if some provided code represents an object literal.
@@ -776,4 +795,5 @@ module.exports = {
776795
setupPreview,
777796
setupReverseSearch,
778797
isObjectLiteral,
798+
isValidSyntax,
779799
};

‎lib/repl.js‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ const {
177177
setupPreview,
178178
setupReverseSearch,
179179
isObjectLiteral,
180+
isValidSyntax,
180181
}=require('internal/repl/utils');
181182
const{
182183
constants:{
@@ -445,7 +446,7 @@ function REPLServer(prompt,
445446
letawaitPromise=false;
446447
constinput=code;
447448

448-
if(isObjectLiteral(code)){
449+
if(isObjectLiteral(code)&&isValidSyntax(code)){
449450
// Add parentheses to make sure `code` is parsed as an expression
450451
code=`(${StringPrototypeTrim(code)})\n`;
451452
wrappedCmd=true;
@@ -2156,6 +2157,7 @@ module.exports = {
21562157
REPL_MODE_SLOPPY,
21572158
REPL_MODE_STRICT,
21582159
Recoverable,
2160+
isValidSyntax,
21592161
};
21602162

21612163
ObjectDefineProperty(module.exports,'builtinModules',{

‎test/parallel/test-repl-preview.js‎

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,83 @@ async function tests(options) {
157157
'\x1B[90m1\x1B[39m\x1B[12G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r',
158158
'\x1B[33m1\x1B[39m',
159159
]
160+
},{
161+
input:'aaaa',
162+
noPreview:'Uncaught ReferenceError: aaaa is not defined',
163+
preview:[
164+
'aaaa\r',
165+
'Uncaught ReferenceError: aaaa is not defined',
166+
]
167+
},{
168+
input:'/0',
169+
noPreview:'/0',
170+
preview:[
171+
'/0\r',
172+
'/0',
173+
'^',
174+
'',
175+
'Uncaught SyntaxError: Invalid regular expression: missing /',
176+
]
177+
},{
178+
input:'{})',
179+
noPreview:'{})',
180+
preview:[
181+
'{})\r',
182+
'{})',
183+
' ^',
184+
'',
185+
"Uncaught SyntaxError: Unexpected token ')'",
186+
],
187+
},{
188+
input:"{ a: '{' }",
189+
noPreview:"{ a: \x1B[32m'{'\x1B[39m }",
190+
preview:[
191+
"{ a: '{' }\r",
192+
"{ a: \x1B[32m'{'\x1B[39m }",
193+
],
194+
},{
195+
input:"{'{':0}",
196+
noPreview:"{ \x1B[32m'{'\x1B[39m: \x1B[33m0\x1B[39m }",
197+
preview:[
198+
"{'{':0}",
199+
"\x1B[90m{ '{': 0 }\x1B[39m\x1B[15G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r",
200+
"{ \x1B[32m'{'\x1B[39m: \x1B[33m0\x1B[39m }",
201+
],
202+
},{
203+
input:'{[Symbol.for("{")]: 0 }',
204+
noPreview:'{ \x1B[32mSymbol({)\x1B[39m: \x1B[33m0\x1B[39m }',
205+
preview:[
206+
'{[Symbol.for("{")]: 0 }\r',
207+
'{ \x1B[32mSymbol({)\x1B[39m: \x1B[33m0\x1B[39m }',
208+
],
209+
},{
210+
input:'{},{}',
211+
noPreview:'{}',
212+
preview:[
213+
'{},{}',
214+
'\x1B[90m{}\x1B[39m\x1B[13G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r',
215+
'{}',
216+
],
217+
},{
218+
input:'{} //',
219+
noPreview:'repl > ',
220+
preview:[
221+
'{} //\r',
222+
],
223+
},{
224+
input:'{} //;',
225+
noPreview:'repl > ',
226+
preview:[
227+
'{} //;\r',
228+
],
229+
},{
230+
input:'{throw 0}',
231+
noPreview:'Uncaught \x1B[33m0\x1B[39m',
232+
preview:[
233+
'{throw 0}',
234+
'\x1B[90m0\x1B[39m\x1B[17G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r',
235+
'Uncaught \x1B[33m0\x1B[39m',
236+
],
160237
}];
161238

162239
consthasPreview=repl.terminal&&
@@ -177,8 +254,13 @@ async function tests(options) {
177254
assert.deepStrictEqual(lines,preview);
178255
}else{
179256
assert.ok(lines[0].includes(noPreview),lines.map(inspect));
180-
if(preview.length!==1||preview[0]!==`${input}\r`)
181-
assert.strictEqual(lines.length,2);
257+
if(preview.length!==1||preview[0]!==`${input}\r`){
258+
if(preview[preview.length-1].includes('Uncaught SyntaxError')){
259+
assert.strictEqual(lines.length,5);
260+
}else{
261+
assert.strictEqual(lines.length,2);
262+
}
263+
}
182264
}
183265
}
184266
}

‎test/parallel/test-repl.js‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,19 @@ const errorTests = [
328328
expect:'[Function (anonymous)]'
329329
},
330330
// Multiline object
331+
{
332+
send:'{}),({}',
333+
expect:'| ',
334+
},
335+
{
336+
send:'}',
337+
expect:[
338+
'{}),({}',
339+
kArrow,
340+
'',
341+
/^UncaughtSyntaxError:/,
342+
]
343+
},
331344
{
332345
send:'{ a: ',
333346
expect:'| '

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp