Skip to content

Commit 1df51a3

Browse files
authored
[mono] ILStrip sorts custom attribute table (#87923)
This prevents custom attribute table corruption by sorting it as the last step when stripping an assembly. Addresses #85414. The PR will have to be backported to net7.0.
1 parent fad3d54 commit 1df51a3

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

src/tasks/MonoTargetsTasks/ILStrip/AssemblyStripper/AssemblyStripper.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@
1212

1313
namespace AssemblyStripper
1414
{
15+
class CustomAttrRowComparer : IComparer
16+
{
17+
public int Compare(object left, object right)
18+
{
19+
CustomAttributeRow row_left = (CustomAttributeRow)left;
20+
CustomAttributeRow row_right = (CustomAttributeRow)right;
21+
return row_left.Parent.RID.CompareTo(row_right.Parent.RID);
22+
}
23+
}
24+
1525
public class AssemblyStripper
1626
{
1727
AssemblyDefinition assembly;
@@ -40,6 +50,7 @@ void Strip()
4050
PatchMethods();
4151
PatchFields();
4252
PatchResources();
53+
SortCustomAttributes();
4354
Write();
4455
}
4556

@@ -192,6 +203,20 @@ void PatchResources()
192203
}
193204
}
194205

206+
// Types that are trimmed away also have their respective rows removed from the
207+
// custom attribute table. This introduces holes in their places, causing the table
208+
// to no longer be sorted by Parent, corrupting the assembly. Runtimes assume ordering
209+
// and may fail to locate the attributes set for a particular type. This step sorts
210+
// the custom attribute table again.
211+
void SortCustomAttributes()
212+
{
213+
CustomAttributeTable table = (CustomAttributeTable)stripped_tables[CustomAttributeTable.RId];
214+
if (table == null)
215+
return;
216+
217+
table.Rows.Sort(new CustomAttrRowComparer());
218+
}
219+
195220
void Write()
196221
{
197222
stripped.MetadataRoot.Accept(metadata_writer);
@@ -209,7 +234,6 @@ public static void StripAssembly(string assemblyFile, string outputPath)
209234
{
210235
AssemblyDefinition assembly = AssemblyFactory.GetAssembly(assemblyFile);
211236
AssemblyStripper.StripAssembly(assembly, outputPath);
212-
213237
}
214238
}
215239
}

0 commit comments

Comments
 (0)