0

I want to disallow calls to a specific method (MessageBox.Show) via a custom FxCop rule. I know the mechanics of how to get an FxCop rule custom-implemented (the XML file, inheriting from BaseIntrospectionRule, etc.) My question here is what I put in the "Check" method.

Below is the initial draft I have based on poking around a lot on the web, but I'm very puzzled as to what I would actually populate in the two fields marked with ????? below.

I'm not sure even this solution, as it exists, would work. What is the fool-proof to make sure I'm doing what I want -- which is catching all calls to MessageBox.Show?

public override ProblemCollection Check(Member member)
{
    Method method = member as Method;
    if (method == null)
    {
        return null;
    }
    MetadataCollection<Instruction>.Enumerator enumerator = method.Instructions.GetEnumerator();
    while (enumerator.MoveNext())
    {
        Instruction current = enumerator.Current;
        switch (current.OpCode)
        {
            case OpCode.Call:
            case OpCode.Callvirt:
            {
                Method method3 = current.Value as Method;
                if (method3 == **?????**)
                {
                    Problem item = new Problem(base.GetResolution(**?????**), current);
                    base.Problems.Add(item);
                }
                break;
            }
        }
    }
    return base.Problems;
}
  • The Instructions are 'the old way' of writing FxCop rules. It's easier to use the Visit methods instead. For a custom rule written by me that looks up calls to string.ToString (among others), see: https://fxcopcontrib.codeplex.com/SourceControl/changeset/view/7476#37972 – jessehouwing May 03 '12 at 20:44
  • The best tutorial on custom rules can be found here: http://www.binarycoder.net/fxcop/index.html – jessehouwing May 03 '12 at 20:48

2 Answers2

1

You might want to take a look at how the built-in SpecifyMessageBoxOptions rule is built using a decompiler like Reflector. There are other possible approaches, but name comparison is usually fine unless you have reason to believe that it will cause excessive false positives.

Nicole Calinoiu
  • 20,843
  • 2
  • 44
  • 49
  • I found nice examples in 'C:\Program Files (x86)\Microsoft Visual Studio 11.0\Team Tools\Static Analysis Tools\FxCop\Rules\' – Maslow Sep 21 '12 at 19:38
1

How about something like this?

   public override ProblemCollection Check(Member member)
    {
        Method method = member as Method;
        if (method != null) 
        {
            this.Visit(method.Body);
        }
        return this.Problems;
    }

    public override void VisitMethodCall(MethodCall call)
    {
        base.VisitMethodCall(call);
        Method targetMethod = (Method)((MemberBinding)call.Callee).BoundMember;
        if (targetMethod.Name.Name.Contains("MessageBox.Show"))
           this.Problems.Add(new Problem(this.GetResolution(), call));
    }
Mark
  • 3,177
  • 4
  • 26
  • 37