开发者

How can I get the value of a parameter passed to a method in a custom rule in FxCop?

Due to certain reasons, in our ASP.NET web application, it is not recommended to use Response.Redirect("something", True). It should be used with False for the endResponse parameter. We want to enforce this with a custom FxCop rule. I've managed to find the usages of Response.Redirect, but now I want to find the value of the endResponse argument. How can I do this?

We're using the following code:

public override ProblemCollection Check(Member member)
{
    var method = member as Method;
    if (method != null)
    {
        foreach (var instruction in method.Instructions)
        {
            switch (instruction.OpCode)
            {
                case OpCode.Call:
                case OpCode.Callvirt:
                case OpCode.Newobj:
                    var call = (Method) instruction.Value;
                    if (call == null)
                    {
                        break;
                    }
                    if (call.Name.Name != "Redirect")
                    {
                        break;
                    }
                    if (call.Parameters.Count == 1)
                    {
                        //Redirect(url)
                        var resolution = GetResolution();
                        var problem = new Problem(resolution);
                        Problems.Add(problem);
                    }
                    if (call.Parameters.Count == 2)
                    {
                        VisitStatements(c开发者_StackOverflow社区all.Body.Statements);
                    }
                    break;
                default:
                    break;
            }
        }
    }

    return Problems;
}

public override void VisitExpression(Expression expression)
{
    var methodCall = expression as MethodCall;
    if (methodCall == null)
    {
        return;
    }

    foreach (var operand in methodCall.Operands)
    {
        if (operand.Type.Name.Name == "Int16" || operand.Type.Name.Name == "Int32" || operand.Type.Name.Name == "Int64")
        {
            var literal = operand as Literal;
            if (literal != null && literal.Value is int)
            {
                var literalValue = (int)literal.Value;
                if (literalValue == 1)
                {
                    var resolution = GetResolution();
                    var problem = new Problem(resolution);
                    Problems.Add(problem);
                }
            }
        }
    }
}

I've used Introspector and thought the endResponse parameter was an integer behind the scenes, but I'm not so sure anymore. Anyway, there don't seem to be any booleans in the methodCall.Operands.

Has anyone ever had a similar situation, where you need to check the actual value of a parameter that's passed to a method?


While the parameter type is actually a System.Boolean, the FxCop IL parser is treating it as an integer. Here's a simplified version of the rule that should work (assuming you want non-literal endResponse values to trigger a rule violation):

    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.DeclaringType.FullName.Equals("System.Web.HttpResponse", StringComparison.Ordinal) &&
            targetMethod.Name.Name.Equals("Redirect", StringComparison.Ordinal))
        {
            bool callIsAcceptable = false;

            if (targetMethod.Parameters.Count == 2)
            {
                Expression endResponseOperand = call.Operands[1];
                if (endResponseOperand.NodeType == NodeType.Literal)
                {
                    if ((int)((Literal)endResponseOperand).Value == 1)
                    {
                        callIsAcceptable = true;
                    }
                }
            }

            if (!callIsAcceptable)
            {
                this.Problems.Add(new Problem(this.GetResolution(), call));
            }
        }
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜