mirror of
https://github.com/nodejs/node.git
synced 2025-08-15 13:48:44 +02:00
readline: fix issue with newline-less last line
The logic for reading lines was slightly flawed, in that it assumed there would be a final new line. It handled the case where there are no new lines, but this then broke if there were some new lines. The fix in logic is basically removing the special case where there are no new lines by changing it to always read the final line with no new lines. This works because if a file contains no new lines, the final line is the first line, and all is well. There is some subtlety in this functioning, however. If the last line contains no new lines, then `lastIndex` will be the start of the last line, and `kInsertString` will be called from that point. If it does contain a new line, `lastIndex` will be equal to `s.length`, so the slice will be the empty string. Fixes: https://github.com/nodejs/node/issues/47305 PR-URL: https://github.com/nodejs/node/pull/47317 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
parent
c94be4125b
commit
9decb70d05
4 changed files with 85 additions and 14 deletions
|
@ -1324,21 +1324,19 @@ class Interface extends InterfaceConstructor {
|
|||
if (typeof s === 'string' && s) {
|
||||
// Erase state of previous searches.
|
||||
lineEnding.lastIndex = 0;
|
||||
let nextMatch = RegExpPrototypeExec(lineEnding, s);
|
||||
// If no line endings are found, just insert the string as is.
|
||||
if (nextMatch === null) {
|
||||
this[kInsertString](s);
|
||||
} else {
|
||||
// Keep track of the end of the last match.
|
||||
let lastIndex = 0;
|
||||
do {
|
||||
this[kInsertString](StringPrototypeSlice(s, lastIndex, nextMatch.index));
|
||||
({ lastIndex } = lineEnding);
|
||||
this[kLine]();
|
||||
// Restore lastIndex as the call to kLine could have mutated it.
|
||||
lineEnding.lastIndex = lastIndex;
|
||||
} while ((nextMatch = RegExpPrototypeExec(lineEnding, s)) !== null);
|
||||
let nextMatch;
|
||||
// Keep track of the end of the last match.
|
||||
let lastIndex = 0;
|
||||
while ((nextMatch = RegExpPrototypeExec(lineEnding, s)) !== null) {
|
||||
this[kInsertString](StringPrototypeSlice(s, lastIndex, nextMatch.index));
|
||||
({ lastIndex } = lineEnding);
|
||||
this[kLine]();
|
||||
// Restore lastIndex as the call to kLine could have mutated it.
|
||||
lineEnding.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.
|
||||
this[kInsertString](StringPrototypeSlice(s, lastIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue