From 522370665d908a8fb987756c1b75672d27f90c99 Mon Sep 17 00:00:00 2001 From: Dario Piotrowicz Date: Sat, 22 Mar 2025 18:47:55 +0000 Subject: [PATCH 1/3] readline: fix unicode line separators being ignored --- lib/internal/readline/interface.js | 11 ++++++++-- .../parallel/test-readline-line-separators.js | 20 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 test/parallel/test-readline-line-separators.js diff --git a/lib/internal/readline/interface.js b/lib/internal/readline/interface.js index c831c79756f343..3ab930b0c5db9d 100644 --- a/lib/internal/readline/interface.js +++ b/lib/internal/readline/interface.js @@ -75,8 +75,15 @@ const { StringDecoder } = require('string_decoder'); const kHistorySize = 30; const kMaxUndoRedoStackSize = 2048; const kMincrlfDelay = 100; -// \r\n, \n, or \r followed by something other than \n -const lineEnding = /\r?\n|\r(?!\n)/g; +/** + * The end of a line is signaled by either one of the following: + * - \r\n + * - \n + * - \r followed by something other than \n + * - \u2028 (Unicode 'LINE SEPARATOR') + * - \u2029 (Unicode 'PARAGRAPH SEPARATOR') + */ +const lineEnding = /\r?\n|\r(?!\n)|\u2028|\u2029/g; const kLineObjectStream = Symbol('line object stream'); const kQuestionCancel = Symbol('kQuestionCancel'); diff --git a/test/parallel/test-readline-line-separators.js b/test/parallel/test-readline-line-separators.js new file mode 100644 index 00000000000000..787ade5550c075 --- /dev/null +++ b/test/parallel/test-readline-line-separators.js @@ -0,0 +1,20 @@ +'use strict'; +const common = require('../common'); +const assert = require('node:assert'); +const readline = require('node:readline'); +const { Readable } = require('node:stream'); + +const str = '123\n456\r789\u{2028}ABC\u{2029}DEF'; + +const rli = new readline.Interface({ + input: Readable.from(str), +}); + +const linesRead = []; +rli.on('line', (line) => linesRead.push(line)); + +rli.on('close', common.mustCall(() => { + const regexpLines = str.split(/^/m).map((line) => line.trim()); + // Readline interprets different lines in the same way js regular expressions do + assert.deepStrictEqual(linesRead, regexpLines); +})); From a5b3e45a65a1386437f5e3bb535805c0fb787169 Mon Sep 17 00:00:00 2001 From: Dario Piotrowicz Date: Sat, 22 Mar 2025 19:32:49 +0000 Subject: [PATCH 2/3] fixup! readline: fix unicode line separators being ignored also include \r\n in test --- test/parallel/test-readline-line-separators.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/parallel/test-readline-line-separators.js b/test/parallel/test-readline-line-separators.js index 787ade5550c075..96d456ec77ee19 100644 --- a/test/parallel/test-readline-line-separators.js +++ b/test/parallel/test-readline-line-separators.js @@ -4,7 +4,7 @@ const assert = require('node:assert'); const readline = require('node:readline'); const { Readable } = require('node:stream'); -const str = '123\n456\r789\u{2028}ABC\u{2029}DEF'; +const str = '012\n345\r67\r\n89\u{2028}ABC\u{2029}DEF'; const rli = new readline.Interface({ input: Readable.from(str), @@ -14,7 +14,7 @@ const linesRead = []; rli.on('line', (line) => linesRead.push(line)); rli.on('close', common.mustCall(() => { - const regexpLines = str.split(/^/m).map((line) => line.trim()); + const regexpLines = str.split(/^/m).map((line) => line.trim()).filter(Boolean); // Readline interprets different lines in the same way js regular expressions do assert.deepStrictEqual(linesRead, regexpLines); })); From d0b4c39a165cb87b9dbcfc7b4e73d62a9d454028 Mon Sep 17 00:00:00 2001 From: Dario Piotrowicz Date: Sat, 22 Mar 2025 19:43:42 +0000 Subject: [PATCH 3/3] fixup! readline: fix unicode line separators being ignored remove confising comparison with regexp splits --- test/parallel/test-readline-line-separators.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/parallel/test-readline-line-separators.js b/test/parallel/test-readline-line-separators.js index 96d456ec77ee19..7591f50c7fa178 100644 --- a/test/parallel/test-readline-line-separators.js +++ b/test/parallel/test-readline-line-separators.js @@ -14,7 +14,5 @@ const linesRead = []; rli.on('line', (line) => linesRead.push(line)); rli.on('close', common.mustCall(() => { - const regexpLines = str.split(/^/m).map((line) => line.trim()).filter(Boolean); - // Readline interprets different lines in the same way js regular expressions do - assert.deepStrictEqual(linesRead, regexpLines); + assert.deepStrictEqual(linesRead, ['012', '345', '67', '89', 'ABC', 'DEF']); }));