-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
readline: fix issue with newline-less last line #47317
readline: fix issue with newline-less last line #47317
Conversation
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: nodejs#47305
I haven't included a test because I'm not sure what it should be. Since I found this after the fix to the previous infinite loop bug I found (#46731), I'm hesitant to just copy and paste the multi-line test and remove the trailing newline. I also am about to go home for the night but wanted to get this up so nobody wastes their time trying to figure out #47305, if this does actually fix it. Further, with the amount of issues around this, I'm not sure if someone wants a closer eye on what's happening and why these bugs are getting through. |
A test is definitely needed here, otherwise the issue is going to come back eventually. |
The repl test probably isn't strictly necessary, but this area's tests has been lacking sufficiently varying cases which have caused a few bugs to be missed, so it seems reasonable to include.
I added a repl test which is virtually identical to the multiline test that already existed. It might be overkill, but I figure just in case. The readline test checks the minimal issue I posted previously. Both tests fail without the update to readline/interface.js. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, LGTM if tests are passing. Two comments:
- Could you add a comment in
test/fixtures/repl-load-multiline-no-trailing-newline.js
that the missing EOL is on purpose (sure it's in the name of the file, but that can easily be missed). - Can you run the linter to fix all the reported style nits?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually think the fixed code is more readable than the original, while still correctly keeping track of the state of the RegExp.
LGTM! 🥳
Landed in 9decb70 |
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: #47305 PR-URL: #47317 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
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: #47305 PR-URL: #47317 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
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: nodejs#47305 PR-URL: nodejs#47317 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
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, andkInsertString
will be called from that point. If it does contain a new line,lastIndex
will be equal tos.length
, so the slice will be the empty string.Fixes: #47305