Browse Source

Fix #532: NullReferenceException when Cecil cannot decode a branch target.

pull/1012/head
Daniel Grunwald 8 years ago
parent
commit
bfea41d585
  1. 2
      ICSharpCode.Decompiler/Disassembler/ILStructure.cs
  2. 44
      ICSharpCode.Decompiler/IL/ILReader.cs

2
ICSharpCode.Decompiler/Disassembler/ILStructure.cs

@ -200,6 +200,8 @@ namespace ICSharpCode.Decompiler.Disassembler
break; break;
} }
} }
// ignore the branches where Cecil doesn't decode the target
result.RemoveAll(x => x.Value == null);
return result; return result;
} }

44
ICSharpCode.Decompiler/IL/ILReader.cs

@ -1339,26 +1339,30 @@ namespace ICSharpCode.Decompiler.IL
} }
} }
int DecodeBranchTarget(bool shortForm) int? DecodeBranchTarget(bool shortForm)
{ {
// int target = shortForm ? reader.ReadSByte() : reader.ReadInt32(); // int target = shortForm ? reader.ReadSByte() : reader.ReadInt32();
// target += reader.Position; // target += reader.Position;
// return target; // return target;
return ((Cil.Instruction)currentInstruction.Operand).Offset; return ((Cil.Instruction)currentInstruction.Operand)?.Offset;
} }
ILInstruction DecodeComparisonBranch(bool shortForm, ComparisonKind kind, bool un = false) ILInstruction DecodeComparisonBranch(bool shortForm, ComparisonKind kind, bool un = false)
{ {
int target = DecodeBranchTarget(shortForm); int? target = DecodeBranchTarget(shortForm);
var condition = Comparison(kind, un); var condition = Comparison(kind, un);
condition.ILRange = GetCurrentInstructionInterval(); condition.ILRange = GetCurrentInstructionInterval();
MarkBranchTarget(target); if (target != null) {
return new IfInstruction(condition, new Branch(target)); MarkBranchTarget(target.Value);
return new IfInstruction(condition, new Branch(target.Value));
} else {
return new IfInstruction(condition, new InvalidBranch("Invalid branch target"));
}
} }
ILInstruction DecodeConditionalBranch(bool shortForm, bool negate) ILInstruction DecodeConditionalBranch(bool shortForm, bool negate)
{ {
int target = DecodeBranchTarget(shortForm); int? target = DecodeBranchTarget(shortForm);
ILInstruction condition = Pop(); ILInstruction condition = Pop();
switch (condition.ResultType) { switch (condition.ResultType) {
case StackType.O: case StackType.O:
@ -1391,18 +1395,26 @@ namespace ICSharpCode.Decompiler.IL
} }
break; break;
} }
MarkBranchTarget(target); if (target != null) {
return new IfInstruction(condition, new Branch(target)); MarkBranchTarget(target.Value);
return new IfInstruction(condition, new Branch(target.Value));
} else {
return new IfInstruction(condition, new InvalidBranch("Invalid branch target"));
}
} }
ILInstruction DecodeUnconditionalBranch(bool shortForm, bool isLeave = false) ILInstruction DecodeUnconditionalBranch(bool shortForm, bool isLeave = false)
{ {
int target = DecodeBranchTarget(shortForm); int? target = DecodeBranchTarget(shortForm);
if (isLeave) { if (isLeave) {
currentStack = currentStack.Clear(); currentStack = currentStack.Clear();
} }
MarkBranchTarget(target); if (target != null) {
return new Branch(target); MarkBranchTarget(target.Value);
return new Branch(target.Value);
} else {
return new InvalidBranch("Invalid branch target");
}
} }
void MarkBranchTarget(int targetILOffset) void MarkBranchTarget(int targetILOffset)
@ -1421,9 +1433,13 @@ namespace ICSharpCode.Decompiler.IL
for (int i = 0; i < labels.Length; i++) { for (int i = 0; i < labels.Length; i++) {
var section = new SwitchSection(); var section = new SwitchSection();
section.Labels = new LongSet(i); section.Labels = new LongSet(i);
int target = labels[i].Offset; // baseOffset + reader.ReadInt32(); int? target = labels[i]?.Offset; // baseOffset + reader.ReadInt32();
MarkBranchTarget(target); if (target != null) {
section.Body = new Branch(target); MarkBranchTarget(target.Value);
section.Body = new Branch(target.Value);
} else {
section.Body = new InvalidBranch("Invalid branch target");
}
instr.Sections.Add(section); instr.Sections.Add(section);
} }
var defaultSection = new SwitchSection(); var defaultSection = new SwitchSection();

Loading…
Cancel
Save