From b652dafe3da2aa6d9c9bd1c79da4142457d84e62 Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:44:51 +0200 Subject: [PATCH 01/20] test: add reproduction test for JSONL with unicode separators Signed-off-by: Francesco Castaldi --- ...eadline-unicode-line-separators-opt-out.js | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 test/parallel/test-readline-unicode-line-separators-opt-out.js diff --git a/test/parallel/test-readline-unicode-line-separators-opt-out.js b/test/parallel/test-readline-unicode-line-separators-opt-out.js new file mode 100644 index 00000000000..1e34a63898f --- /dev/null +++ b/test/parallel/test-readline-unicode-line-separators-opt-out.js @@ -0,0 +1,26 @@ +'use strict'; +const common = require('../common'); +const assert = require('node:assert'); +const readline = require('node:readline'); +const { Readable } = require('node:stream'); + +// Test 1: JSONL with Unicode line/paragraph separators inside JSON strings +{ + const jsonlData = '{"text":"Hello\\u2028World"}\n{"text":"Foo\\u2029Bar"}\n'; + + const rli = readline.createInterface({ + input: Readable.from(jsonlData), + unicodeLineSeparators: false, + }); + + const parsed = []; + rli.on('line', (line) => { + parsed.push(JSON.parse(line)); + }); + + rli.on('close', common.mustCall(() => { + assert.strictEqual(parsed.length, 2); + assert.deepStrictEqual(parsed[0], { text: 'Hello\u2028World' }); + assert.deepStrictEqual(parsed[1], { text: 'Foo\u2029Bar' }); + })); +} From 51f5b12c30af84a5b225fdd450607e21464f5ce0 Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:45:01 +0200 Subject: [PATCH 02/20] test: add test asserting default unicode separator handling Signed-off-by: Francesco Castaldi --- ...t-readline-unicode-line-separators-opt-out.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/parallel/test-readline-unicode-line-separators-opt-out.js b/test/parallel/test-readline-unicode-line-separators-opt-out.js index 1e34a63898f..d849a577efb 100644 --- a/test/parallel/test-readline-unicode-line-separators-opt-out.js +++ b/test/parallel/test-readline-unicode-line-separators-opt-out.js @@ -24,3 +24,19 @@ const { Readable } = require('node:stream'); assert.deepStrictEqual(parsed[1], { text: 'Foo\u2029Bar' }); })); } + +// Test 2: Default behavior remains unicodeLineSeparators: true +{ + const input = '012\n345\r67\r\n89\u{2028}ABC\u{2029}DEF'; + + const rli = readline.createInterface({ + input: Readable.from(input), + }); + + const lines = []; + rli.on('line', (line) => lines.push(line)); + + rli.on('close', common.mustCall(() => { + assert.deepStrictEqual(lines, ['012', '345', '67', '89', 'ABC', 'DEF']); + })); +} From c681ecc9e67c23968f2890addce0d44f75102a2c Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:45:12 +0200 Subject: [PATCH 03/20] test: add test for crlf and isolated cr when unicode separators are disabled Signed-off-by: Francesco Castaldi --- ...-readline-unicode-line-separators-opt-out.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/parallel/test-readline-unicode-line-separators-opt-out.js b/test/parallel/test-readline-unicode-line-separators-opt-out.js index d849a577efb..0b3b21217db 100644 --- a/test/parallel/test-readline-unicode-line-separators-opt-out.js +++ b/test/parallel/test-readline-unicode-line-separators-opt-out.js @@ -40,3 +40,20 @@ const { Readable } = require('node:stream'); assert.deepStrictEqual(lines, ['012', '345', '67', '89', 'ABC', 'DEF']); })); } + +// Test 3: Standard CRLF/LF/CR still split, but U+2028 and U+2029 do not split +{ + const input = '012\n345\r67\r\n89\u{2028}ABC\u{2029}DEF'; + + const rli = readline.createInterface({ + input: Readable.from(input), + unicodeLineSeparators: false, + }); + + const lines = []; + rli.on('line', (line) => lines.push(line)); + + rli.on('close', common.mustCall(() => { + assert.deepStrictEqual(lines, ['012', '345', '67', '89\u{2028}ABC\u{2029}DEF']); + })); +} From 06cd9eab7b1b22b6521d1daca37cb92609dc4e82 Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:45:32 +0200 Subject: [PATCH 04/20] test: add type validation tests for unicodeLineSeparators option Signed-off-by: Francesco Castaldi --- ...readline-unicode-line-separators-opt-out.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/parallel/test-readline-unicode-line-separators-opt-out.js b/test/parallel/test-readline-unicode-line-separators-opt-out.js index 0b3b21217db..8b8f373eba4 100644 --- a/test/parallel/test-readline-unicode-line-separators-opt-out.js +++ b/test/parallel/test-readline-unicode-line-separators-opt-out.js @@ -57,3 +57,21 @@ const { Readable } = require('node:stream'); assert.deepStrictEqual(lines, ['012', '345', '67', '89\u{2028}ABC\u{2029}DEF']); })); } + +// Test 4: Argument type validation for unicodeLineSeparators +{ + for (const badValue of ['false', 0, 1, {}, [], () => {}]) { + assert.throws( + () => { + readline.createInterface({ + input: Readable.from(''), + unicodeLineSeparators: badValue, + }); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + }, + ); + } +} From 5812c96a8197b5e816ed25d02c90ee87bee3dc2d Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:45:42 +0200 Subject: [PATCH 05/20] test: add readline promises interface test with unicodeLineSeparators Signed-off-by: Francesco Castaldi --- .../test-readline-promises-unicode.js | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 test/parallel/test-readline-promises-unicode.js diff --git a/test/parallel/test-readline-promises-unicode.js b/test/parallel/test-readline-promises-unicode.js new file mode 100644 index 00000000000..9adeec1f7d7 --- /dev/null +++ b/test/parallel/test-readline-promises-unicode.js @@ -0,0 +1,21 @@ +'use strict'; +const common = require('../common'); +const assert = require('node:assert'); +const readlinePromises = require('node:readline/promises'); +const { Readable } = require('node:stream'); + +// Test readlinePromises.createInterface with unicodeLineSeparators: false +{ + const input = '{"a":1}\u2028{"b":2}\n{"c":3}'; + const rli = readlinePromises.createInterface({ + input: Readable.from(input), + unicodeLineSeparators: false, + }); + + const lines = []; + rli.on('line', (line) => lines.push(line)); + + rli.on('close', common.mustCall(() => { + assert.deepStrictEqual(lines, ['{"a":1}\u2028{"b":2}', '{"c":3}']); + })); +} From 3ce6ca1336781c9b97f25a320f20e0ec2fa1c98b Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:45:54 +0200 Subject: [PATCH 06/20] test: add async iterator test with unicodeLineSeparators Signed-off-by: Francesco Castaldi --- .../test-readline-async-iterators-unicode.js | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 test/parallel/test-readline-async-iterators-unicode.js diff --git a/test/parallel/test-readline-async-iterators-unicode.js b/test/parallel/test-readline-async-iterators-unicode.js new file mode 100644 index 00000000000..1bd1adc1a11 --- /dev/null +++ b/test/parallel/test-readline-async-iterators-unicode.js @@ -0,0 +1,25 @@ +'use strict'; +const common = require('../common'); +const assert = require('node:assert'); +const readline = require('node:readline'); +const { Readable } = require('node:stream'); + +// Test async iterator on readline interface with unicodeLineSeparators: false +(async () => { + const input = 'line 1\u2028continued\nline 2\u2029continued\nline 3'; + const rli = readline.createInterface({ + input: Readable.from(input), + unicodeLineSeparators: false, + }); + + const lines = []; + for await (const line of rli) { + lines.push(line); + } + + assert.deepStrictEqual(lines, [ + 'line 1\u2028continued', + 'line 2\u2029continued', + 'line 3', + ]); +})().then(common.mustCall()); From 0603e603bc73586736d99e16075e7d5b10a0e50d Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:46:04 +0200 Subject: [PATCH 07/20] readline: import validateBoolean from internal/validators Signed-off-by: Francesco Castaldi --- lib/internal/readline/interface.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/internal/readline/interface.js b/lib/internal/readline/interface.js index bc8f3042761..179ffa9cf8f 100644 --- a/lib/internal/readline/interface.js +++ b/lib/internal/readline/interface.js @@ -45,6 +45,7 @@ const { const { validateAbortSignal, + validateBoolean, validateString, validateUint32, } = require('internal/validators'); From 00a0cbfd23d7638c27e76e861b64cfb99b6a1280 Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:46:16 +0200 Subject: [PATCH 08/20] readline: declare kLineEnding private symbol Signed-off-by: Francesco Castaldi --- lib/internal/readline/interface.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/internal/readline/interface.js b/lib/internal/readline/interface.js index 179ffa9cf8f..5c9bec6f724 100644 --- a/lib/internal/readline/interface.js +++ b/lib/internal/readline/interface.js @@ -118,6 +118,7 @@ const kMoveUpOrHistoryPrev = Symbol('_moveUpOrHistoryPrev'); const kInsertString = Symbol('_insertString'); const kLine = Symbol('_line'); const kLine_buffer = Symbol('_line_buffer'); +const kLineEnding = Symbol('_lineEnding'); const kKillRing = Symbol('_killRing'); const kKillRingCursor = Symbol('_killRingCursor'); const kMoveCursor = Symbol('_moveCursor'); From 4cc59b8cdc17e195d03f5ae43a8bef86261c2ca9 Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:46:28 +0200 Subject: [PATCH 09/20] readline: define unicode and non-unicode line ending patterns Signed-off-by: Francesco Castaldi --- lib/internal/readline/interface.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/internal/readline/interface.js b/lib/internal/readline/interface.js index 5c9bec6f724..bd21f548de3 100644 --- a/lib/internal/readline/interface.js +++ b/lib/internal/readline/interface.js @@ -87,7 +87,9 @@ const kMincrlfDelay = 100; * - \u2028 (Unicode 'LINE SEPARATOR') * - \u2029 (Unicode 'PARAGRAPH SEPARATOR') */ -const lineEnding = /\r?\n|\r(?!\n)|\u2028|\u2029/g; +const lineEndingWithUnicode = /\r?\n|\r(?!\n)|\u2028|\u2029/g; +const lineEndingWithoutUnicode = /\r?\n|\r(?!\n)/g; +const lineEnding = lineEndingWithUnicode; const kLineObjectStream = Symbol('line object stream'); const kQuestionCancel = Symbol('kQuestionCancel'); From 8d0c9e651410f195d8ff86c9becb446803d470d4 Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:46:51 +0200 Subject: [PATCH 10/20] readline: parse unicodeLineSeparators option in InterfaceConstructor Signed-off-by: Francesco Castaldi --- lib/internal/readline/interface.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/internal/readline/interface.js b/lib/internal/readline/interface.js index bd21f548de3..cb8e479eeb6 100644 --- a/lib/internal/readline/interface.js +++ b/lib/internal/readline/interface.js @@ -180,6 +180,7 @@ function InterfaceConstructor(input, output, completer, terminal) { let prompt = '> '; let signal; let historyOptions; + let unicodeLineSeparators = true; if (input?.input) { // An options object was given @@ -212,6 +213,10 @@ function InterfaceConstructor(input, output, completer, terminal) { } } + if (input.unicodeLineSeparators !== undefined) { + unicodeLineSeparators = input.unicodeLineSeparators; + } + if (signal) { validateAbortSignal(signal, 'options.signal'); } From 85ebf1e2e9091551e18572c691bef3a9acea3465 Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:47:05 +0200 Subject: [PATCH 11/20] readline: validate boolean type for unicodeLineSeparators option Signed-off-by: Francesco Castaldi --- lib/internal/readline/interface.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/internal/readline/interface.js b/lib/internal/readline/interface.js index cb8e479eeb6..3c24e9dadb9 100644 --- a/lib/internal/readline/interface.js +++ b/lib/internal/readline/interface.js @@ -214,6 +214,7 @@ function InterfaceConstructor(input, output, completer, terminal) { } if (input.unicodeLineSeparators !== undefined) { + validateBoolean(input.unicodeLineSeparators, 'options.unicodeLineSeparators'); unicodeLineSeparators = input.unicodeLineSeparators; } From d6fa926238b9368a3fea9ecf08ba6e7240837518 Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:47:16 +0200 Subject: [PATCH 12/20] readline: expose unicodeLineSeparators property on Interface instance Signed-off-by: Francesco Castaldi --- lib/internal/readline/interface.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/internal/readline/interface.js b/lib/internal/readline/interface.js index 3c24e9dadb9..e6eea756339 100644 --- a/lib/internal/readline/interface.js +++ b/lib/internal/readline/interface.js @@ -272,6 +272,7 @@ function InterfaceConstructor(input, output, completer, terminal) { this.setPrompt(prompt); this.terminal = !!terminal; + this.unicodeLineSeparators = unicodeLineSeparators; function onerror(err) { self.emit('error', err); From 6ddf8412dc680cf3214341f5a90e3d24bda819d9 Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:47:30 +0200 Subject: [PATCH 13/20] readline: attach active line ending pattern to instance kLineEnding Signed-off-by: Francesco Castaldi --- lib/internal/readline/interface.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/internal/readline/interface.js b/lib/internal/readline/interface.js index e6eea756339..6d21f82cc8c 100644 --- a/lib/internal/readline/interface.js +++ b/lib/internal/readline/interface.js @@ -273,6 +273,9 @@ function InterfaceConstructor(input, output, completer, terminal) { this.terminal = !!terminal; this.unicodeLineSeparators = unicodeLineSeparators; + this[kLineEnding] = unicodeLineSeparators ? + lineEndingWithUnicode : + lineEndingWithoutUnicode; function onerror(err) { self.emit('error', err); From 9b060ce1735bedf6b72f2a46142f806956455264 Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:47:49 +0200 Subject: [PATCH 14/20] readline: gate unicode character check in onStreamData Signed-off-by: Francesco Castaldi --- lib/internal/readline/interface.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/internal/readline/interface.js b/lib/internal/readline/interface.js index 6d21f82cc8c..3ece926e8c2 100644 --- a/lib/internal/readline/interface.js +++ b/lib/internal/readline/interface.js @@ -661,8 +661,10 @@ class Interface extends InterfaceConstructor { // string split is much cheaper than the regular expression. const lines = StringPrototypeIncludes(string, '\r') || - StringPrototypeIncludes(string, '\u2028') || - StringPrototypeIncludes(string, '\u2029') ? + (this.unicodeLineSeparators && ( + StringPrototypeIncludes(string, '\u2028') || + StringPrototypeIncludes(string, '\u2029') + )) ? RegExpPrototypeSymbolSplit(lineEnding, string) : StringPrototypeSplit(string, '\n'); const lastIndex = lines.length - 1; From 5e986ccb82d0f0de04d3ecf6bfa65723c8fb9be1 Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:48:00 +0200 Subject: [PATCH 15/20] readline: use instance kLineEnding in onStreamData regex splitting Signed-off-by: Francesco Castaldi --- lib/internal/readline/interface.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/readline/interface.js b/lib/internal/readline/interface.js index 3ece926e8c2..d8cfaae33e3 100644 --- a/lib/internal/readline/interface.js +++ b/lib/internal/readline/interface.js @@ -665,7 +665,7 @@ class Interface extends InterfaceConstructor { StringPrototypeIncludes(string, '\u2028') || StringPrototypeIncludes(string, '\u2029') )) ? - RegExpPrototypeSymbolSplit(lineEnding, string) : + RegExpPrototypeSymbolSplit(this[kLineEnding], string) : StringPrototypeSplit(string, '\n'); const lastIndex = lines.length - 1; if (lastIndex === 0) { From 0d756c77f5c461000ab1426d7df8885946bd617a Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:48:25 +0200 Subject: [PATCH 16/20] readline: update _ttyWrite to use instance line ending pattern Signed-off-by: Francesco Castaldi --- lib/internal/readline/interface.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/internal/readline/interface.js b/lib/internal/readline/interface.js index d8cfaae33e3..580ab7335eb 100644 --- a/lib/internal/readline/interface.js +++ b/lib/internal/readline/interface.js @@ -89,7 +89,6 @@ const kMincrlfDelay = 100; */ const lineEndingWithUnicode = /\r?\n|\r(?!\n)|\u2028|\u2029/g; const lineEndingWithoutUnicode = /\r?\n|\r(?!\n)/g; -const lineEnding = lineEndingWithUnicode; const kLineObjectStream = Symbol('line object stream'); const kQuestionCancel = Symbol('kQuestionCancel'); @@ -1572,16 +1571,16 @@ class Interface extends InterfaceConstructor { default: if (typeof s === 'string' && s) { // Erase state of previous searches. - lineEnding.lastIndex = 0; + this[kLineEnding].lastIndex = 0; let nextMatch; // Keep track of the end of the last match. let lastIndex = 0; - while ((nextMatch = RegExpPrototypeExec(lineEnding, s)) !== null) { + while ((nextMatch = RegExpPrototypeExec(this[kLineEnding], s)) !== null) { this[kInsertString](StringPrototypeSlice(s, lastIndex, nextMatch.index)); - ({ lastIndex } = lineEnding); + ({ lastIndex } = this[kLineEnding]); this[kLine](); // Restore lastIndex as the call to kLine could have mutated it. - lineEnding.lastIndex = lastIndex; + this[kLineEnding].lastIndex = lastIndex; } // This ensures that the last line is written if it doesn't end in a newline. // Note that the last line may be the first line, in which case this still works. From a9511731712b1adc327c59ed01972b41995db1c4 Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:48:36 +0200 Subject: [PATCH 17/20] test: add test for ttyWrite line splitting with unicode separators Signed-off-by: Francesco Castaldi --- .../test-readline-tty-unicode-separators.js | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 test/parallel/test-readline-tty-unicode-separators.js diff --git a/test/parallel/test-readline-tty-unicode-separators.js b/test/parallel/test-readline-tty-unicode-separators.js new file mode 100644 index 00000000000..e093da7fbb6 --- /dev/null +++ b/test/parallel/test-readline-tty-unicode-separators.js @@ -0,0 +1,46 @@ +'use strict'; +require('../common'); +const assert = require('node:assert'); +const readline = require('node:readline'); +const { PassThrough } = require('node:stream'); + +// Test terminal write with unicodeLineSeparators: false +{ + const input = new PassThrough(); + const output = new PassThrough(); + + const rli = readline.createInterface({ + input, + output, + terminal: true, + unicodeLineSeparators: false, + }); + + const lines = []; + rli.on('line', (line) => lines.push(line)); + + input.write('foo\u2028bar\n'); + rli.close(); + + assert.deepStrictEqual(lines, ['foo\u2028bar']); +} + +// Test terminal write with default unicodeLineSeparators: true +{ + const input = new PassThrough(); + const output = new PassThrough(); + + const rli = readline.createInterface({ + input, + output, + terminal: true, + }); + + const lines = []; + rli.on('line', (line) => lines.push(line)); + + input.write('foo\u2028bar\n'); + rli.close(); + + assert.deepStrictEqual(lines, ['foo', 'bar']); +} From 2460294a6289c16682b1cfa076551d4b96e1bcbe Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:48:54 +0200 Subject: [PATCH 18/20] benchmark: add benchmark for readline stream data line splitting Signed-off-by: Francesco Castaldi --- benchmark/readline/readline-stream-split.js | 35 +++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 benchmark/readline/readline-stream-split.js diff --git a/benchmark/readline/readline-stream-split.js b/benchmark/readline/readline-stream-split.js new file mode 100644 index 00000000000..2e5bd8ef5f1 --- /dev/null +++ b/benchmark/readline/readline-stream-split.js @@ -0,0 +1,35 @@ +'use strict'; +const common = require('../common.js'); +const readline = require('readline'); +const { Readable } = require('stream'); + +const bench = common.createBenchmark(main, { + n: [1e4], + unicodeLineSeparators: [0, 1], +}); + +function main({ n, unicodeLineSeparators }) { + const line = '{"item":"data","value":42}\n'; + const chunks = Array.from({ length: 100 }, () => line); + + bench.start(); + let remaining = n; + + function run() { + if (remaining-- === 0) { + bench.end(n); + return; + } + + const input = Readable.from(chunks); + const rl = readline.createInterface({ + input, + unicodeLineSeparators: Boolean(unicodeLineSeparators), + }); + + rl.on('line', () => {}); + rl.on('close', run); + } + + run(); +} From 99defbd55ff45af04ae0c57928796a5836509924 Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:49:06 +0200 Subject: [PATCH 19/20] doc: document unicodeLineSeparators in readline.createInterface Signed-off-by: Francesco Castaldi --- doc/api/readline.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/api/readline.md b/doc/api/readline.md index 02e56e4c6a3..778bc540006 100644 --- a/doc/api/readline.md +++ b/doc/api/readline.md @@ -990,6 +990,10 @@ changes: **Default:** `8`. * `signal` {AbortSignal} Allows closing the interface using an AbortSignal. Aborting the signal will internally call `close` on the interface. + * `unicodeLineSeparators` {boolean} If `true`, `\u2028` (LINE SEPARATOR) and + `\u2029` (PARAGRAPH SEPARATOR) are treated as line endings. If `false`, + only `\r\n`, `\n`, and `\r` are treated as line endings. + **Default:** `true`. * Returns: {readline.Interface} The `readline.createInterface()` method creates a new `readline.Interface` From d5483ab598db0555b3e75c1b3a1545e0ecf42018 Mon Sep 17 00:00:00 2001 From: Francesco Castaldi Date: Sat, 3 Oct 2026 12:49:20 +0200 Subject: [PATCH 20/20] doc: document unicodeLineSeparators in readlinePromises.createInterface Fixes: https://github.com/nodejs/node/issues/60606 Signed-off-by: Francesco Castaldi --- doc/api/readline.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/api/readline.md b/doc/api/readline.md index 778bc540006..be6d689ae18 100644 --- a/doc/api/readline.md +++ b/doc/api/readline.md @@ -724,6 +724,10 @@ added: v17.0.0 * `tabSize` {integer} The number of spaces a tab is equal to (minimum 1). **Default:** `8`. * `signal` {AbortSignal} Allows closing the interface using an AbortSignal. + * `unicodeLineSeparators` {boolean} If `true`, `\u2028` (LINE SEPARATOR) and + `\u2029` (PARAGRAPH SEPARATOR) are treated as line endings. If `false`, + only `\r\n`, `\n`, and `\r` are treated as line endings. + **Default:** `true`. * Returns: {readlinePromises.Interface} The `readlinePromises.createInterface()` method creates a new `readlinePromises.Interface`