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));
}
}
}
精彩评论