Skip to content

Commit 3d41a44

Browse files
zeusdeuxFishrock123
authored andcommitted
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: nodejs#4102 PR-URL: nodejs#4108 Reviewed-By: Jeremiah Senkpiel <[email protected]>
1 parent 8f7af9a commit 3d41a44

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed

lib/internal/repl.js

Lines changed: 16 additions & 2 deletions
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

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

78-
7983
const tests = [{
8084
env: { NODE_REPL_HISTORY: '' },
8185
test: [UP],
@@ -93,6 +97,16 @@ const tests = [{
9397
test: [UP],
9498
expected: [prompt, replDisabled, prompt]
9599
},
100+
{
101+
env: { NODE_REPL_HISTORY_FILE: emptyHistoryPath },
102+
test: [UP],
103+
expected: [prompt, convertMsg, prompt]
104+
},
105+
{
106+
env: { NODE_REPL_HISTORY_FILE: defaultHistoryPath },
107+
test: [UP],
108+
expected: [prompt, sameHistoryFilePaths, prompt]
109+
},
96110
{
97111
env: { NODE_REPL_HISTORY: historyPath },
98112
test: [UP, CLEAR],

0 commit comments

Comments
 (0)