diffviewer: stop reading past the end of a line, and free the word diff - #5153
Open
ilia-maslakov wants to merge 2 commits into
Open
diffviewer: stop reading past the end of a line, and free the word diff#5153ilia-maslakov wants to merge 2 commits into
ilia-maslakov wants to merge 2 commits into
Conversation
ret holds the common substrings the recursion found, and it is freed only where there were some and every call below returned success. The ordinary case, where nothing is in common and the recursion ends, falls through to the bottom of the function and loses it, as do the three failure paths. Signed-off-by: Ilia Maslakov <il.smind@gmail.com>
dview_str_utf8_offset_to_pos() is asked for the byte at a column, and the column it is asked for is the width of the pane; a line is usually shorter than that. g_utf8_offset_to_pointer() counts out the characters it is asked for without looking for the end of the string, so it walked over whatever followed the line. Past the end the rest is padding, a byte to a column, which is the number it was arriving at anyway; compute it instead of walking to it. What is drawn does not change. Signed-off-by: Ilia Maslakov <il.smind@gmail.com>
Contributor
|
|
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.
Problem
Two defects in the diff viewer, both reached by simply opening a diff.
dview_str_utf8_offset_to_pos()reads past the end of the line. It is askedfor the byte offset of a given column, and the column it is asked for is the
width of the pane. A line shorter than that is walked past the end:
g_utf8_offset_to_pointer()counts out the characters it is asked for withoutlooking for the end of the string.
hdiff_multi()drops the array of common substrings.retis freed onlywhere the function found something and every recursion below it succeeded. The
ordinary case — nothing in common, which is how the recursion ends — falls
through to the bottom of the function and loses it, as do the three
return FALSEpaths.Change
Past the end of the line the rest is padding, one byte to a column, which is the
number
g_utf8_offset_to_pointer()was arriving at anyway by stepping overwhatever followed the string; it is now computed instead of walked to. The
rendering is unchanged — I compared the screen dumps of a diff before and after,
byte for byte.
hdiff_multi()keeps the result in a local and freesreton the way out ofevery path.
Verified
Opening a diff, scrolling it, switching the layout and quitting, under
valgrind --leak-check=full --errors-for-leak-kinds=definite:Ubuntu 24.04,
--enable-werror: no compiler warnings,make check69/69.