Repository navigation
Fix rid lists when the target table has 0xFFFF rows - #591
Open
pcshrosbree wants to merge 1 commit into
Open
pcshrosbree wants to merge 1 commit into
pcshrosbree wants to merge 1 commit into
Conversation
With 0xFFFF rows the list column is normally 2 bytes wide, so the end-of-table value 0x10000 is stored as 0 in every row after the last owner with items. GetRidList handled that 0 only when the next row was the source table's last row. With two or more trailing empty owners, the last owner with items got an empty list, so its params, fields or PDB local variables were silently dropped. Treat a 0 in the next row as the end of the table whenever the target table has 0xFFFF rows. ENCMetadata.GetRidList already treats any 0 as the end.
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.
Fixes #590
When a list's target table has exactly 65,535 rows,
CompressedMetadata.GetRidListreturned an empty list for the last nonempty owner if two or more empty owners followed it. This PR treats a 0 in the next row's list column as the end of the table whenever the target table has 0xFFFF rows, not only when the next row is the source table's last row.Why this shape: with 0xFFFF rows the column is normally 2 bytes wide, so the end-of-table value 0x10000 is stored as 0, and every trailing empty owner holds that 0. Their own lists stay empty, because
GetRidListalready returns an empty list when the start is 0. ThetableDest.Rows == 0xFFFFtest stays, so files whose target table has any other row count read as before. When it has exactly 0xFFFF rows, a 0 in the next row is now read as the end of the table, whatever wrote it. I haven't tested files that use 0 there for another purpose.ENCMetadata.GetRidListalready treats any 0 as the end of the table.What I ran (dnlib's net6.0 build, .NET SDK 10.0.401, Linux x64):
65534and0at master, and65535and1with this change.MetadataBuilder. The cases cover Param, Field and Portable PDB LocalVariable lists. For each list kind, I used 65,534, 65,535 and 65,536 target rows and zero to three trailing empty owners. I compared every owner's list with what was written. At master, the six 65,535-row files with two or three trailing empty owners lose the last nonempty owner's 7 items. With this change all 36 match.ModuleWriter. Master misreads 2 of them; this change reads all 12 correctly.Read, not run:
TypeDef.MethodList,EventMap,PropertyMapand Portable PDB local constants go through the sameGetRidList, so this change covers them too. I didn't generate files for them.dnlib has no test project, so this PR adds no test. The repro is in #590, and I can share the generator if it helps.