REPL: dot-commands produce SyntaxError inside multi-line input
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Anfängerfreundlichkeit
- 72/100
- Issue-Typ
- Bug
- Klarheit
- Klar beschrieben
- Aktivitätsstatus
- Ruhig
- Tech-Stack
- javascript, nodejs
- Bereich
- cli
Rechercherichtung
Beginne in lib/repl.js und konzentriere dich auf den Recoverable-error-Pfad, kAddNewLineOnTTY und den onLine(cmd)-Handler. Reproduziere das Problem mit den bereitgestellten printf-Befehlen unter Verwendung von node -i und verfolge dann, wie die gepufferte mehrzeilige Eingabe die Prüfung auf Dot-Befehle erreicht. Die Aufgabe ist abgeschlossen, wenn .break, .clear, .exit und .help innerhalb einer mehrzeiligen Eingabe funktionieren, ohne einen SyntaxError zu erzeugen.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Version
any v24.1.0+
Platform
Tested on:
Microsoft Windows NT 10.0.19045.0 x64;
WSL2 Debian;
Subsystem
REPL
What steps will reproduce the bug?
printf "function a() {\n.break\n" | node -i
printf "function a() {\n.exit\n" | node -i
printf "function a() {\n.help\n" | node -i
How often does it reproduce? Is there a required condition?
Always. Required condition: any registered dot-command typed as the first line after a Recoverable error if self.terminal === true. This includes both real interactive TTYs and node -i with piped stdin.
What is the expected behavior? Why is that the expected behavior?
Welcome to Node.js v24.0.2.
Type ".help" for more information.
> function a() {
| .exit
Welcome to Node.js v24.0.2.
Type ".help" for more information.
> function a() {
| .break
>
Welcome to Node.js v24.0.2.
Type ".help" for more information.
> function a() {
| .help
.break Sometimes you get stuck, this gets you out
.clear Alias for .break
.editor Enter editor mode
.exit Exit the REPL
.help Print this help message
.load Load JS from a file into the REPL session
.save Save all evaluated commands in this REPL session to a file
Press Ctrl+C to abort current expression, Ctrl+D to exit the REPL
|
What do you see instead?
Welcome to Node.js v24.1.0.
Type ".help" for more information.
> function a() {
| .exit
.exit
^
Uncaught SyntaxError: Unexpected token '.'
Welcome to Node.js v24.1.0.
Type ".help" for more information.
> function a() {
| .break
.break
^
Uncaught SyntaxError: Unexpected token '.'
Welcome to Node.js v24.1.0.
Type ".help" for more information.
> function a() {
| .help
.help
^
Uncaught SyntaxError: Unexpected token '.'
Additional information
The expected behavior is dot-commands working in multi-line mode. Since 24.1.0 they do not. Only changes to TTY multi-line input behavior in 24.1.0 were introduced by #58003.
Bisect:
git checkout v24.1.0
./configure
make -j2 node > /dev/null 2>/dev/null
printf "function a(){\n.break\n" | ./node -i
git checkout 629a954477^
make -j2 node > /dev/null 2>/dev/null
printf "function a(){\n.break\n" | ./node -i
git checkout 629a954477
make -j2 node > /dev/null 2>/dev/null
printf "function a(){\n.break\n" | ./node -i
Hunk level bisect:
git checkout 629a954477
make -j2 node >/dev/null 2>/dev/null
printf "n\nn\nn\nn\ny\nn\n" | git checkout -p 629a954477^ -- lib/repl.js
make -j2 node >/dev/null 2>/dev/null
printf "function a() {\n.break\n" | ./node -i
particular hunk introducing the bug:
@@ -943,33 +941,15 @@ function REPLServer(prompt,
}
// If error was SyntaxError and not JSON.parse error
- if (e) {
- if (e instanceof Recoverable && !sawCtrlD) {
- // Start buffering data like that:
- // {
- // ... x: 1
- // ... }
+ // We can start a multiline command
+ if (e instanceof Recoverable && !sawCtrlD) {
+ if (self.terminal) {
+ self[kAddNewLineOnTTY]();
+ } else {
self[kBufferedCommandSymbol] += cmd + '\n';
self.displayPrompt();
- return;
- }
- }
-
- // In the next two if blocks, we do not use os.EOL instead of '\n'
- // because on Windows it is '\r\n'
- if (StringPrototypeIncludes(cmd, '\n')) { // If you are editing a multiline command
- self.history[0] = self[kNormalizeHistoryLineEndings](cmd, '\n', '\r');
- } else if (self[kBufferedCommandSymbol]) { // If a new multiline command was entered
- // Remove the first N lines from the self.history array
- // where N is the number of lines in the buffered command
-
- const lines = StringPrototypeSplit(self[kBufferedCommandSymbol], '\n');
- self.history = ArrayPrototypeSlice(self.history, lines.length);
- lines[lines.length - 1] = cmd;
- const newHistoryLine = ArrayPrototypeJoin(ArrayPrototypeReverse(lines), '\r');
- if (self.history[0] !== newHistoryLine) {
- ArrayPrototypeUnshift(self.history, newHistoryLine);
}
+ return;
}
if (e) {
Reason:
- The change in handling of
Recoverableerror shifts the TTY multi-line handling intoself[kAddNewLineOnTTY]();. - It causes
onLine(cmd)handler to be called with the whole multi-line buffer incmd. - That results in the REPL keyword check failing - instead of checking the first character in
".break"it checks the first character in"function a() {\r.break". (\nbecomes\rinkAddHistory, not relevant to the bug) - Which leads to REPL keywords being passed to
evalwhere they produceSyntaxError: Unexpected token '.'.
- Vorherrschende Sprache
- JavaScript
- Sterne
- 122k
- Forks
- 37.4k
- Ø Merge
- 4 T. 3 Std.
- Gemergte PRs (30 T.)
- 279
Beitragsleitfaden
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus nodejs/node
-
doc
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 65/100
-
build
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 88/100
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 84/100
-
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 90/100
-
feature request
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 65/100
-
Theme loads third-party resources on every page (jsdelivr web font, cdnjs Font Awesome) – GDPR Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
docToolchain/docToolchain#1705 ·
-
Timezone select lists one option per character; duplicate "Failed" reason; shared tracker popover id Offenbug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
nightscout/nocturne#1414 ·
-
bug v2
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
modelcontextprotocol/inspector#2458 · 1 Kommentar ·
-
Mend: dependency security vulnerability status: needs triage 🕵️♀️
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
carbon-design-system/ibm-products#9907 ·