col: fix cur_col underflow on backspace over a wide char#4464
Open
aizu-m wants to merge 1 commit into
Open
Conversation
The BS handler in handle_not_graphic() subtracts the last stored character's width from lns->cur_col (a size_t) and only guards against cur_col == 0. When the last graphic character is double-width and the column was reset by CR then advanced by a single space, cur_col is 1 and cur_col -= 2 wraps to SIZE_MAX. That feeds l_max_col and the stored c_column, so flush_line() sizes count[] as l_max_col + 1 (== 0) and then memsets sizeof(size_t) * l_max_col bytes and indexes count[SIZE_MAX] -- an out-of-bounds write reachable from stdin under a UTF-8 locale. Clamp the subtraction so the column cannot go below zero. Signed-off-by: Aizal Khan <aizumusheer2@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AddressSanitizer, feeding col a small crafted stream under a UTF-8 locale:
Tracked it back to the BS branch in handle_not_graphic(). cur_col is a
size_t and the only guard there is cur_col == 0. Give it a double-width
glyph, then CR, one space, then BS: the last stored character still has
c_width 2 while cur_col has dropped to 1, so cur_col -= 2 wraps to
SIZE_MAX. That value then lands in l_max_col and the stored c_column, and
flush_line() sizes count[] as l_max_col + 1 (which wraps to 0) before it
memsets and indexes the array, so the write runs off the end.
Reproducer under a UTF-8 locale:
Clamp the subtraction to the column origin, matching the intent of the
existing cur_col == 0 check.