From 3d51d8a581ad5f6c58cae7a840043e67405060f7 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Fri, 29 Aug 2025 20:59:21 +0200 Subject: [PATCH] Fix #3547: Fix duplicate key in PropertyAndEventBackingFieldLookup --- .../PropertyAndEventBackingFieldLookup.cs | 36 +++++++++++++------ .../Util/MultiDictionary.cs | 11 ++++++ 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/ICSharpCode.Decompiler/Metadata/PropertyAndEventBackingFieldLookup.cs b/ICSharpCode.Decompiler/Metadata/PropertyAndEventBackingFieldLookup.cs index b28eb4264..e0882cdb7 100644 --- a/ICSharpCode.Decompiler/Metadata/PropertyAndEventBackingFieldLookup.cs +++ b/ICSharpCode.Decompiler/Metadata/PropertyAndEventBackingFieldLookup.cs @@ -19,6 +19,8 @@ using System.Collections.Generic; using System.Reflection.Metadata; +using ICSharpCode.Decompiler.Util; + namespace ICSharpCode.Decompiler.Metadata { class PropertyAndEventBackingFieldLookup @@ -33,7 +35,7 @@ namespace ICSharpCode.Decompiler.Metadata { this.metadata = metadata; - var nameToFieldMap = new Dictionary(); + var nameToFieldMap = new MultiDictionary(); foreach (var tdh in metadata.TypeDefinitions) { @@ -51,14 +53,22 @@ namespace ICSharpCode.Decompiler.Metadata var property = metadata.GetPropertyDefinition(pdh); var name = metadata.GetString(property.Name); // default C# property backing field name is "k__BackingField" - if (nameToFieldMap.TryGetValue($"<{name}>k__BackingField", out var fieldHandle)) + if (nameToFieldMap.TryGetValues($"<{name}>k__BackingField", out var fieldHandles)) { - propertyLookup[fieldHandle] = pdh; + foreach (var fieldHandle in fieldHandles) + { + propertyLookup[fieldHandle] = pdh; + } } - else if (nameToFieldMap.TryGetValue($"_{name}", out fieldHandle) - && fieldHandle.IsCompilerGenerated(metadata)) + else if (nameToFieldMap.TryGetValues($"_{name}", out fieldHandles)) { - propertyLookup[fieldHandle] = pdh; + foreach (var fieldHandle in fieldHandles) + { + if (fieldHandle.IsCompilerGenerated(metadata)) + { + propertyLookup[fieldHandle] = pdh; + } + } } } @@ -66,13 +76,19 @@ namespace ICSharpCode.Decompiler.Metadata { var ev = metadata.GetEventDefinition(edh); var name = metadata.GetString(ev.Name); - if (nameToFieldMap.TryGetValue(name, out var fieldHandle)) + if (nameToFieldMap.TryGetValues(name, out var fieldHandles)) { - eventLookup[fieldHandle] = edh; + foreach (var fieldHandle in fieldHandles) + { + eventLookup[fieldHandle] = edh; + } } - else if (nameToFieldMap.TryGetValue($"{name}Event", out fieldHandle)) + else if (nameToFieldMap.TryGetValues($"{name}Event", out fieldHandles)) { - eventLookup[fieldHandle] = edh; + foreach (var fieldHandle in fieldHandles) + { + eventLookup[fieldHandle] = edh; + } } } diff --git a/ICSharpCode.Decompiler/Util/MultiDictionary.cs b/ICSharpCode.Decompiler/Util/MultiDictionary.cs index 9b113870e..7dd882c30 100644 --- a/ICSharpCode.Decompiler/Util/MultiDictionary.cs +++ b/ICSharpCode.Decompiler/Util/MultiDictionary.cs @@ -86,6 +86,17 @@ namespace ICSharpCode.Decompiler.Util } } + public bool TryGetValues(TKey key, out IReadOnlyList values) + { + values = EmptyList.Instance; + if (dict.TryGetValue(key, out var list)) + { + values = list; + return true; + } + return false; + } + /// /// Returns the number of different keys. ///