From 9dc21a946f725e5f8c12338c89f99521d37fe0c1 Mon Sep 17 00:00:00 2001 From: Zohaib Arif Date: Thu, 29 Jan 2026 14:37:06 +0500 Subject: [PATCH] readline: initialize input before history manager --- lib/internal/readline/interface.js | 12 ++++++++---- .../test-readline-history-init-order.js | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 test/parallel/test-readline-history-init-order.js diff --git a/lib/internal/readline/interface.js b/lib/internal/readline/interface.js index 08f7aaa9e3e7e8..859ce3ebc398fd 100644 --- a/lib/internal/readline/interface.js +++ b/lib/internal/readline/interface.js @@ -215,7 +215,6 @@ function InterfaceConstructor(input, output, completer, terminal) { input.removeHistoryDuplicates = removeHistoryDuplicates; } - this.setupHistoryManager(input); if (completer !== undefined && typeof completer !== 'function') { throw new ERR_INVALID_ARG_VALUE('completer', completer); @@ -234,6 +233,7 @@ function InterfaceConstructor(input, output, completer, terminal) { this[kSubstringSearch] = null; this.output = output; this.input = input; + this.setupHistoryManager(input); this[kUndoStack] = []; this[kRedoStack] = []; this[kPreviousCursorCols] = -1; @@ -384,9 +384,13 @@ class Interface extends InterfaceConstructor { setupHistoryManager(options) { this.historyManager = new ReplHistory(this, options); - if (options.onHistoryFileLoaded) { - this.historyManager.initialize(options.onHistoryFileLoaded); - } + // Only initialize REPL history when createInterface() + // was called with an options object (options.input). + // This prevents accidental REPL history init when + // createInterface(input) is used. + if (options?.input && typeof options.onHistoryFileLoaded === 'function') { + this.historyManager.initialize(options.onHistoryFileLoaded); + } ObjectDefineProperty(this, 'history', { __proto__: null, configurable: true, enumerable: true, diff --git a/test/parallel/test-readline-history-init-order.js b/test/parallel/test-readline-history-init-order.js new file mode 100644 index 00000000000000..41bcd70b49b26c --- /dev/null +++ b/test/parallel/test-readline-history-init-order.js @@ -0,0 +1,18 @@ +'use strict'; + +const assert = require('assert'); +const readline = require('readline'); +const { PassThrough } = require('stream'); + +assert.doesNotThrow(() => { + const input = new PassThrough(); + + // This simulates the condition that previously caused + // accidental REPL history initialization. + input.onHistoryFileLoaded = () => {}; + + readline.createInterface({ + input, + output: new PassThrough() + }); +});