Repository navigation
sas7bcat: compare block pointers three-way instead of subtracting - #420
Merged
Merged
Conversation
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.
compare_block_pointersin the SAS7BCAT catalog reader returns a 64-bit subtraction truncated toint. The values it sorts pack the catalog page number into the high 32 bits ((page << 32) + pos, withpageread from the file), so two block pointers on different pages differ only above bit 32 and the truncated result loses that difference. Pointers on pages 1 and 2 compare as equal, and a descending set is left unsorted, soqsortruns with a comparator that violates the required total order (undefined behavior, and out-of-bounds reads in some qsort implementations) and the adjacent-duplicate removal insas7bcat_uniq_indexno longer works, reading and emitting the same catalog block twice.Compare the two values three-way instead, the same way
dta_compare_strlsanddta_compare_value_labelsalready do in this codebase (the latter with a comment about this exact overflow). Reproducer with the current code:compare((1<<32), (2<<32))returns 0, andqsortof{3<<32, 2<<32, 1<<32}leaves the array in descending order; with the fix it sorts ascending.