Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/cecil.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvitek-karas <vitek.karas@microsoft.com>2020-08-27 14:48:27 +0300
committerMarek Safar <marek.safar@gmail.com>2020-09-07 22:04:06 +0300
commit75fc419764f239dcdd679657316e6eae31e04dc2 (patch)
tree3763e97908a4405eefffbcb636e3a3ce06bcd23f
parentc2dec1423990005029279785905e8c54abb706d4 (diff)
Fix crash with null local scoperelease/5.0
-rw-r--r--Mono.Cecil.Cil/MethodBody.cs27
-rw-r--r--Test/Mono.Cecil.Tests/ILProcessorTests.cs14
2 files changed, 17 insertions, 24 deletions
diff --git a/Mono.Cecil.Cil/MethodBody.cs b/Mono.Cecil.Cil/MethodBody.cs
index 4aa71a9..d970a01 100644
--- a/Mono.Cecil.Cil/MethodBody.cs
+++ b/Mono.Cecil.Cil/MethodBody.cs
@@ -340,32 +340,11 @@ namespace Mono.Cecil.Cil {
UpdateLocalScope (debug_info.Scope, removedInstruction, existingInstruction, ref cache);
}
- static void UpdateLocalScope (ScopeDebugInformation scope, int startFromOffset, int offset, Instruction instructionRemoved)
- {
- // For both start and enf offsets on the scope:
- // * If the offset is resolved (points to instruction by reference) only update it if the instruction it points to is being removed.
- // For non-removed instructions it remains correct regardless of any updates to the instructions.
- // * If the offset is not resolved (stores the instruction offset number itself)
- // update the number accordingly to keep it pointing to the correct instruction (by offset).
-
- if ((!scope.Start.IsResolved && scope.Start.Offset >= startFromOffset) ||
- (instructionRemoved != null && scope.Start.ResolvedInstruction == instructionRemoved))
- scope.Start = new InstructionOffset (scope.Start.Offset + offset);
-
- // For end offset only update it if it's not the special sentinel value "EndOfMethod"; that should remain as-is.
- if (!scope.End.IsEndOfMethod &&
- ((!scope.End.IsResolved && scope.End.Offset >= startFromOffset) ||
- (instructionRemoved != null && scope.End.ResolvedInstruction == instructionRemoved)))
- scope.End = new InstructionOffset (scope.End.Offset + offset);
-
- if (scope.HasScopes) {
- foreach (var subScope in scope.Scopes)
- UpdateLocalScope (subScope, startFromOffset, offset, instructionRemoved);
- }
- }
-
void UpdateLocalScope (ScopeDebugInformation scope, Instruction removedInstruction, Instruction existingInstruction, ref InstructionOffsetCache cache)
{
+ if (scope == null)
+ return;
+
if (!scope.Start.IsResolved)
scope.Start = ResolveInstructionOffset (scope.Start, ref cache);
diff --git a/Test/Mono.Cecil.Tests/ILProcessorTests.cs b/Test/Mono.Cecil.Tests/ILProcessorTests.cs
index 446e8fc..8836615 100644
--- a/Test/Mono.Cecil.Tests/ILProcessorTests.cs
+++ b/Test/Mono.Cecil.Tests/ILProcessorTests.cs
@@ -194,6 +194,20 @@ namespace Mono.Cecil.Tests {
methodBody.Method.Module.Dispose ();
}
+ [Test]
+ public void EditWithDebugInfoButNoLocalScopes()
+ {
+ var methodBody = CreateTestMethod (OpCodes.Ret);
+ methodBody.Method.DebugInformation = new MethodDebugInformation (methodBody.Method);
+
+ var il = methodBody.GetILProcessor ();
+ il.Replace (methodBody.Instructions [0], il.Create (OpCodes.Nop));
+
+ Assert.AreEqual (1, methodBody.Instructions.Count);
+ Assert.AreEqual (Code.Nop, methodBody.Instructions [0].OpCode.Code);
+ Assert.Null (methodBody.Method.DebugInformation.Scope);
+ }
+
static void AssertOpCodeSequence (OpCode [] expected, MethodBody body)
{
var opcodes = body.Instructions.Select (i => i.OpCode).ToArray ();