From a0a6ce41c0e5292413ca33dcb76d514e608d21e5 Mon Sep 17 00:00:00 2001 From: Steve Gilham Date: Fri, 13 Aug 2021 00:27:19 +0100 Subject: [PATCH] Addressing issue #781 (#782) * Pose the problem * Quick and v dirty fix * A better and more targeted fix (to fix the previous fix) --- Mono.Cecil.Cil/MethodBody.cs | 6 ++-- Test/Mono.Cecil.Tests/ILProcessorTests.cs | 39 +++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/Mono.Cecil.Cil/MethodBody.cs b/Mono.Cecil.Cil/MethodBody.cs index 1526b5973..1aecb5755 100644 --- a/Mono.Cecil.Cil/MethodBody.cs +++ b/Mono.Cecil.Cil/MethodBody.cs @@ -312,7 +312,7 @@ void UpdateLocalScopes (Instruction removedInstruction, Instruction existingInst if (debug_info == null) return; - // Local scopes store start/end pair of "instruction offsets". Instruction offset can be either resolved, in which case it + // Local scopes store start/end pair of "instruction offsets". Instruction offset can be either resolved, in which case it // has a reference to Instruction, or unresolved in which case it stores numerical offset (instruction offset in the body). // Typically local scopes loaded from PE/PDB files will be resolved, but it's not a requirement. // Each instruction has its own offset, which is populated on load, but never updated (this would be pretty expensive to do). @@ -407,7 +407,7 @@ InstructionOffset ResolveInstructionOffset(InstructionOffset inputOffset, ref In // Allow for trailing null values in the case of // instructions.Size < instructions.Capacity if (item == null) - break; + return new InstructionOffset (items [i - 1]); cache.Instruction = item; @@ -424,4 +424,4 @@ InstructionOffset ResolveInstructionOffset(InstructionOffset inputOffset, ref In } } } -} +} \ No newline at end of file diff --git a/Test/Mono.Cecil.Tests/ILProcessorTests.cs b/Test/Mono.Cecil.Tests/ILProcessorTests.cs index 4eecfe3ff..c5854033f 100644 --- a/Test/Mono.Cecil.Tests/ILProcessorTests.cs +++ b/Test/Mono.Cecil.Tests/ILProcessorTests.cs @@ -63,6 +63,45 @@ public void InsertBeforeIssue697 () } } + [Test] + public void InsertBeforeIssue697bis () + { + var parameters = new ReaderParameters { SymbolReaderProvider = new MdbReaderProvider () }; + using (var module = GetResourceModule ("Issue697.dll", parameters)) { + var pathGetterDef = module.GetTypes () + .SelectMany (t => t.Methods) + .First (m => m.Name.Equals ("get_Defer")); + + var body = pathGetterDef.Body; + var worker = body.GetILProcessor (); + var initialBody = body.Instructions.ToList (); + Console.WriteLine (initialBody.Sum (i => i.GetSize ())); + + var head = initialBody.First (); + var opcode = worker.Create (OpCodes.Ldc_I4_1); + worker.InsertBefore (head, opcode); + + Assert.That (pathGetterDef.DebugInformation.Scope.Start.IsEndOfMethod, Is.False); + foreach (var subscope in pathGetterDef.DebugInformation.Scope.Scopes) + Assert.That (subscope.Start.IsEndOfMethod, Is.False); + + // big test -- we can write w/o crashing + var unique = Guid.NewGuid ().ToString (); + var output = Path.GetTempFileName (); + var outputdll = output + ".dll"; + + var writer = new WriterParameters () { + SymbolWriterProvider = new MdbWriterProvider (), + WriteSymbols = true + }; + using (var sink = File.Open (outputdll, FileMode.Create, FileAccess.ReadWrite)) { + module.Write (sink, writer); + } + + Assert.Pass (); + } + } + [Test] public void InsertAfter () {