From a606e38cd10bb070f8037c32b85971c877fdf16b Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Wed, 3 Sep 2025 22:15:39 +0200 Subject: [PATCH] Fix potential infinite loop in `TryGetOriginalTargetFrameworkAttribute` --- src/DotNet/AssemblyDef.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/DotNet/AssemblyDef.cs b/src/DotNet/AssemblyDef.cs index 0e89652c1..109b196d8 100644 --- a/src/DotNet/AssemblyDef.cs +++ b/src/DotNet/AssemblyDef.cs @@ -901,6 +901,21 @@ void InitializeTargetFrameworkAttribute() { var caRid = list[i]; if (!readerModule.TablesStream.TryReadCustomAttributeRow(caRid, out var caRow)) continue; + + // Prevent a possible infinite loop. + // This can happen when a custom AssemblyResolver calls this function when resolving an AssemblyRef. + // If this function encounters a custom attribute whose type is a MemberRef with a TypeSpec class, + // the MemberRef constructor called by ResolveCustomAttributeType() will call ResolveTypeDef() which + // will make it back to the AssemblyResolver and back to this function creating an infinite loop. + // The TargetFrameworkAttribute will never be generic so we can just skip parsing any generic attributes. + if (!CodedToken.CustomAttributeType.Decode(caRow.Type, out MDToken token)) + continue; + if (token.Table == Table.MemberRef && + (!readerModule.TablesStream.TryReadMemberRefRow(token.Rid, out var mrRow) || + readerModule.ResolveMemberRefParent(mrRow.Class, gpContext) is TypeSpec ts && + ts.TypeSig is GenericInstSig)) + continue; + var caType = readerModule.ResolveCustomAttributeType(caRow.Type, gpContext); if (!TryGetName(caType, out var ns, out var name)) continue;