Stack overflow while handling SignatureCycle2 test #986

Open
opened 2026-09-25 08:56:45 -05:00 by Lozov-Petr · 0 comments
Lozov-Petr commented 2026-09-25 08:56:45 -05:00 (Migrated from github.com)

Roslyn has a test with signatures cycle - here. When loading this binary Cecil stack overflows. This simple code snippet demonstrates it:

using System;
using Mono.Cecil;
using System.Linq;

namespace Worker
{
    public class Program
    {
        private static void Main(string[] args)
        {
            if (args.Length != 1)
            {
                Console.WriteLine($"Program requires one argument, {args.Length} given\n");
                return;
            }

            var numTypes = TryLoad(args[0]);
            Console.WriteLine($"{numTypes} types found");
        }

        private static int TryLoad(string moduleName)
        {
            try
            {
                var readerParamsWithoutSymbols = new ReaderParameters()
                {
                    ReadSymbols = false
                };
                var module = ModuleDefinition.ReadModule(moduleName, readerParamsWithoutSymbols);
                return module.Types.Count();
            }
            catch
            {
            }
            return 0;
        }
    }
}

I think the fix should be done in 'public IMetadataTokenProvider LookupToken (MetadataToken token)' function, At the start it should check that token is not handled (a dedicated HashSet will help), if yes - throw an exception, if not - add the handled token to the set. Then execute the code of the function in a try/finally block, and remove the token from the set in finally.

Roslyn has a test with signatures cycle - [here](https://github.com/dotnet/roslyn/tree/main/src/Compilers/Test/Resources/Core/MetadataTests/Invalid/Signatures/SignatureCycle2.exe). When loading this binary Cecil stack overflows. This simple code snippet demonstrates it: ```csharp using System; using Mono.Cecil; using System.Linq; namespace Worker { public class Program { private static void Main(string[] args) { if (args.Length != 1) { Console.WriteLine($"Program requires one argument, {args.Length} given\n"); return; } var numTypes = TryLoad(args[0]); Console.WriteLine($"{numTypes} types found"); } private static int TryLoad(string moduleName) { try { var readerParamsWithoutSymbols = new ReaderParameters() { ReadSymbols = false }; var module = ModuleDefinition.ReadModule(moduleName, readerParamsWithoutSymbols); return module.Types.Count(); } catch { } return 0; } } } ``` I think the fix should be done in 'public IMetadataTokenProvider LookupToken (MetadataToken token)' function, At the start it should check that token is not handled (a dedicated HashSet will help), if yes - throw an exception, if not - add the handled token to the set. Then execute the code of the function in a try/finally block, and remove the token from the set in finally.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-jbevain/cecil#986
No description provided.