Skip to content

Commit db0e906

Browse files
zeusdeuxMyles Borins
authored and
Myles Borins
committed
repl: Fixed node repl history edge case.
If the deprecated NODE_REPL_HISTORY_FILE is set to default node history file path ($HOME/.node_repl_history) and the file doesn't exist, then node creates the file and then crashes when it tries to parse that file as JSON thinking that it's an older JSON formatted history file. This fixes that bug. This patch also prevents node repl from throwing if the old history file is empty or if $HOME/.node_repl_history is empty. Fixes: #4102 PR-URL: #4108 Reviewed-By: Jeremiah Senkpiel <[email protected]>
1 parent 4856420 commit db0e906

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed

lib/internal/repl.js

+16-2
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,29 @@ function setupHistory(repl, historyPath, oldHistoryPath, ready) {
120120

121121
if (data) {
122122
repl.history = data.split(/[\n\r]+/, repl.historySize);
123-
} else if (oldHistoryPath) {
123+
} else if (oldHistoryPath === historyPath) {
124+
// If pre-v3.0, the user had set NODE_REPL_HISTORY_FILE to
125+
// ~/.node_repl_history, warn the user about it and proceed.
126+
repl._writeToOutput(
127+
'\nThe old repl history file has the same name and location as ' +
128+
`the new one i.e., ${historyPath} and is empty.\nUsing it as is.\n`);
129+
repl._refreshLine();
130+
131+
} else if (oldHistoryPath) {
124132
// Grab data from the older pre-v3.0 JSON NODE_REPL_HISTORY_FILE format.
125133
repl._writeToOutput(
126134
'\nConverting old JSON repl history to line-separated history.\n' +
127135
`The new repl history file can be found at ${historyPath}.\n`);
128136
repl._refreshLine();
129137

130138
try {
131-
repl.history = JSON.parse(fs.readFileSync(oldHistoryPath, 'utf8'));
139+
// Pre-v3.0, repl history was stored as JSON.
140+
// Try and convert it to line separated history.
141+
const oldReplJSONHistory = fs.readFileSync(oldHistoryPath, 'utf8');
142+
143+
// Only attempt to use the history if there was any.
144+
if (oldReplJSONHistory) repl.history = JSON.parse(oldReplJSONHistory);
145+
132146
if (!Array.isArray(repl.history)) {
133147
throw new Error('Expected array, got ' + typeof repl.history);
134148
}

test/fixtures/.empty-repl-history-file

Whitespace-only changes.

test/parallel/test-repl-persistent-history.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,20 @@ const homedirErr = '\nError: Could not get the home directory.\n' +
6565
'REPL session history will not be persisted.\n';
6666
const replFailedRead = '\nError: Could not open history file.\n' +
6767
'REPL session history will not be persisted.\n';
68+
const sameHistoryFilePaths = '\nThe old repl history file has the same name ' +
69+
'and location as the new one i.e., ' +
70+
path.join(common.tmpDir, '.node_repl_history') +
71+
' and is empty.\nUsing it as is.\n';
6872
// File paths
6973
const fixtures = path.join(common.testDir, 'fixtures');
7074
const historyFixturePath = path.join(fixtures, '.node_repl_history');
7175
const historyPath = path.join(common.tmpDir, '.fixture_copy_repl_history');
7276
const historyPathFail = path.join(common.tmpDir, '.node_repl\u0000_history');
7377
const oldHistoryPath = path.join(fixtures, 'old-repl-history-file.json');
7478
const enoentHistoryPath = path.join(fixtures, 'enoent-repl-history-file.json');
79+
const emptyHistoryPath = path.join(fixtures, '.empty-repl-history-file');
7580
const defaultHistoryPath = path.join(common.tmpDir, '.node_repl_history');
7681

77-
7882
const tests = [{
7983
env: { NODE_REPL_HISTORY: '' },
8084
test: [UP],
@@ -92,6 +96,16 @@ const tests = [{
9296
test: [UP],
9397
expected: [prompt, replDisabled, prompt]
9498
},
99+
{
100+
env: { NODE_REPL_HISTORY_FILE: emptyHistoryPath },
101+
test: [UP],
102+
expected: [prompt, convertMsg, prompt]
103+
},
104+
{
105+
env: { NODE_REPL_HISTORY_FILE: defaultHistoryPath },
106+
test: [UP],
107+
expected: [prompt, sameHistoryFilePaths, prompt]
108+
},
95109
{
96110
env: { NODE_REPL_HISTORY: historyPath },
97111
test: [UP, CLEAR],

0 commit comments

Comments
 (0)