Skip to content

Commit 8141b1d

Browse files
repl: fix dot command handling in multiline mode
Update conditional logic to correctly handle dot commands in multiline REPL input Fixes: #63864 Refs: #63889 Signed-off-by: SudhansuBandha <bandhasudhansu@gmail.com>
1 parent 3501b3e commit 8141b1d

2 files changed

Lines changed: 52 additions & 4 deletions

File tree

lib/repl.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ const {
7676
StringPrototypeCharAt,
7777
StringPrototypeEndsWith,
7878
StringPrototypeIncludes,
79+
StringPrototypeIndexOf,
7980
StringPrototypeRepeat,
8081
StringPrototypeSlice,
8182
StringPrototypeStartsWith,
@@ -807,10 +808,17 @@ class REPLServer extends Interface {
807808
// Check to see if a REPL keyword was used. If it returns true,
808809
// display next prompt and return.
809810
if (trimmedCmd) {
810-
if (StringPrototypeCharAt(trimmedCmd, 0) === '.' &&
811-
StringPrototypeCharAt(trimmedCmd, 1) !== '.' &&
812-
NumberIsNaN(NumberParseFloat(trimmedCmd))) {
813-
const matches = RegExpPrototypeExec(/^\.([^\s]+)\s*(.*)$/, trimmedCmd);
811+
// If condition validates for dot commands at the beginning of the line,
812+
// or dot commands after some whitespace.
813+
const isDotCommandAtStart = StringPrototypeCharAt(trimmedCmd, 0) === '.' &&
814+
StringPrototypeCharAt(trimmedCmd, 1) !== '.';
815+
const dotIndex = StringPrototypeIndexOf(trimmedCmd, '.');
816+
const isDotCommandAfterWhitespace = dotIndex > 0 &&
817+
StringPrototypeCharAt(trimmedCmd, dotIndex + 1) !== '.';
818+
819+
if ((isDotCommandAtStart || isDotCommandAfterWhitespace) &&
820+
NumberIsNaN(NumberParseFloat(trimmedCmd))) {
821+
const matches = RegExpPrototypeExec(/(?:^|\s)\.([^\s]+)\s*(.*)$/, trimmedCmd);
814822
const keyword = matches?.[1];
815823
const rest = matches?.[2];
816824
if (FunctionPrototypeCall(_parseREPLKeyword, self, keyword, rest) === true) {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const { startNewREPLServer } = require('../common/repl');
5+
6+
7+
const dotCommandSyntaxError =
8+
/Uncaught SyntaxError: Unexpected token '\.'/;
9+
10+
11+
function runDotCommand(command, validate) {
12+
const { replServer, output } = startNewREPLServer();
13+
14+
replServer.on('exit', common.mustCall());
15+
replServer.write('function a() {\n');
16+
replServer.write(`${command}\n`);
17+
validate(replServer, output);
18+
replServer.write('arr = [1,\n');
19+
replServer.write(`${command}\n`);
20+
validate(replServer, output);
21+
replServer.close();
22+
}
23+
24+
runDotCommand('.break', common.mustCall((replServer, output) => {
25+
replServer.write('1 + 1\n');
26+
assert.doesNotMatch(output.accumulator, dotCommandSyntaxError);
27+
assert.match(output.accumulator, /2\n/);
28+
}, 2));
29+
30+
runDotCommand('.clear', common.mustCall((replServer, output) => {
31+
replServer.write('1 + 1\n');
32+
assert.doesNotMatch(output.accumulator, dotCommandSyntaxError);
33+
assert.match(output.accumulator, /2\n/);
34+
}, 2));
35+
36+
runDotCommand('.help', common.mustCall((replServer, output) => {
37+
replServer.write('1 + 1\n');
38+
assert.doesNotMatch(output.accumulator, dotCommandSyntaxError);
39+
assert.match(output.accumulator, /2\n/);
40+
}, 2));

0 commit comments

Comments
 (0)