protected override void CheckMethod(MethodDefinition method, bool abstractWarning) { if ((method == null) || !method.HasBody) { return; } OpCodeBitmask bitmask = OpCodeEngine.GetBitmask(method); // method must have a CALL[VIRT] and either STFLD or STELEM_REF if (!bitmask.Intersect(OpCodeBitmask.Calls) || !bitmask.Intersect(StoreFieldBitmask)) { return; } foreach (Instruction ins in method.Body.Instructions) { MethodReference mr = (ins.Operand as MethodReference); if (mr == null || mr.DeclaringType.IsNative()) { continue; } FieldDefinition field = null; Instruction next = ins.Next; if (next.Is(Code.Stfld)) { field = next.Operand as FieldDefinition; } else if (next.Is(Code.Stobj) || next.Is(Code.Stind_I)) { Instruction origin = next.TraceBack(method); if (origin.Is(Code.Ldelema)) { origin = origin.TraceBack(method); if (origin != null) { field = origin.Operand as FieldDefinition; } } } if (field != null && FieldCandidates.Contains(field)) { Runner.Report(field, Severity.High, Confidence.High, abstractWarning ? AbstractTypeMessage : TypeMessage); } } }
protected override void CheckMethod(MethodDefinition method, bool abstractWarning) { if ((method == null) || !method.HasBody) { return; } OpCodeBitmask bitmask = OpCodeEngine.GetBitmask(method); // method must have a NEWOBJ and either STFLD or STELEM_REF if (!bitmask.Get(Code.Newobj) || !bitmask.Intersect(StoreFieldBitmask)) { return; } foreach (Instruction ins in method.Body.Instructions) { if (!ins.Is(Code.Newobj)) { continue; } FieldDefinition field = null; Instruction next = ins.Next; if (next.Is(Code.Stfld)) { field = next.Operand as FieldDefinition; } else if (next.Is(Code.Stelem_Ref)) { Instruction origin = next.TraceBack(method); if (origin != null) { field = origin.Operand as FieldDefinition; } } if (field != null && FieldCandidates.Contains(field)) { Runner.Report(field, Severity.High, Confidence.High, abstractWarning ? AbstractTypeMessage : TypeMessage); } } }