[Fb-contrib-commit] SF.net SVN: fb-contrib:[1771] trunk/fb-contrib
Brought to you by:
dbrosius
From: <dbr...@us...> - 2014-04-13 01:38:48
|
Revision: 1771 http://sourceforge.net/p/fb-contrib/code/1771 Author: dbrosius Date: 2014-04-13 01:38:42 +0000 (Sun, 13 Apr 2014) Log Message: ----------- sync from github Modified Paths: -------------- trunk/fb-contrib/build.xml trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/htdocs/index.shtml trunk/fb-contrib/pom.xml trunk/fb-contrib/samples/LSC_Sample.java trunk/fb-contrib/samples/OCP_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/collect/CollectMethodsReturningImmutableCollections.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ArrayIndexOutOfBounds.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BackportReusePublicIdentifiers.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BogusExceptionDeclaration.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CloneUsability.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/DeletingWhileIterating.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FinalParameters.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LiteralStringComparison.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LoggerOddities.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ModifyingUnmodifiableCollection.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousGetterSetterUse.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnboundMethodTemplateParameter.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnusedParameter.java Removed Paths: ------------- trunk/fb-contrib/lib/ Modified: trunk/fb-contrib/build.xml =================================================================== --- trunk/fb-contrib/build.xml 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/build.xml 2014-04-13 01:38:42 UTC (rev 1771) @@ -18,7 +18,7 @@ <property name="javac.deprecation" value="on" /> <property name="javac.debug" value="on" /> - <property name="fb-contrib.version" value="5.2.0" /> + <property name="fb-contrib.version" value="5.3.0" /> <property name="sonatype.dir" value="${user.home}/.fb-contrib-${fb-contrib.version}-sonatype" /> @@ -73,11 +73,6 @@ <pathelement location="${lib.dir}/slf4j-api-${slf4j-api.version}.jar" /> <pathelement location="${lib.dir}/guava-${guava.version}.jar" /> </path> - <mkdir dir="${classes.dir}/com" /> - <mkdir dir="${classes.dir}/com/mebigfatguy" /> - <mkdir dir="${classes.dir}/com/mebigfatguy/fbcontrib" /> - <mkdir dir="${classes.dir}/com/mebigfatguy/fbcontrib/detect" /> - <echo message="*.class" file="${classes.dir}/com/mebigfatguy/fbcontrib/detect/.cvsignore" /> </target> <target name="validate_xml" depends="-init" description="validates the xml files"> @@ -95,7 +90,7 @@ </target> <target name="compile_samples" depends="-init" description="compiles sample problem files"> - <javac srcdir="${samples.dir}" destdir="${samples.dir}" source="1.5" target="1.5" deprecation="${javac.deprecation}" debug="${javac.debug}" includeantruntime="false"> + <javac srcdir="${samples.dir}" destdir="${samples.dir}" source="1.7" target="1.7" deprecation="${javac.deprecation}" debug="${javac.debug}" includeantruntime="false"> <classpath refid="fb-contrib.classpath" /> <classpath refid="fb-contrib.samples.classpath" /> </javac> @@ -135,6 +130,7 @@ <attribute name="Require-Bundle" value="edu.umd.cs.findbugs.plugin.eclipse" /> <attribute name="Bundle-ActivationPolicy" value="lazy" /> <attribute name="Export-Package" value="com.mebigfatguy.fbcontrib.collect, com.mebigfatguy.fbcontrib.detect, com.mebigfatguy.fbcontrib.debug" /> + <attribute name="Import-Package" value="edu.umd.cs.findbugs, edu.umd.cs.findbugs.ba, edu.umd.cs.findbugs.bceledu.umd.cs.findbugs.visitclass, org.apache.bcel, org.apache.bcel.classfile, org.apache.bcel.generic" /> </manifest> </jar> </target> @@ -150,8 +146,9 @@ <include name="**/*.xml" /> <include name="**/*.xsd" /> <include name="**/*.license" /> - <include name="**/*.txt" /> - <include name="lib/*.jar" /> + <include name="**/*.txt" /> + <include name="**/*.md" /> + <include name="**/*.xls" /> </fileset> </zip> </target> @@ -159,7 +156,7 @@ <target name="javadoc" depends="-init" description="build the javadoc for the project"> <javadoc packagenames="com.mebigfatguy.*" sourcepath="${src.dir}" classpathref="fb-contrib.classpath" destdir="${javadoc.dir}" windowtitle="fb-contrib api"> <doctitle><![CDATA[<h1>fb-contrib javadoc</h1>]]></doctitle> - <bottom><![CDATA[<i>Copyright © 2005-2012 MeBigFatGuy.com. All Rights Reserved.</i>]]></bottom> + <bottom><![CDATA[<i>Copyright © 2005-2014 MeBigFatGuy.com. All Rights Reserved.</i>]]></bottom> </javadoc> </target> Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/etc/findbugs.xml 2014-04-13 01:38:42 UTC (rev 1771) @@ -20,7 +20,7 @@ <!-- Detectors --> -<!-- COMMENT OUT FOR RELEASE +<!-- COMMENT OUT FOR RELEASE --> <Detector class="com.mebigfatguy.fbcontrib.debug.OCSDebugger" speed="fast"/> @@ -34,7 +34,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.BloatedAssignmentScope" speed="fast" reports="BAS_BLOATED_ASSIGNMENT_SCOPE" hidden="true" /> - COMMENT OUT FOR RELEASE --> +<!-- COMMENT OUT FOR RELEASE --> <Detector class="com.mebigfatguy.fbcontrib.collect.CollectStatistics" speed="fast" reports="" hidden="true" /> @@ -265,12 +265,12 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.ModifyingUnmodifiableCollection" speed="fast" reports="MUC_MODIFYING_UNMODIFIABLE_COLLECTION"/> - <!-- COMMENT OUT FOR POINT RELEASE + <!-- COMMENT OUT FOR POINT RELEASE --> <Detector class="com.mebigfatguy.fbcontrib.detect.PresizeCollections" speed="fast" reports="PSC_PRESIZE_COLLECTIONS" /> <Detector class="com.mebigfatguy.fbcontrib.detect.ArrayIndexOutOfBounds" speed="fast" reports="AIOB_ARRAY_INDEX_OUT_OF_BOUNDS,AIOB_ARRAY_STORE_TO_NULL_REFERENCE" /> - COMMENT OUT FOR POINT RELEASE --> + <!-- COMMENT OUT FOR POINT RELEASE --> <!-- BugPattern --> Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/etc/messages.xml 2014-04-13 01:38:42 UTC (rev 1771) @@ -1545,9 +1545,19 @@ <LongDescription>Method {1} makes literal string comparisons passing the literal as an argument</LongDescription> <Details> <![CDATA[ - <p>This method calls the equals or compareTo methods on a String variable passing in a String literal. - A NullPointerException may occur if the string variable is null. If instead the method was called on - the string literal, and the variable was passed as an argument, this exception could never happen.</p> + <p>This line is in the form of <br/> + <code>String str = ...<br/> + str.equals("someOtherString");<br/> + //or</br> + str.compareTo("someOtherString");</code></p> + <p>A <code>NullPointerException</code> may occur if the String variable <code>str</code> is <code>null</code>. If instead the code was restructured to<br/> + <code>String str = ...<br/> + "someOtherString".equals(str);<br/> + //or</br> + "someOtherString".compareTo(str);</code><br/> + that is, call <code>equals()</code> or <code>compareTo()</code> on the string literal, passing the + variable as an argument, this exception could never happen as both <code>equals()</code> and + <code>compareTo()</code> check for <code>null</code>.</p> ]]> </Details> </BugPattern> @@ -3888,8 +3898,8 @@ <Details> <![CDATA[ <p>This class defines a field or local collection variable with a name that contains a different type - of collection in its name. This is confusing to the reader, and likely caused by a previous refactor of - type, without changing the name.</p> + of collection in its name. An example woutd be a Set<User> called userList. This is confusing to the reader, + and likely caused by a previous refactor of type, without changing the name.</p> ]]> </Details> </BugPattern> Modified: trunk/fb-contrib/htdocs/index.shtml =================================================================== --- trunk/fb-contrib/htdocs/index.shtml 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/htdocs/index.shtml 2014-04-13 01:38:42 UTC (rev 1771) @@ -123,7 +123,7 @@ </li> <li><b>[MUC] Modifying Unmodifiable Collection</b><br/> Looks for code that attempts to modify a collection that is or may be - defined as immutable. or instance, being returned from Arrays.asList(). Doing so will cause exceptions at runtime. + defined as immutable. for instance, being returned from Arrays.asList(). Doing so will cause exceptions at runtime. </li> </ul> </div> Modified: trunk/fb-contrib/pom.xml =================================================================== --- trunk/fb-contrib/pom.xml 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/pom.xml 2014-04-13 01:38:42 UTC (rev 1771) @@ -8,7 +8,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>com.mebigfatguy.fb-contrib</groupId> <artifactId>fb-contrib</artifactId> - <version>5.2.0</version> + <version>5.3.0</version> <parent> <groupId>org.sonatype.oss</groupId> @@ -56,6 +56,9 @@ <contributor> <name>Philipp Wiesemann</name> </contributor> + <contributor> + <name>Kevin Lubick</name> + </contributor> </contributors> <licenses> Modified: trunk/fb-contrib/samples/LSC_Sample.java =================================================================== --- trunk/fb-contrib/samples/LSC_Sample.java 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/samples/LSC_Sample.java 2014-04-13 01:38:42 UTC (rev 1771) @@ -1,22 +1,173 @@ + public class LSC_Sample { + public static final String CONSTANT_VAL_STRING = "GoodBye"; + private static final String CONSTANT_VAL_STRING2 = "GoodBye2"; + + enum Planets { + EARTH,MARS,VENUS, JUPITER; + } + public boolean test1(String s) { + //tag return s.equals("Hello"); } public boolean test2(String s) { + //no tag return "Hello".equals(s); } public boolean test3(String s1, String s2) { + //no tag return s1.equals(s2); } public int test4(String s) { + //tag return s.compareTo("Hello"); } public int test5(String s) { + //no tag return "Hello".compareTo(s); } + + public int test6(String s) { + //tag + return s.compareTo(CONSTANT_VAL_STRING); + } + + public int test7(String s) { + //no tag + return CONSTANT_VAL_STRING.compareTo(s); + } + + public int test8(String s) { + //tag + return s.compareTo(CONSTANT_VAL_STRING2); + } + + public int test9(String s) { + //no tag + return CONSTANT_VAL_STRING2.compareTo(s); + } + + public static int test10(String s) { + switch (s) { + case "Hello": + return 1; + case CONSTANT_VAL_STRING: + return 2; + + } + + switch (s) { //two in a row to check the correct switch offsets + case "Hello2": + return 1; + case CONSTANT_VAL_STRING+"2": + return 2; + default: + return 3; + } + } + + + public static int test11(String s, String s2) { + //no tag + switch (s) { + case "Switch1": + return 1; + case "switch2": + return 2; + case "switch3": + //tag + if (s2.equalsIgnoreCase("Foo6")) { + return 5; + } + } + + //tag + if (s.equals("Foo7")) { + return 3; + } + System.out.println(s); + return 4; + + } + + public static int test12(int n, String s2) { + switch (n) { //this is probably a table lookup + case 1: + return 1; + case 2: + return 2; + case 3: + case 4: + //tag + if (s2.equalsIgnoreCase("Foo6")) { + return 5; + } + } + + //tag + if (s2.equals("Foo7")) { + return 3; + } + System.out.println(s2); + return 4; + + } + + public static int test13(Planets p, String s2) { + switch (p) { + case EARTH: + return 1; + case MARS: + return 2; + case JUPITER: + //tag + if (s2.equalsIgnoreCase("Foo6")) { + return 5; + } + default: + break; + } + + //tag + if (s2.equals("Foo7")) { + return 3; + } + System.out.println(s2); + return 4; + + } + + /* + * Tried really hard to get a false negative, by manipulating this switch to look like a + * string switch. Couldn't make it happen. + */ + public static int test14(String s2) { + switch (s2.hashCode()) { + case 1: + return 1; + case 2: + return 2; + case 3: + case 99: //forces this to also be a lookup table, like the strings + //tag + if (s2.equalsIgnoreCase("Foo6")) { + return 5; + } + } + + //tag + if (s2.equals("Foo7")) { + return 3; + } + System.out.println(s2); + return 4; + + } + } \ No newline at end of file Modified: trunk/fb-contrib/samples/OCP_Sample.java =================================================================== --- trunk/fb-contrib/samples/OCP_Sample.java 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/samples/OCP_Sample.java 2014-04-13 01:38:42 UTC (rev 1771) @@ -6,6 +6,8 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; +import java.sql.Date; +import java.util.Comparator; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; @@ -98,3 +100,12 @@ public void usesOCP(LinkedList<String> ll) { } } + +class fpOverride { + public static final Comparator<Date> COMPARATOR = new Comparator<Date>() { + + public int compare(Date o1, Date o2) { + return o1.getYear() - o2.getYear(); + } + }; +} \ No newline at end of file Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/collect/CollectMethodsReturningImmutableCollections.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/collect/CollectMethodsReturningImmutableCollections.java 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/collect/CollectMethodsReturningImmutableCollections.java 2014-04-13 01:38:42 UTC (rev 1771) @@ -69,7 +69,7 @@ /** * constructs a CMRIC detector given the reporter to report bugs on * - * @param bugReporter + * @param reporter * the sync of bug reports */ public CollectMethodsReturningImmutableCollections(BugReporter reporter) { Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ArrayIndexOutOfBounds.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ArrayIndexOutOfBounds.java 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ArrayIndexOutOfBounds.java 2014-04-13 01:38:42 UTC (rev 1771) @@ -19,6 +19,9 @@ package com.mebigfatguy.fbcontrib.detect; import java.util.BitSet; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; import org.apache.bcel.Constants; import org.apache.bcel.classfile.Code; @@ -43,6 +46,7 @@ private OpcodeStack stack; private BitSet initializedRegs; private BitSet modifyRegs; + private Map<Integer, Integer> nullStoreToLocation; /** * constructs an AIOB detector given the reporter to report bugs on @@ -58,10 +62,13 @@ stack = new OpcodeStack(); initializedRegs = new BitSet(); modifyRegs = new BitSet(); + nullStoreToLocation = new HashMap<Integer, Integer>(); super.visitClassContext(classContext); } finally { stack = null; initializedRegs = null; + modifyRegs = null; + nullStoreToLocation = null; } } @@ -77,10 +84,15 @@ initializedRegs.set(arg); arg += ("J".equals(argSig) || "D".equals(argSig)) ? 2 : 1; } + nullStoreToLocation.clear(); super.visitCode(obj); - initializedRegs.clear(); - modifyRegs.clear(); + for (Integer pc : nullStoreToLocation.values()) { + bugReporter.reportBug(new BugInstance(this, "AIOB_ARRAY_STORE_TO_NULL_REFERENCE", HIGH_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this, pc.intValue())); + } } public void sawOpcode(int seen) { @@ -189,10 +201,7 @@ int reg = arrayItem.getRegisterNumber(); if ((reg >= 0) && !initializedRegs.get(reg)) { - bugReporter.reportBug(new BugInstance(this, "AIOB_ARRAY_STORE_TO_NULL_REFERENCE", HIGH_PRIORITY) - .addClass(this) - .addMethod(this) - .addSourceLine(this)); + nullStoreToLocation.put(Integer.valueOf(reg), getPC()); } } } @@ -237,8 +246,33 @@ initializedRegs.set(getRegisterOperand()); } break; + + case IFEQ: + case IFNE: + case IFLT: + case IFGE: + case IFGT: + case IFLE: + case IF_ICMPEQ: + case IF_ICMPNE: + case IF_ICMPLT: + case IF_ICMPGE: + case IF_ICMPGT: + case IF_ICMPLE: + case IF_ACMPEQ: + case IF_ACMPNE: + case GOTO: + case GOTO_W: + int branchTarget = getBranchTarget(); + Iterator<Map.Entry<Integer, Integer>> it = nullStoreToLocation.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry<Integer, Integer> entry = it.next(); + int pc = entry.getValue().intValue(); + if ((branchTarget < pc) && (initializedRegs.get(entry.getKey().intValue()))) + it.remove(); + } } - + } finally { stack.sawOpcode(this, seen); if (sizeSet) { Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BackportReusePublicIdentifiers.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BackportReusePublicIdentifiers.java 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BackportReusePublicIdentifiers.java 2014-04-13 01:38:42 UTC (rev 1771) @@ -55,21 +55,21 @@ stack.precomputation(this); switch (seen) { - case INVOKESTATIC: { - String className = getClassConstantOperand(); - if (className.startsWith("edu/emory/mathcs/backport/")) { - reportBug(); + case INVOKESTATIC: { + String className = getClassConstantOperand(); + if (className.startsWith("edu/emory/mathcs/backport/")) { + reportBug(); + } } - } break; - case INVOKESPECIAL: { - String className = getClassConstantOperand(); - String methodName = getNameConstantOperand(); - if (className.startsWith("edu/emory/mathcs/backport/") - && methodName.equals("<init>")) { - reportBug(); + + case INVOKESPECIAL: { + String className = getClassConstantOperand(); + String methodName = getNameConstantOperand(); + if (className.startsWith("edu/emory/mathcs/backport/") && "<init>".equals(methodName)) { + reportBug(); + } } - } break; } } Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java 2014-04-13 01:38:42 UTC (rev 1771) @@ -26,6 +26,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.apache.bcel.classfile.Code; import org.apache.bcel.classfile.CodeException; @@ -52,6 +54,7 @@ public class BloatedAssignmentScope extends BytecodeScanningDetector { private static final Set<String> dangerousAssignmentClassSources = new HashSet<String>(7); private static final Set<String> dangerousAssignmentMethodSources = new HashSet<String>(4); + private static final Set<Pattern> dangerousAssignmentMethodPatterns = new HashSet<Pattern>(1); static { dangerousAssignmentClassSources.add("java/io/BufferedInputStream"); @@ -61,12 +64,17 @@ dangerousAssignmentClassSources.add("java/io/BufferedReader"); dangerousAssignmentClassSources.add("java/io/FileReader"); dangerousAssignmentClassSources.add("java/io/Reader"); + dangerousAssignmentClassSources.add("javax/nio/channels/Channel"); + dangerousAssignmentClassSources.add("io/netty/channel/Channel"); + dangerousAssignmentMethodSources.add("java/lang/System.currentTimeMillis()J"); dangerousAssignmentMethodSources.add("java/lang/System.nanoTime()J"); dangerousAssignmentMethodSources.add("java/util/Calendar.get(I)I"); dangerousAssignmentMethodSources.add("java/util/GregorianCalendar.get(I)I"); dangerousAssignmentMethodSources.add("java/util/Iterator.next()Ljava/lang/Object;"); dangerousAssignmentMethodSources.add("java/util/regex/Matcher.start()I"); + + dangerousAssignmentMethodPatterns.add(Pattern.compile(".*serial.*", Pattern.CASE_INSENSITIVE)); } BugReporter bugReporter; @@ -932,7 +940,19 @@ } String key = clsName + "." + getNameConstantOperand() + getSigConstantOperand(); - return dangerousAssignmentMethodSources.contains(key); + if (dangerousAssignmentMethodSources.contains(key)) { + return true; + } + + for (Pattern p : dangerousAssignmentMethodPatterns) { + Matcher m = p.matcher(key); + if (m.matches()) { + return true; + } + } + + + return false; } static class UserObject { Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BogusExceptionDeclaration.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BogusExceptionDeclaration.java 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BogusExceptionDeclaration.java 2014-04-13 01:38:42 UTC (rev 1771) @@ -68,10 +68,10 @@ /** - * constructs a BED detector given the reporter to report bugs on + * overrides the visitor to create the opcode stack * - * @param bugReporter - * the sync of bug reports + * @param classContext the context object of the currently parsed class + * */ @Override public void visitClassContext(ClassContext classContext) { Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CloneUsability.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CloneUsability.java 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CloneUsability.java 2014-04-13 01:38:42 UTC (rev 1771) @@ -95,7 +95,7 @@ public void visitCode(Code obj) { try { Method m = getMethod(); - if (m.isPublic() && !m.isSynthetic() && m.getName().equals("clone") && (m.getArgumentTypes().length == 0)) { + if (m.isPublic() && !m.isSynthetic() && "clone".equals(m.getName()) && (m.getArgumentTypes().length == 0)) { String returnClsName = m.getReturnType().getSignature(); returnClsName = returnClsName.substring(1, returnClsName.length() - 1).replaceAll("/", "."); Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/DeletingWhileIterating.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/DeletingWhileIterating.java 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/DeletingWhileIterating.java 2014-04-13 01:38:42 UTC (rev 1771) @@ -192,7 +192,7 @@ if (loop != null) { int pc = getPC(); if (loop.hasPC(pc)) { - boolean breakFollows = breakFollows(loop, !Type.getReturnType(signature).getSignature().equals("V")); + boolean breakFollows = breakFollows(loop, !"V".equals(Type.getReturnType(signature).getSignature())); if (!breakFollows) { bugReporter.reportBug(new BugInstance(this, "DWI_DELETING_WHILE_ITERATING", NORMAL_PRIORITY) @@ -218,7 +218,7 @@ if (loop != null) { int pc = getPC(); if (loop.hasPC(pc)) { - boolean breakFollows = breakFollows(loop, !Type.getReturnType(signature).getSignature().equals("V")); + boolean breakFollows = breakFollows(loop, !"V".equals(Type.getReturnType(signature).getSignature())); if (!breakFollows) { bugReporter.reportBug(new BugInstance(this, "DWI_MODIFYING_WHILE_ITERATING", NORMAL_PRIORITY) .addClass(this) @@ -497,12 +497,12 @@ static class GroupPair { private Set<Comparable<?>> groupMembers; - private String collectionClass; + private String colClass; public GroupPair(Comparable<?> member, String cls) { groupMembers = new HashSet<Comparable<?>>(); groupMembers.add(member); - collectionClass = cls; + colClass = cls; } public void addMember(Comparable<?> member) { @@ -518,12 +518,12 @@ } public boolean isStandardCollection() { - return (collectionClass == null) || !collectionClass.contains("/concurrent/"); + return (colClass == null) || !colClass.contains("/concurrent/"); } @Override public String toString() { - return groupMembers + ((collectionClass == null) ? "" : collectionClass); + return groupMembers + ((colClass == null) ? "" : colClass); } } } Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FinalParameters.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FinalParameters.java 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FinalParameters.java 2014-04-13 01:38:42 UTC (rev 1771) @@ -99,7 +99,7 @@ firstLocalReg = isStatic ? 0 : 1; for (Type p : parms) { String parmSig = p.getSignature(); - firstLocalReg += (parmSig.equals("J") || parmSig.equals("D")) ? 2 : 1; + firstLocalReg += ("J".equals(parmSig) || "D".equals(parmSig)) ? 2 : 1; } sourceLines = getSourceLines(obj); Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LiteralStringComparison.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LiteralStringComparison.java 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LiteralStringComparison.java 2014-04-13 01:38:42 UTC (rev 1771) @@ -19,6 +19,8 @@ package com.mebigfatguy.fbcontrib.detect; import java.util.BitSet; +import java.util.HashSet; +import java.util.Set; import org.apache.bcel.Constants; import org.apache.bcel.classfile.Code; @@ -34,15 +36,30 @@ * looks for methods that compare strings against literal strings, where the literal string * is passed as the parameter. If the .equals or .compareTo is called on the literal itself, passing * the variable as the parameter, you avoid the possibility of a NullPointerException. + * + * Updated for 1.7 to not throw false positives for string-based switch statements (which are susceptible to + * NPEs). String-based switch generate String.equals(Constant) bytecodes, and thus, must be accounted for */ public class LiteralStringComparison extends BytecodeScanningDetector { + //offsets to detect for a string switch + private static final int HASH_CODE_PC_OFFSET = 3; + private static final int DUP_PC_OFFSET = 5; + private static final int STRING_SWITCH_OFFSET = 3; + + private BugReporter bugReporter; private OpcodeStack stack; - + + private Set<Integer> stringBasedSwitchFalsePositives; + + int lastDupSeen; + int lastStringHashCodeSeen; + + /** - * constructs a LSC detector given the reporter to report bugs on - * @param bugReporter the sync of bug reports + * constructs a LSC detector given the reporter to report bugs on + * @param bugReporter the sync of bug reports */ public LiteralStringComparison(final BugReporter bugReporter) { this.bugReporter = bugReporter; @@ -57,12 +74,16 @@ public void visitClassContext(ClassContext classContext) { try { stack = new OpcodeStack(); + + stringBasedSwitchFalsePositives = new HashSet<Integer>(); super.visitClassContext(classContext); } finally { stack = null; + stringBasedSwitchFalsePositives.clear(); + stringBasedSwitchFalsePositives = null; } } - + /** * looks for methods that contain a LDC or LDC_W opcodes * @@ -73,7 +94,7 @@ BitSet bytecodeSet = getClassContext().getBytecodeSet(method); return (bytecodeSet != null) && (bytecodeSet.get(Constants.LDC) || bytecodeSet.get(Constants.LDC_W)); } - + /** * overrides the visitor to reset the opcode stack * @@ -83,10 +104,14 @@ public void visitCode(final Code obj) { if (prescreen(getMethod())) { stack.resetForMethodEntry(this); + lastDupSeen=-10; + lastStringHashCodeSeen=-10; + stringBasedSwitchFalsePositives.clear(); + super.visitCode(obj); } } - + /** * looks for strings comparisons where the stack object is a literal * @@ -95,31 +120,67 @@ @Override public void sawOpcode(final int seen) { try { - stack.precomputation(this); - + stack.precomputation(this); + if ((seen == INVOKEVIRTUAL) && "java/lang/String".equals(getClassConstantOperand())) { - String calledMethodName = getNameConstantOperand(); - String calledMethodSig = getSigConstantOperand(); - - if (("equals".equals(calledMethodName) && "(Ljava/lang/Object;)Z".equals(calledMethodSig)) - || ("compareTo".equals(calledMethodName) && "(Ljava/lang/String;)I".equals(calledMethodSig)) - || ("equalsIgnoreCase".equals(calledMethodName) && "(Ljava/lang/String;)Z".equals(calledMethodSig))) { - - if (stack.getStackDepth() > 0) { - OpcodeStack.Item itm = stack.getStackItem(0); - Object constant = itm.getConstant(); - if ((constant != null) && constant.getClass().equals(String.class)) { - bugReporter.reportBug( new BugInstance( this, "LSC_LITERAL_STRING_COMPARISON", LOW_PRIORITY) - .addClass(this) - .addMethod(this) - .addSourceLine(this)); - } - } - } + handleMethodOnString(); + } + else if (seen == DUP) { + lastDupSeen = getPC(); } + else if (seen == LOOKUPSWITCH) { + handleLookupSwitch(); + } } finally { stack.sawOpcode(this, seen); } } + + private void handleLookupSwitch() { + int pc = getPC(); + //This setup, with a dup 5 bytes before and a hashcode call 3 bytes before is a near-sure-fire + //way to detect a string-based switch + if (pc-lastStringHashCodeSeen == HASH_CODE_PC_OFFSET && pc - lastDupSeen == DUP_PC_OFFSET) { + addFalsePositivesForStringSwitch(getSwitchOffsets(),pc); + } + } + + private void addFalsePositivesForStringSwitch(int[] switchOffsets, int pc) { + for (Integer i:switchOffsets) { + //string-based switches + stringBasedSwitchFalsePositives.add(pc + i.intValue() + STRING_SWITCH_OFFSET); + } + } + + private void handleMethodOnString() { + String calledMethodName = getNameConstantOperand(); + String calledMethodSig = getSigConstantOperand(); + + if (("equals".equals(calledMethodName) && "(Ljava/lang/Object;)Z".equals(calledMethodSig)) + || ("compareTo".equals(calledMethodName) && "(Ljava/lang/String;)I".equals(calledMethodSig)) + || ("equalsIgnoreCase".equals(calledMethodName) && "(Ljava/lang/String;)Z".equals(calledMethodSig))) { + + if (stack.getStackDepth() > 0) { + OpcodeStack.Item itm = stack.getStackItem(0); + Object constant = itm.getConstant(); + if ((constant != null) && constant.getClass().equals(String.class)) { + if (stringBasedSwitchFalsePositives.contains(getPC())) { + System.out.println("Ignoring false positive LSC"); + } + else { + bugReporter.reportBug( new BugInstance( this, "LSC_LITERAL_STRING_COMPARISON", HIGH_PRIORITY) //very confident + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + + } + } + } + else if ("hashCode".equals(calledMethodName)) { + lastStringHashCodeSeen = getPC(); + } + } + } Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LoggerOddities.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LoggerOddities.java 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LoggerOddities.java 2014-04-13 01:38:42 UTC (rev 1771) @@ -244,7 +244,7 @@ } } else if (((seen == INVOKEVIRTUAL) || (seen == INVOKEINTERFACE)) && (THROWABLE_CLASS != null)) { String mthName = getNameConstantOperand(); - if (mthName.equals("getMessage")) { + if ("getMessage".equals(mthName)) { String callingClsName = getClassConstantOperand(); JavaClass cls = Repository.lookupClass(callingClsName); if (cls.instanceOf(THROWABLE_CLASS)) { @@ -321,9 +321,9 @@ } } - } else if (mthName.equals("toString")) { + } else if ("toString".equals(mthName)) { String callingClsName = getClassConstantOperand(); - if ((callingClsName.equals("java/lang/StringBuilder") || callingClsName.equals("java/lang/StringBuffer"))) { + if (("java/lang/StringBuilder".equals(callingClsName) || "java/lang/StringBuffer".equals(callingClsName))) { seenMethodName = mthName; } } Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ModifyingUnmodifiableCollection.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ModifyingUnmodifiableCollection.java 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ModifyingUnmodifiableCollection.java 2014-04-13 01:38:42 UTC (rev 1771) @@ -63,7 +63,8 @@ /** * constructs a MUC detector given the reporter to report bugs on - * @param bugReporter the sync of bug reports + * + * @param reporter the sync of bug reports */ public ModifyingUnmodifiableCollection(BugReporter reporter) { bugReporter = reporter; @@ -71,7 +72,8 @@ /** * overrides the visitor to setup and tear down the opcode stack - * @parm context the context object of the currently parse java class + * + * @param context the context object of the currently parse java class */ @Override public void visitClassContext(ClassContext context) { Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2014-04-13 01:38:42 UTC (rev 1771) @@ -389,7 +389,7 @@ OpcodeStack.Item item = stack.getStackItem(0); String mName = (String) item.getUserValue(); if (mName != null) { - if (mName.equals("trim")) { + if ("trim".equals(mName)) { item.setUserValue(null); } else { Matcher m = APPEND_PATTERN.matcher(mName); Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousGetterSetterUse.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousGetterSetterUse.java 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousGetterSetterUse.java 2014-04-13 01:38:42 UTC (rev 1771) @@ -138,7 +138,7 @@ String sig = getSigConstantOperand(); if (sig.startsWith("()")) { propType = sig.substring("()".length()); - if (!propType.equals("V")) { + if (!"V".equals(propType)) { propName = getNameConstantOperand(); if (propName.startsWith("get")) { propName = propName.substring("get".length()); Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnboundMethodTemplateParameter.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnboundMethodTemplateParameter.java 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnboundMethodTemplateParameter.java 2014-04-13 01:38:42 UTC (rev 1771) @@ -70,7 +70,7 @@ public void visitMethod(Method obj) { Attribute[] attributes = obj.getAttributes(); for (Attribute a : attributes) { - if (a.getName().equals("Signature")) { + if ("Signature".equals(a.getName())) { TemplateSignature ts = parseSignatureAttribute((Signature) a); if (ts != null) { for (String templateParm : ts.templateParameters) { Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnusedParameter.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnusedParameter.java 2014-03-18 05:59:32 UTC (rev 1770) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnusedParameter.java 2014-04-13 01:38:42 UTC (rev 1771) @@ -135,8 +135,8 @@ .addClass(this) .addMethod(this) .addString("Parameter " + regToParm.get(reg) + ": " + parmName)); - reg = unusedParms.nextSetBit(reg+1); } + reg = unusedParms.nextSetBit(reg+1); } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |