[Fb-contrib-commit] SF.net SVN: fb-contrib:[1397] trunk/fb-contrib
Brought to you by:
dbrosius
From: <dbr...@us...> - 2009-12-19 23:45:12
|
Revision: 1397 http://fb-contrib.svn.sourceforge.net/fb-contrib/?rev=1397&view=rev Author: dbrosius Date: 2009-12-19 23:45:00 +0000 (Sat, 19 Dec 2009) Log Message: ----------- add support for IKNC for HttpSession.getAttribute/setAttribute Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InconsistentKeyNameCasing.java Added Paths: ----------- trunk/fb-contrib/javadoc/ Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2009-12-19 23:35:21 UTC (rev 1396) +++ trunk/fb-contrib/etc/findbugs.xml 2009-12-19 23:45:00 UTC (rev 1397) @@ -295,7 +295,7 @@ speed="fast" reports="ITU_INAPPROPRIATE_TOSTRING_USE" /> <Detector class="com.mebigfatguy.fbcontrib.detect.InconsistentKeyNameCasing" - speed="fast" reports="IKNC_INCONSISTENT_HTTP_PARAM_CASING" /> + speed="fast" reports="IKNC_INCONSISTENT_HTTP_ATTRIBUTE_CASING,IKNC_INCONSISTENT_HTTP_PARAM_CASING" /> <Detector class="com.mebigfatguy.fbcontrib.detect.OverzealousCasting" speed="fast" reports="OC_OVERZEALOUS_CASTING" /> @@ -550,6 +550,8 @@ category="CORRECTNESS" /> <BugPattern abbrev="ITU" type="ITU_INAPPROPRIATE_TOSTRING_USE" category="CORRECTNESS" /> + <BugPattern abbrev="IKNC" type="IKNC_INCONSISTENT_HTTP_ATTRIBUTE_CASING" + category="STYLE" experimental="true" /> <BugPattern abbrev="IKNC" type="IKNC_INCONSISTENT_HTTP_PARAM_CASING" category="STYLE" experimental="true" /> <BugPattern abbrev="OC" type="OC_OVERZEALOUS_CASTING" Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2009-12-19 23:35:21 UTC (rev 1396) +++ trunk/fb-contrib/etc/messages.xml 2009-12-19 23:45:00 UTC (rev 1397) @@ -1006,8 +1006,8 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.InconsistentKeyNameCasing"> <Details> <![CDATA[ - <p>looks for methods that use the same name with different casing to access objects in HttpRequest Parameters. - As these parameter names are case sensitive this will lead to confusion.</p> + <p>looks for methods that use the same name with different casing to access objects in HttpRequest parameters + and attributes. As these parameter names are case sensitive this will lead to confusion.</p> <p>It is a fast detector</p> ]]> </Details> @@ -2700,6 +2700,17 @@ </Details> </BugPattern> + <BugPattern type="IKNC_INCONSISTENT_HTTP_ATTRIBUTE_CASING"> + <ShortDescription>method uses the same HttpSession attribute name but with different casing</ShortDescription> + <LongDescription>method {1} uses the same HttpSession attribute name but with different casing</LongDescription> + <Details> + <![CDATA[ + <p>This method sets or gets an HttpSession attribute with a parmeter name that was used in other locations + but with a different casing. As HttpSession attribute are case sensitive, this will be very confusing. + ]]> + </Details> + </BugPattern> + <BugPattern type="IKNC_INCONSISTENT_HTTP_PARAM_CASING"> <ShortDescription>method uses the same HttpRequestRequest parameter name but with different casing</ShortDescription> <LongDescription>method {1} uses the same HttpRequestRequest parameter name but with different casing</LongDescription> Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InconsistentKeyNameCasing.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InconsistentKeyNameCasing.java 2009-12-19 23:35:21 UTC (rev 1396) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InconsistentKeyNameCasing.java 2009-12-19 23:45:00 UTC (rev 1397) @@ -19,6 +19,7 @@ package com.mebigfatguy.fbcontrib.detect; import java.util.ArrayList; +import java.util.EnumMap; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -26,6 +27,8 @@ import org.apache.bcel.classfile.Code; +import com.sun.org.apache.bcel.internal.generic.Type; + import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; import edu.umd.cs.findbugs.BytecodeScanningDetector; @@ -38,13 +41,34 @@ * name with different cases like 'id' and 'Id'. */ public class InconsistentKeyNameCasing extends BytecodeScanningDetector -{ +{ + private static final String HTTP_SESSION = "javax/servlet/http/HttpSession"; private static final String HTTP_SERVLET_REQUEST = "javax/servlet/http/HttpServletRequest"; + private static final String GET_ATTRIBUTE = "getAttribute"; + private static final String SET_ATTRIBUTE = "setAttribute"; private static final String GET_PARAMETER = "getParameter"; + private static final String GET_ATTRIBUTE_SIG = "(Ljava/lang/String;)Ljava/lang/Object;"; + private static final String SET_ATTRIBUTE_SIG = "(Ljava/lang/String;Ljava/lang/Object;)V"; private static final String GET_PARAMETER_SIG = "(Ljava/lang/String;)Ljava/lang/String;"; + + enum KeyType { + ATTRIBUTE("IKNC_INCONSISTENT_HTTP_ATTRIBUTE_CASING"), + PARAMETER("IKNC_INCONSISTENT_HTTP_PARAM_CASING"); + + private String key; + + KeyType(String descriptionKey) { + key = descriptionKey; + } + + public String getDescription() { + return key; + } + }; + BugReporter bugReporter; OpcodeStack stack; - Map<String, Map<String, List<SourceInfo>>> parmInfo = new HashMap<String, Map<String, List<SourceInfo>>>(); + Map<KeyType, Map<String, Map<String, List<SourceInfo>>>> parmInfo; /** * constructs a IKNC detector given the reporter to report bugs on @@ -52,6 +76,9 @@ */ public InconsistentKeyNameCasing(BugReporter reporter) { bugReporter = reporter; + parmInfo = new EnumMap<KeyType, Map<String, Map<String, List<SourceInfo>>>>(KeyType.class); + parmInfo.put(KeyType.ATTRIBUTE, new HashMap<String, Map<String, List<SourceInfo>>>()); + parmInfo.put(KeyType.PARAMETER, new HashMap<String, Map<String, List<SourceInfo>>>()); } /** @@ -87,36 +114,32 @@ public void sawOpcode(int seen) { try { if (seen == INVOKEINTERFACE) { - String clsName = getClassConstantOperand(); - if (HTTP_SERVLET_REQUEST.equals(clsName)) { - String methodName = getNameConstantOperand(); - if (GET_PARAMETER.equals(methodName)) { - String signature = getSigConstantOperand(); - if (GET_PARAMETER_SIG.equals(signature)) { - if (stack.getStackDepth() > 0) { - OpcodeStack.Item item = stack.getStackItem(0); - String parmName = (String)item.getConstant(); - if (parmName != null) - { - String upperParmName = parmName.toUpperCase(Locale.getDefault()); - Map<String, List<SourceInfo>> parmCaseInfo = parmInfo.get(upperParmName); - if (parmCaseInfo == null) { - parmCaseInfo = new HashMap<String, List<SourceInfo>>(); - parmInfo.put(upperParmName, parmCaseInfo); - } - - List<SourceInfo> annotations = parmCaseInfo.get(parmName); - if (annotations == null) { - annotations = new ArrayList<SourceInfo>(); - parmCaseInfo.put(parmName, annotations); - } - - annotations.add(new SourceInfo(getClassName(), getMethodName(), getMethodSig(), getMethod().isStatic(), SourceLineAnnotation.fromVisitedInstruction(getClassContext(), this, getPC()))); - } + KeyType type = isKeyAccessMethod(seen); + if (type != null) { + int numParms = Type.getArgumentTypes(getSigConstantOperand()).length; + if (stack.getStackDepth() >= numParms) { + OpcodeStack.Item item = stack.getStackItem(numParms - 1); + String parmName = (String)item.getConstant(); + if (parmName != null) + { + String upperParmName = parmName.toUpperCase(Locale.getDefault()); + Map<String, Map<String, List<SourceInfo>>> typeMap = parmInfo.get(KeyType.PARAMETER); + Map<String, List<SourceInfo>> parmCaseInfo = typeMap.get(upperParmName); + if (parmCaseInfo == null) { + parmCaseInfo = new HashMap<String, List<SourceInfo>>(); + typeMap.put(upperParmName, parmCaseInfo); } + + List<SourceInfo> annotations = parmCaseInfo.get(parmName); + if (annotations == null) { + annotations = new ArrayList<SourceInfo>(); + parmCaseInfo.put(parmName, annotations); + } + + annotations.add(new SourceInfo(getClassName(), getMethodName(), getMethodSig(), getMethod().isStatic(), SourceLineAnnotation.fromVisitedInstruction(getClassContext(), this, getPC()))); } } - } + } } } finally { stack.sawOpcode(this, seen); @@ -129,25 +152,53 @@ */ @Override public void report() { - for (Map<String, List<SourceInfo>> parmCaseInfo : parmInfo.values()) { - if (parmCaseInfo.size() > 1) { - BugInstance bi = new BugInstance(this, "IKNC_INCONSISTENT_HTTP_PARAM_CASING", NORMAL_PRIORITY); - - for (Map.Entry<String, List<SourceInfo>> sourceInfos :parmCaseInfo.entrySet()) { - for (SourceInfo sourceInfo : sourceInfos.getValue()) { - bi.addClass(sourceInfo.clsName); - bi.addMethod(sourceInfo.clsName, sourceInfo.methodName, sourceInfo.signature, sourceInfo.isStatic); - bi.addSourceLine(sourceInfo.srcLine); - bi.addString(sourceInfos.getKey()); - } - } - - bugReporter.reportBug(bi); - } - } + for (Map.Entry<KeyType, Map<String, Map<String, List<SourceInfo>>>> entry : parmInfo.entrySet()) { + KeyType type = entry.getKey(); + Map<String, Map<String, List<SourceInfo>>> typeMap = entry.getValue(); + + for (Map<String, List<SourceInfo>> parmCaseInfo : typeMap.values()) { + if (parmCaseInfo.size() > 1) { + BugInstance bi = new BugInstance(this, type.getDescription(), NORMAL_PRIORITY); + + for (Map.Entry<String, List<SourceInfo>> sourceInfos :parmCaseInfo.entrySet()) { + for (SourceInfo sourceInfo : sourceInfos.getValue()) { + bi.addClass(sourceInfo.clsName); + bi.addMethod(sourceInfo.clsName, sourceInfo.methodName, sourceInfo.signature, sourceInfo.isStatic); + bi.addSourceLine(sourceInfo.srcLine); + bi.addString(sourceInfos.getKey()); + } + } + + bugReporter.reportBug(bi); + } + } + } parmInfo.clear(); } + private KeyType isKeyAccessMethod(int seen) { + if (seen == INVOKEINTERFACE) { + String clsName = getClassConstantOperand(); + if (HTTP_SESSION.equals(clsName)) { + String methodName = getNameConstantOperand(); + if (GET_ATTRIBUTE.equals(methodName)) { + String signature = getSigConstantOperand(); + return (GET_ATTRIBUTE_SIG.equals(signature)) ? KeyType.ATTRIBUTE : null; + } else if (SET_ATTRIBUTE.equals(methodName)) { + String signature = getSigConstantOperand(); + return (SET_ATTRIBUTE_SIG.equals(signature)) ? KeyType.ATTRIBUTE : null; + } + } else if (HTTP_SERVLET_REQUEST.equals(clsName)) { + String methodName = getNameConstantOperand(); + if (GET_PARAMETER.equals(methodName)) { + String signature = getSigConstantOperand(); + return (GET_PARAMETER_SIG.equals(signature)) ? KeyType.PARAMETER : null; + } + } + } + + return null; + } /** * a holder for location information of a getParameter call */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |