From c0aa2db0f89d0bd57e711470ca73386b9192ee6b Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 27 Jul 2026 08:17:18 +0200 Subject: [PATCH] Add regression test for property rows without accessors Corrupt or hand-written metadata can contain a property with no MethodSemantics rows at all. MetadataTypeDefinition.Properties already skips properties with neither a visible getter nor setter, so neither the parameterized-property path nor the ordinary one ever sees them; the accessor-method emission also tolerates a missing accessor by construction. Pin that with an ILPretty case containing both a parameterized and an ordinary accessor-less property. Assisted-by: Claude:claude-fable-5:Claude Code --- .../ICSharpCode.Decompiler.Tests.csproj | 3 ++ .../ILPrettyTestRunner.cs | 6 ++++ .../ILPretty/NoAccessorProperties.cs | 9 +++++ .../ILPretty/NoAccessorProperties.il | 33 +++++++++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/ILPretty/NoAccessorProperties.cs create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/ILPretty/NoAccessorProperties.il diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index 4cdadca46..010f69d91 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -158,6 +158,7 @@ + @@ -202,6 +203,8 @@ + + diff --git a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs index 3e50801b6..bf560a612 100644 --- a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs @@ -159,6 +159,12 @@ namespace ICSharpCode.Decompiler.Tests await Run(); } + [Test] + public async Task NoAccessorProperties() + { + await Run(); + } + [Test] public async Task Issue1145() { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/NoAccessorProperties.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/NoAccessorProperties.cs new file mode 100644 index 000000000..dc76b7b10 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/NoAccessorProperties.cs @@ -0,0 +1,9 @@ +public class BrokenProperties +{ + private int _field; + + public int Touch(int i) + { + return _field + i; + } +} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/NoAccessorProperties.il b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/NoAccessorProperties.il new file mode 100644 index 000000000..fc59fe3d4 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/NoAccessorProperties.il @@ -0,0 +1,33 @@ +// Property rows without any MethodSemantics accessors (corrupt or hand-written +// metadata). The type system skips such properties, whether parameterized or not; +// decompilation must not crash on them. +.class public auto ansi beforefieldinit BrokenProperties extends [mscorlib]System.Object +{ + .field private int32 _field + + .property instance int32 Parameterized(int32) + { + } // end of property BrokenProperties::Parameterized + + .property instance int32 Plain() + { + } // end of property BrokenProperties::Plain + + .method public hidebysig instance int32 Touch (int32 i) cil managed + { + .maxstack 8 + ldarg.0 + ldfld int32 BrokenProperties::_field + ldarg.1 + add + ret + } // end of method BrokenProperties::Touch + + .method public hidebysig specialname rtspecialname instance void .ctor () cil managed + { + .maxstack 8 + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } // end of method BrokenProperties::.ctor +}