[Fb-contrib-commit] SF.net SVN: fb-contrib:[1786] trunk/fb-contrib
Brought to you by:
dbrosius
From: <dbr...@us...> - 2015-12-12 17:34:00
|
Revision: 1786 http://sourceforge.net/p/fb-contrib/code/1786 Author: dbrosius Date: 2015-12-12 17:33:56 +0000 (Sat, 12 Dec 2015) 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/pom.xml trunk/fb-contrib/samples/ISB_Sample.java trunk/fb-contrib/samples/SPP_Sample.java trunk/fb-contrib/samples/WOC_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/debug/Debug.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/debug/OCSDebugger.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConflictingTimeUnits.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/HangingExecutors.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ImmatureClass.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InappropriateToStringUse.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/IncorrectInternalClassUse.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InefficientStringBuffering.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InvalidConstantArgument.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LocalSynchronizedCollection.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LoggerOddities.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/MissingMethodsDetector.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NeedlessAutoboxing.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NeedlessMemberCollectionSynchronization.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NonRecycleableTaglibs.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/OverlyPermissiveMethod.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SQLInLoop.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SluggishGui.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousUninitializedArray.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousWaitOnConcurrentObject.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SyncCollectionIterators.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnitTestAssertionOddities.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnrelatedCollectionContents.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnusedParameter.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/WeakExceptionMessaging.java Modified: trunk/fb-contrib/build.xml =================================================================== --- trunk/fb-contrib/build.xml 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/build.xml 2015-12-12 17:33:56 UTC (rev 1786) @@ -2,6 +2,14 @@ <project name="fb-contrib" default="default"> + <presetdef name="javac"> + <javac encoding="UTF-8" /> + </presetdef> + + <presetdef name="javadoc"> + <javadoc encoding="UTF-8" /> + </presetdef> + <property file="user.properties" /> <property file="build.properties" /> <property file="version.properties" /> @@ -20,7 +28,7 @@ <property name="javac.deprecation" value="on" /> <property name="javac.debug" value="on" /> - <property name="fb-contrib.version" value="6.4.0" /> + <property name="fb-contrib.version" value="6.5.0-SNAPSHOT" /> <property name="sonatype.dir" value="${user.home}/.fb-contrib-${fb-contrib.version}-sonatype" /> Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/etc/findbugs.xml 2015-12-12 17:33:56 UTC (rev 1786) @@ -20,7 +20,7 @@ <!-- Detectors --> -<!-- COMMENT OUT FOR RELEASE +<!-- COMMENT OUT FOR RELEASE --> <Detector class="com.mebigfatguy.fbcontrib.debug.OCSDebugger" speed="fast"/> @@ -32,7 +32,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" /> Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/etc/messages.xml 2015-12-12 17:33:56 UTC (rev 1786) @@ -52,7 +52,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.SyncCollectionIterators"> <Details> <![CDATA[ - <p>Looks for use of iterators on synchronized collections built from the java.util.Collections class</p> + <p>Looks for use of iterators on synchronized collections built from the java.util.Collections class.</p> <p>As the collection in question was built through Collections.synchronizedXXX, an assumption is made that this collection must be multithreaded safe. However, iterator access is used, which is explicitly unsafe. When iterators are to be used, synchronization should be done manually.</p> @@ -322,7 +322,7 @@ Since primitive wrapper classes are immutable this is needless garbage being created. Just use the original reference. </p> - <p>It also looks for calls to BoxedClass.valueOf(x) where X is already a Boxed class</p> + <p>It also looks for calls to BoxedClass.valueOf(x) where X is already a BoxedClass</p> <p>It also looks for calls to BoxedClass.valueOf(myString).boxedValue(), when instead it is simpler to use BoxedClass.parseBoxed(myString)</p> <p>It is a fast detector.</p> @@ -696,7 +696,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.SuspiciousComparatorReturnValues"> <Details> <![CDATA[ - <p>Looks for class that implement Comparator or Comparable, and whose compare or compareTo + <p>Looks for classes that implement Comparator or Comparable, and whose compare or compareTo methods return constant values only, but that don't represent the three possible choice (a negative number, 0, and a positive number).</p> <p>It is a fast detector.</p> @@ -847,11 +847,11 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.UnitTestAssertionOddities"> <Details> <![CDATA[ - <p>Looks for junit or testng test case methods that use assertions with odd parameters. + <p>Looks for JUnit or TestNG test case methods that use assertions with odd parameters. Including in this is: <ul> - <li>Passing a constant as the second (actual) parameter in a junit test</li> - <li>not using the three parameter version of asserts for doubles</li> + <li>Passing a constant as the second (actual) parameter in a JUnit test</li> + <li>Not using the three parameter version of asserts for doubles</li> <li>Passing true or false as the first parameter instead of using assertTrue, or assertFalse</li> <li>Using the assert keyword</li> </ul> @@ -911,7 +911,7 @@ should not be counted on.</p> Packages that shouldn't be used are: <ul> - <li>com.sun.xxx</li> + <li>sun.xxx</li> <li>org.apache.xerces.xxx</li> <li>org.apache.xalan.xxx</li> </ul> @@ -1496,7 +1496,7 @@ <p>Looks for classes that store fields that are Strings that impersonate instances of classes, or collections that are fields that hold Strings that impersonate a class. Examples of String impersonating are storing: <ul> - <li>the result of a toString call</li> + <li>The result of a toString call</li> <li>Strings build from parsing or building strings from other objects, such as "1,2,3,4" or "Project:3"</li> </ul> By using Strings you are throwing away type-safety, and making it difficult to reason about what the values of variables @@ -1513,7 +1513,7 @@ <p>Looks for methods that assign a value to a variable in an if equals conditional in a loop, but does not break after doing so. Since equality would seem to be a one time event, continuing with the loop seems pointless, and a break statement in the if statement seems like it should be added.</p> - <p>It is a fast detector</p> + <p>It is a fast detector.</p> ]]> </Details> </Detector> @@ -1521,10 +1521,10 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.ConflatingResourcesAndFiles"> <Details> <![CDATA[ - <p>Looks for methods that use the File api on resources retrieved from URLs where the URL in question isn't from a file protocol. - In the case of classpath resources, this will work if the code is executed from directories, but fail using jars. - If using resources, then use URL.openStream() method instead of File apis.</p> - <p>It is a fast detector</p> + <p>Looks for methods that use the File API on resources retrieved from URLs where the URL in question isn't from a file protocol. + In the case of classpath resources, this will work if the code is executed from directories, but fail using JARs. + If using resources, then use URL.openStream() method instead of File APIs.</p> + <p>It is a fast detector.</p> ]]> </Details> </Detector> @@ -1533,12 +1533,12 @@ <Details> <![CDATA[ <p>Looks for classes that are not fully complete from a usability point of view. Making them more difficult to use - than should be. Things such as - <UL> - <LI>Missing toString() method</LI> - </UL> + than it should be. Things such as + <ul> + <li>Missing toString() method</li> + </ul> </p> - <p>It is a moderately fast detector</p> + <p>It is a moderately fast detector.</p> ]]> </Details> </Detector> @@ -1737,7 +1737,7 @@ <![CDATA[ <p>This method declares a RuntimeException derived class in its throws clause. This may indicate a misunderstanding as to how unchecked exceptions are handled. - If is felt that a RuntimeException is so prevalent that it should be declared, it + If it is felt that a RuntimeException is so prevalent that it should be declared, it is probably a better idea to prevent the occurrence in code.</p> ]]> </Details> @@ -2195,11 +2195,11 @@ </BugPattern> <BugPattern type="COM_PARENT_DELEGATED_CALL"> - <ShortDescription>Method merely delegates to it's superclass's version</ShortDescription> - <LongDescription>Method {1} merely delegates to it's superclass's version</LongDescription> + <ShortDescription>Method merely delegates to its superclass's version</ShortDescription> + <LongDescription>Method {1} merely delegates to its superclass's version</LongDescription> <Details> <![CDATA[ - <p>This method is implemented to just delegate it's implementation by calling + <p>This method is implemented to just delegate its implementation by calling the superclass method with the same signature. This method can just be removed.</p> ]]> </Details> @@ -3123,7 +3123,7 @@ <LongDescription>Method {1} uses iterator().next() on a List to get the first item</LongDescription> <Details> <![CDATA[ - <p>This Method calls myList.iterator().next() on a List to get the first item. It is more performant + <p>This method calls myList.iterator().next() on a List to get the first item. It is more performant to just use myList.get(0).</p> ]]> </Details> @@ -3247,8 +3247,8 @@ </BugPattern> <BugPattern type="BAS_BLOATED_ASSIGNMENT_SCOPE"> - <ShortDescription>Method assigns a variable in a larger scope then is needed</ShortDescription> - <LongDescription>Method {1} assigns a variable in a larger scope then is needed</LongDescription> + <ShortDescription>Method assigns a variable in a larger scope than is needed</ShortDescription> + <LongDescription>Method {1} assigns a variable in a larger scope than is needed</LongDescription> <Details> <![CDATA[ <p><em>THIS DETECTOR IS HIGHLY EXPERIMENTAL AND IS LIKELY TO CREATE A LOT OF FUD</em></p> @@ -3447,8 +3447,8 @@ </BugPattern> <BugPattern type="UTAO_JUNIT_ASSERTION_ODDITIES_ACTUAL_CONSTANT"> - <ShortDescription>Junit test method passes constant to second (actual) assertion parameter</ShortDescription> - <LongDescription>Junit test method {1} passes constant to second (actual) assertion parameter</LongDescription> + <ShortDescription>JUnit test method passes constant to second (actual) assertion parameter</ShortDescription> + <LongDescription>JUnit test method {1} passes constant to second (actual) assertion parameter</LongDescription> <Details> <![CDATA[ <p>This method calls assert passing a constant value as the second of the two values. The assert @@ -3459,8 +3459,8 @@ </BugPattern> <BugPattern type="UTAO_JUNIT_ASSERTION_ODDITIES_INEXACT_DOUBLE"> - <ShortDescription>Junit test method asserts that two doubles are exactly equal</ShortDescription> - <LongDescription>Junit test method {1} asserts that two doubles are exactly equal</LongDescription> + <ShortDescription>JUnit test method asserts that two doubles are exactly equal</ShortDescription> + <LongDescription>JUnit test method {1} asserts that two doubles are exactly equal</LongDescription> <Details> <![CDATA[ <p>This method calls assert with two doubles or Doubles. Due to the imprecision of doubles, you @@ -3470,8 +3470,8 @@ </BugPattern> <BugPattern type="UTAO_JUNIT_ASSERTION_ODDITIES_BOOLEAN_ASSERT"> - <ShortDescription>Junit test method asserts that a value is true or false</ShortDescription> - <LongDescription>Junit test method {1} asserts that a value is true or false</LongDescription> + <ShortDescription>JUnit test method asserts that a value is true or false</ShortDescription> + <LongDescription>JUnit test method {1} asserts that a value is true or false</LongDescription> <Details> <![CDATA[ <p>This method asserts that a value is equal to true or false. It is simpler to just @@ -3481,8 +3481,8 @@ </BugPattern> <BugPattern type="UTAO_JUNIT_ASSERTION_ODDITIES_IMPOSSIBLE_NULL"> - <ShortDescription>Junit test method asserts that an auto-boxed value is not null</ShortDescription> - <LongDescription>Junit test method {1} asserts that an auto-boxed value is not null</LongDescription> + <ShortDescription>JUnit test method asserts that an autoboxed value is not null</ShortDescription> + <LongDescription>JUnit test method {1} asserts that an autoboxed value is not null</LongDescription> <Details> <![CDATA[ <p>This method asserts that a primitive value that was autoboxed into a boxed primitive was not @@ -3493,66 +3493,66 @@ </BugPattern> <BugPattern type="UTAO_JUNIT_ASSERTION_ODDITIES_ASSERT_USED"> - <ShortDescription>Junit test method uses Java asserts rather than a junit assertion</ShortDescription> - <LongDescription>Junit test method {1} uses Java asserts rather than a junit assertion</LongDescription> + <ShortDescription>JUnit test method uses Java asserts rather than a JUnit assertion</ShortDescription> + <LongDescription>JUnit test method {1} uses Java asserts rather than a JUnit assertion</LongDescription> <Details> <![CDATA[ <p>This method uses a Java assert to assure that a certain state is in effect. As this is - a junit test it makes more sense to either check this condition with a junit assert, or allow + a JUnit test it makes more sense to either check this condition with a JUnit assert, or allow a following exception to occur.</p> ]]> </Details> </BugPattern> <BugPattern type="UTAO_JUNIT_ASSERTION_ODDITIES_USE_ASSERT_NULL"> - <ShortDescription>Junit test method passes null Assert.assertEquals</ShortDescription> - <LongDescription>Junit test method {1} passes null to Assert.assertEquals</LongDescription> + <ShortDescription>JUnit test method passes null Assert.assertEquals</ShortDescription> + <LongDescription>JUnit test method {1} passes null to Assert.assertEquals</LongDescription> <Details> <![CDATA[ <p>This method compares an object's equality to null. It is better to use the Assert.assertNull - method so that the junit failure method is more meaningful of the intended test.</p> + method so that the JUnit failure method is more meaningful of the intended test.</p> ]]> </Details> </BugPattern> <BugPattern type="UTAO_JUNIT_ASSERTION_ODDITIES_USE_ASSERT_NOT_NULL"> - <ShortDescription>Junit test method passes null Assert.assertNotEquals</ShortDescription> - <LongDescription>Junit test method {1} passes null to Assert.assertNotEquals</LongDescription> + <ShortDescription>JUnit test method passes null Assert.assertNotEquals</ShortDescription> + <LongDescription>JUnit test method {1} passes null to Assert.assertNotEquals</LongDescription> <Details> <![CDATA[ <p>This method compares an object's inequality to null. It is better to use the Assert.assertNotNull - method so that the junit failure method is more meaningful of the intended test.</p> + method so that the JUnit failure method is more meaningful of the intended test.</p> ]]> </Details> </BugPattern> <BugPattern type="UTAO_JUNIT_ASSERTION_ODDITIES_USE_ASSERT_EQUALS"> - <ShortDescription>Junit test method passes boolean expression to Assert.assertFalse / Assert.assertTrue</ShortDescription> - <LongDescription>Junit test method {1} passes boolean expression to Assert.assertFalse / Assert.assertTrue</LongDescription> + <ShortDescription>JUnit test method passes boolean expression to Assert.assertFalse / Assert.assertTrue</ShortDescription> + <LongDescription>JUnit test method {1} passes boolean expression to Assert.assertFalse / Assert.assertTrue</LongDescription> <Details> <![CDATA[ <p>This method evaluates a boolean expression and passes that to Assert.assertFalse / Assert.assertTrue. It is better to pass the two values that are being equated to the Assert.assertEquals method so that the - junit failure method is more meaningful of the intended test.</p> + JUnit failure method is more meaningful of the intended test.</p> ]]> </Details> </BugPattern> <BugPattern type="UTAO_JUNIT_ASSERTION_ODDITIES_USE_ASSERT_NOT_EQUALS"> - <ShortDescription>Junit test method passes boolean expression to Assert.assertFalse / Assert.assertTrue</ShortDescription> - <LongDescription>Junit test method {1} passes boolean expression to Assert.assertFalse / Assert.assertTrue</LongDescription> + <ShortDescription>JUnit test method passes boolean expression to Assert.assertFalse / Assert.assertTrue</ShortDescription> + <LongDescription>JUnit test method {1} passes boolean expression to Assert.assertFalse / Assert.assertTrue</LongDescription> <Details> <![CDATA[ <p>This method evaluates a boolean expression and passes that to Assert.assertFalse / Assert.assertTrue. It is better to pass the two values that are being equated to the Assert.assertNotEquals method so that the - junit failure method is more meaningful of the intended test.</p> + JUnit failure method is more meaningful of the intended test.</p> ]]> </Details> </BugPattern> <BugPattern type="UTAO_JUNIT_ASSERTION_ODDITIES_NO_ASSERT"> - <ShortDescription>Junit test method appears to have no assertions</ShortDescription> - <LongDescription>Junit test method {1} appears to have no assertions</LongDescription> + <ShortDescription>JUnit test method appears to have no assertions</ShortDescription> + <LongDescription>JUnit test method {1} appears to have no assertions</LongDescription> <Details> <![CDATA[ <p>This JUnit test method has no assertions. While a unit test could still be valid if it relies on whether @@ -3569,7 +3569,7 @@ <Details> <![CDATA[ <p>This JUnit 4 test is still using classes from the junit.framework.* package. You should switch them - over to the corresponding org.junit.* set of classes, instead</p> + over to the corresponding org.junit.* set of classes, instead.</p> ]]> </Details> </BugPattern> @@ -3609,8 +3609,8 @@ </BugPattern> <BugPattern type="UTAO_TESTNG_ASSERTION_ODDITIES_IMPOSSIBLE_NULL"> - <ShortDescription>TestNG test method asserts that an auto-boxed value is not null</ShortDescription> - <LongDescription>TestNG test method {1} asserts that an auto-boxed value is not null</LongDescription> + <ShortDescription>TestNG test method asserts that an autoboxed value is not null</ShortDescription> + <LongDescription>TestNG test method {1} asserts that an autoboxed value is not null</LongDescription> <Details> <![CDATA[ <p>This method asserts that a primitive value that was autoboxed into a boxed primitive was not @@ -3621,12 +3621,12 @@ </BugPattern> <BugPattern type="UTAO_TESTNG_ASSERTION_ODDITIES_ASSERT_USED"> - <ShortDescription>TestNG test method uses Java asserts rather than a testng assertion</ShortDescription> - <LongDescription>TestNG test method {1} uses Java asserts rather than a testng assertion</LongDescription> + <ShortDescription>TestNG test method uses Java asserts rather than a TestNG assertion</ShortDescription> + <LongDescription>TestNG test method {1} uses Java asserts rather than a TestNG assertion</LongDescription> <Details> <![CDATA[ <p>This method uses a Java assert to assure that a certain state is in effect. As this is - a testng test it makes more sense to either check this condition with a testng assert, or allow + a TestNG test it makes more sense to either check this condition with a TestNG assert, or allow a following exception to occur.</p> ]]> </Details> @@ -3724,7 +3724,7 @@ <p>This method catches an exception and generates a new exception of type java.lang.Exception, passing the original exception as the new Exception's cause. If the original Exception was actually an java.lang.Error, this is dubious as you should not be handling errors. If the original exception is a more specific exception, there is no - reason to wrap it in an exception of the java.lang.Exception class, and just obfuscates the type of error that is occuring. + reason to wrap it in an exception of the java.lang.Exception class, and just obfuscates the type of error that is occurring. </p> ]]> </Details> @@ -3852,7 +3852,7 @@ to change or removal. You should not be using these classes.</p> Packages that shouldn't be used are: <ul> - <li>com.sun.xxx</li> + <li>sun.xxx</li> <li>org.apache.xerces.xxx</li> <li>org.apache.xalan.xxx</li> </ul> @@ -3872,9 +3872,9 @@ type functionality, which seems dubious when done on a collection</p> <p>Finally, as a collection is often modified, problems will occur if the collection is contained in a set, because the hashCode, equals or compareTo values will change while the - collection is in the set</p> + collection is in the set.</p> <p>If you wish to maintain a collection of collections, it is probably better to use a List - as the outer collection</p> + as the outer collection.</p> ]]> </Details> </BugPattern> @@ -4172,7 +4172,7 @@ <LongDescription>Method {1} calls deprecated SecureRandom method {2}</LongDescription> <Details> <![CDATA[ - <p>The <code>In JDK 1.5 or less, SecureRandom()</code> constructors and <code>SecureRandom.getSeed()</code> method are recommended against using. Call <code>SecureRandom.getInstance()</code> and <code>SecureRandom.getInstance().generateSeed()</code> instead.</p> + <p>In JDK 1.5 or less, the <code>SecureRandom()</code> constructors and <code>SecureRandom.getSeed()</code> method are recommended against using. Call <code>SecureRandom.getInstance()</code> and <code>SecureRandom.getInstance().generateSeed()</code> instead.</p> ]]> </Details> </BugPattern> @@ -4246,7 +4246,7 @@ <p>As per the Java specifications, "UTF-8", "US-ASCII", "UTF-16" and "ISO-8859-1" will all be valid <a href = "http://docs.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html#standard">encoding charsets</a>. If you aren't sure, try "UTF-8".</p> - <p><b>New in Java 1.7</b>, You can specify an encoding from <code>StandardCharsets</code>, like <code>StandardCharsets.UTF_8</code>. These are generally preferrable because you don't have to deal with <code>UnsupportedEncodingException</code>.</p> + <p><b>New in Java 1.7</b>, you can specify an encoding from <code>StandardCharsets</code>, like <code>StandardCharsets.UTF_8</code>. These are generally preferrable because you don't have to deal with <code>UnsupportedEncodingException</code>.</p> ]]> </Details> </BugPattern> @@ -4450,7 +4450,7 @@ <LongDescription>Method {1} compares class name instead of comparing the class</LongDescription> <Details> <![CDATA[ - <p>In a JVM, Two classes are the same class (and consequently the same type) if + <p>In a JVM, two classes are the same class (and consequently the same type) if they are loaded by the same class loader, and they have the same fully qualified name [JVMSpec 1999]. @@ -4484,8 +4484,8 @@ </BugPattern> <BugPattern type="CU_CLONE_USABILITY_MISMATCHED_RETURN"> - <ShortDescription>Clone method declares it returns a type different then the owning class</ShortDescription> - <LongDescription>Clone method {1} declares it returns a type different then the owning class</LongDescription> + <ShortDescription>Clone method declares it returns a type different than the owning class</ShortDescription> + <LongDescription>Clone method {1} declares it returns a type different than the owning class</LongDescription> <Details> <![CDATA[ <p>This class implements the Cloneable interface but defines its clone method to return a type @@ -4531,7 +4531,7 @@ and thus needlessly causes intermediate reallocations of the collection.</p> <p>You can use the constructor that takes an initial size and that will be much better, but due to the loadFactor of Maps and Sets, even this will not be a correct estimate.</p> - <p>If you are using guava, use its methods that allocate maps and sets with a predetermined size, + <p>If you are using Guava, use its methods that allocate maps and sets with a predetermined size, to get the best chance for no reallocations, such as: <ul> <li>Sets.newHashSetWithExpectedSize(int)</li> @@ -4655,7 +4655,7 @@ <Details> <![CDATA[ <p>This method attempts to modify a collection that it got from a source that could potentially have created an - immutable collection, thru Arrays.asList, Collections.unmodifiableXXX, or one of guava's methods. Doing so will cause + immutable collection, through Arrays.asList, Collections.unmodifiableXXX, or one of Guava's methods. Doing so will cause an exception, as these collections are not mutable.</p> ]]> </Details> @@ -4979,13 +4979,13 @@ </BugPattern> <BugPattern type="CRF_CONFLATING_RESOURCES_AND_FILES"> - <ShortDescription>This method accesses URL resources using the File api</ShortDescription> - <LongDescription>This method {1} accesses URL resources using the File api]</LongDescription> + <ShortDescription>This method accesses URL resources using the File API</ShortDescription> + <LongDescription>This method {1} accesses URL resources using the File API</LongDescription> <Details> <![CDATA[ - <p>This method fetches a resource from a URL, and uses the File api to manipulate it. If this resource is a - classpath resource, it will work if the resource is a file in a directory. If however the file is inside a jar file - this will fail. Use the URL.openStream api instead to access the data of the classpath resource. + <p>This method fetches a resource from a URL, and uses the File API to manipulate it. If this resource is a + classpath resource, it will work if the resource is a file in a directory. If however the file is inside a JAR file + this will fail. Use the URL.openStream API instead to access the data of the classpath resource. </p> ]]> </Details> @@ -4996,7 +4996,7 @@ <LongDescription>Class {0} does not implement an equals method</LongDescription> <Details> <![CDATA[ - <p>This class which has instance fields has no equals(Object o) method, It is possible that this + <p>This class which has instance fields has no equals(Object o) method. It is possible that this class is never used in a context where this is required, it is often assumed, however, from clients of this class that it is, so it is good to add such methods when you create them. </p> @@ -5009,7 +5009,7 @@ <LongDescription>Class {0} does not implement a hashCode method</LongDescription> <Details> <![CDATA[ - <p>This class which has instance fields has no hashCode() method, It is possible that this + <p>This class which has instance fields has no hashCode() method. It is possible that this class is never used in a context where this is required, it is often assumed, however, from clients of this class that it is, so it is good to add such methods when you create them. </p> @@ -5050,7 +5050,7 @@ <Details> <![CDATA[ <p>This JAX-RS endpoint is annotated to be used as @GET requests, but also documents that it - consumes JSON or XML data. Since a get request pulls parameters from the url, and not + consumes JSON or XML data. Since a GET request pulls parameters from the URL, and not the body of request, this pattern is problematic. If you wish to consume JSON or XML data, this request should be annotated with @POST. ]]> @@ -5075,7 +5075,7 @@ <li>javax.servlet.HttpServletRequest</li> <li>javax.servlet.HttpServletResponse</li> </ul> - It is possible that your container can supply additional types, but these types are not standard are may + It is possible that your container can supply additional types, but these types are not standard and may not be supported on other application servers.</p> ]]> </Details> @@ -5099,7 +5099,7 @@ <![CDATA[ <p>This JAX-RS endpoint declares parameters without specifying where the value of this parameter comes from. You can specify this by using one of several 'Param' annotations (@PathParam, @CookieParam, @FormParam @HeaderParam @MatrixParam @QueryParam), - by adding a @Context parameter annotation, or you can declare that the method @Consumes an xml or json stream. + by adding a @Context parameter annotation, or you can declare that the method @Consumes an XML or JSON stream. ]]> </Details> </BugPattern> Modified: trunk/fb-contrib/pom.xml =================================================================== --- trunk/fb-contrib/pom.xml 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/pom.xml 2015-12-12 17:33:56 UTC (rev 1786) @@ -8,7 +8,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>com.mebigfatguy.fb-contrib</groupId> <artifactId>fb-contrib</artifactId> - <version>6.4.0</version> + <version>6.5.0-SNAPSHOT</version> <prerequisites> <maven>2.2.1</maven> @@ -74,6 +74,9 @@ <name>Juan Martín Sotuyo Dodero</name> <email>jua...@gm...</email> </contributor> + <contributor> + <name>Richard Fearn</name> + </contributor> </contributors> <licenses> Modified: trunk/fb-contrib/samples/ISB_Sample.java =================================================================== --- trunk/fb-contrib/samples/ISB_Sample.java 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/samples/ISB_Sample.java 2015-12-12 17:33:56 UTC (rev 1786) @@ -116,5 +116,15 @@ public String xform(String a) { return a; } + + enum MonsterSpeak {UNGA, BUNGA} + + public String speak(MonsterSpeak s) { + return "hello" + 1 + s.toString(); + } + + public String fpSpeak(MonsterSpeak s) { + return 1 + s.toString(); + } } Modified: trunk/fb-contrib/samples/SPP_Sample.java =================================================================== --- trunk/fb-contrib/samples/SPP_Sample.java 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/samples/SPP_Sample.java 2015-12-12 17:33:56 UTC (rev 1786) @@ -1,6 +1,8 @@ import java.io.Serializable; import java.lang.reflect.Array; import java.math.BigDecimal; +import java.sql.PreparedStatement; +import java.sql.SQLException; import java.util.ArrayList; import java.util.BitSet; import java.util.Calendar; @@ -396,7 +398,12 @@ return t.equals("foo"); } - + + public void fpGitHubIssue81(PreparedStatement sqlQuery, String name) throws SQLException { + if (name != null && !(name = name.trim()).equals("")) { + sqlQuery.setString(1, name + "%"); + } + } } class StringProducer { Modified: trunk/fb-contrib/samples/WOC_Sample.java =================================================================== --- trunk/fb-contrib/samples/WOC_Sample.java 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/samples/WOC_Sample.java 2015-12-12 17:33:56 UTC (rev 1786) @@ -45,6 +45,13 @@ System.out.println("woops"); } } + + public void testIterateEmpty() { + Set<String> ss = new HashSet<String>(); + + for (String s : ss) { + } + } public Map<String, String> testFPWOCReturn() { // no tag, value is returned Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/debug/Debug.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/debug/Debug.java 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/debug/Debug.java 2015-12-12 17:33:56 UTC (rev 1786) @@ -21,8 +21,8 @@ import java.io.BufferedOutputStream; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; -import java.io.FileOutputStream; import java.io.PrintStream; import java.nio.charset.StandardCharsets; Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/debug/OCSDebugger.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/debug/OCSDebugger.java 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/debug/OCSDebugger.java 2015-12-12 17:33:56 UTC (rev 1786) @@ -20,6 +20,7 @@ import java.io.IOException; import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; import org.apache.bcel.Constants; import org.apache.bcel.classfile.Code; @@ -57,7 +58,7 @@ String curMethodDesc = getClassContext().getJavaClass().getClassName() + "." + m.getName() + m.getSignature(); if (curMethodDesc.equals(METHOD_DESC)) { try { - pw = new PrintWriter(OUTPUT_FILE_NAME, "UTF-8"); + pw = new PrintWriter(OUTPUT_FILE_NAME, StandardCharsets.UTF_8.name()); stack.resetForMethodEntry(this); super.visitCode(obj); Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java 2015-12-12 17:33:56 UTC (rev 1786) @@ -216,6 +216,12 @@ if (catchHandlers.get(pc)) { ignoreRegs.set(reg); + ScopeBlock catchSB = findScopeBlock(rootScopeBlock, pc+1); + if ((catchSB != null) && (catchSB.getStart() < pc)) { + ScopeBlock sb = new ScopeBlock(pc, catchSB.getFinish()); + catchSB.setFinish(getPC() - 1); + rootScopeBlock.addChild(sb); + } } else if (monitorSyncPCs.size() > 0) { ignoreRegs.set(reg); } else if (sawNull) { Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConflictingTimeUnits.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConflictingTimeUnits.java 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConflictingTimeUnits.java 2015-12-12 17:33:56 UTC (rev 1786) @@ -171,10 +171,11 @@ case INVOKEVIRTUAL: case INVOKEINTERFACE: case INVOKESTATIC: - FQMethod methodCall = new FQMethod(getClassConstantOperand(), getNameConstantOperand(), getSigConstantOperand()); + String signature = getSigConstantOperand(); + FQMethod methodCall = new FQMethod(getClassConstantOperand(), getNameConstantOperand(), signature); unit = TIME_UNIT_GENERATING_METHODS.get(methodCall); if (unit == Units.CALLER) { - int offset = Type.getArgumentTypes(getSigConstantOperand()).length; + int offset = Type.getArgumentTypes(signature).length; if (stack.getStackDepth() > offset) { OpcodeStack.Item item = stack.getStackItem(offset); unit = (Units) item.getUserValue(); Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/HangingExecutors.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/HangingExecutors.java 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/HangingExecutors.java 2015-12-12 17:33:56 UTC (rev 1786) @@ -35,6 +35,7 @@ import com.mebigfatguy.fbcontrib.utils.BugType; import com.mebigfatguy.fbcontrib.utils.ToString; +import com.mebigfatguy.fbcontrib.utils.UnmodifiableSet; import com.mebigfatguy.fbcontrib.utils.Values; import edu.umd.cs.findbugs.BugInstance; @@ -55,27 +56,16 @@ */ public class HangingExecutors extends BytecodeScanningDetector { - private static final Set<String> hangableSig; + private static final Set<String> hangableSig = UnmodifiableSet.create( + "Ljava/util/concurrent/ExecutorService;", + "Ljava/util/concurrent/AbstractExecutorService;", + "Ljava/util/concurrent/ForkJoinPool;", + "Ljava/util/concurrent/ScheduledThreadPoolExecutor;", + "Ljava/util/concurrent/ThreadPoolExecutor;" + ); - static { - Set<String> hs = new HashSet<String>(); - hs.add("Ljava/util/concurrent/ExecutorService;"); - hs.add("Ljava/util/concurrent/AbstractExecutorService;"); - hs.add("Ljava/util/concurrent/ForkJoinPool;"); - hs.add("Ljava/util/concurrent/ScheduledThreadPoolExecutor;"); - hs.add("Ljava/util/concurrent/ThreadPoolExecutor;"); - hangableSig = Collections.unmodifiableSet(hs); - } + private static final Set<String> shutdownMethods = UnmodifiableSet.create("shutdown","shutdownNow"); - private static final Set<String> shutdownMethods; - - static { - Set<String> sm = new HashSet<String>(); - sm.add("shutdown"); - sm.add("shutdownNow"); - shutdownMethods = Collections.unmodifiableSet(sm); - } - private final BugReporter bugReporter; private Map<XField, AnnotationPriority> hangingFieldCandidates; private Map<XField, Integer> exemptExecutors; Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ImmatureClass.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ImmatureClass.java 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ImmatureClass.java 2015-12-12 17:33:56 UTC (rev 1786) @@ -1,9 +1,9 @@ package com.mebigfatguy.fbcontrib.detect; +import org.apache.bcel.Repository; import org.apache.bcel.classfile.AnnotationEntry; import org.apache.bcel.classfile.Field; import org.apache.bcel.classfile.JavaClass; -import org.apache.bcel.Repository; import com.mebigfatguy.fbcontrib.collect.MethodInfo; import com.mebigfatguy.fbcontrib.collect.Statistics; Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InappropriateToStringUse.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InappropriateToStringUse.java 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InappropriateToStringUse.java 2015-12-12 17:33:56 UTC (rev 1786) @@ -19,7 +19,6 @@ package com.mebigfatguy.fbcontrib.detect; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -32,6 +31,7 @@ import com.mebigfatguy.fbcontrib.utils.RegisterUtils; import com.mebigfatguy.fbcontrib.utils.SignatureUtils; import com.mebigfatguy.fbcontrib.utils.TernaryPatcher; +import com.mebigfatguy.fbcontrib.utils.UnmodifiableSet; import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; @@ -51,35 +51,31 @@ @CustomUserValue public class InappropriateToStringUse extends BytecodeScanningDetector { - private static final Set<String> validToStringClasses = new HashSet<String>(); + private static final Set<String> validToStringClasses = UnmodifiableSet.create( + "java/lang/Object", // too many fps + "java/lang/Byte", + "java/lang/Character", + "java/lang/Short", + "java/lang/Integer", + "java/lang/Boolean", + "java/lang/Float", + "java/lang/Double", + "java/lang/Long", + "java/lang/String", + "java/lang/Number", + "java/lang/StringBuffer", + "java/lang/StringBuilder", + "java/io/StringWriter" + ); - static { - validToStringClasses.add("java/lang/Object"); // too many fps - validToStringClasses.add("java/lang/Byte"); - validToStringClasses.add("java/lang/Character"); - validToStringClasses.add("java/lang/Short"); - validToStringClasses.add("java/lang/Integer"); - validToStringClasses.add("java/lang/Boolean"); - validToStringClasses.add("java/lang/Float"); - validToStringClasses.add("java/lang/Double"); - validToStringClasses.add("java/lang/Long"); - validToStringClasses.add("java/lang/String"); - validToStringClasses.add("java/lang/Number"); - validToStringClasses.add("java/lang/StringBuffer"); - validToStringClasses.add("java/lang/StringBuilder"); - validToStringClasses.add("java/io/StringWriter"); - } + private static final Set<String> stringAlgoMethods = UnmodifiableSet.create( + "indexOf", + "contains", + "startsWith", + "endsWith", + "substring" + ); - private static final Set<String> stringAlgoMethods = new HashSet<String>(); - - static { - stringAlgoMethods.add("indexOf"); - stringAlgoMethods.add("contains"); - stringAlgoMethods.add("startsWith"); - stringAlgoMethods.add("endsWith"); - stringAlgoMethods.add("substring"); - } - private final BugReporter bugReporter; private OpcodeStack stack; private Map<Integer, String> toStringRegisters; Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/IncorrectInternalClassUse.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/IncorrectInternalClassUse.java 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/IncorrectInternalClassUse.java 2015-12-12 17:33:56 UTC (rev 1786) @@ -18,7 +18,6 @@ */ package com.mebigfatguy.fbcontrib.detect; -import java.util.HashSet; import java.util.Set; import org.apache.bcel.classfile.Constant; @@ -28,6 +27,7 @@ import com.mebigfatguy.fbcontrib.utils.BugType; import com.mebigfatguy.fbcontrib.utils.ToString; +import com.mebigfatguy.fbcontrib.utils.UnmodifiableSet; import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; @@ -40,23 +40,24 @@ */ public class IncorrectInternalClassUse implements Detector { private final BugReporter bugReporter; - private static final Set<String> internalPackages = new HashSet<String>(); - private static final Set<String> externalPackages = new HashSet<String>(); - static { - internalPackages.add("sun/"); - internalPackages.add("org/apache/commons/digester/annotations/internal"); - internalPackages.add("org/apache/xerces/"); - internalPackages.add("org/apache/xalan/"); - internalPackages.add("org/mockito/internal/"); - internalPackages.add("org/springframework/asm/"); - internalPackages.add("org/springframework/cglib/"); - internalPackages.add("org/springframework/objenesis/"); - externalPackages.add("org/apache/xerces/xni/"); - externalPackages.add("org/apache/xerces/xs/"); - externalPackages.add("org/apache/xalan/extensions"); - } - + private static final Set<String> internalPackages = UnmodifiableSet.create( + "sun/", + "org/apache/commons/digester/annotations/internal", + "org/apache/xerces/", + "org/apache/xalan/", + "org/mockito/internal/", + "org/springframework/asm/", + "org/springframework/cglib/", + "org/springframework/objenesis/" + ); + + private static final Set<String> externalPackages = UnmodifiableSet.create( + "org/apache/xerces/xni/", + "org/apache/xerces/xs/", + "org/apache/xalan/extensions" + ); + /** * constructs a IICU detector given the reporter to report bugs on * @@ -99,6 +100,7 @@ */ @Override public void report() { + // not used, required by the interface } /** Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InefficientStringBuffering.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InefficientStringBuffering.java 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InefficientStringBuffering.java 2015-12-12 17:33:56 UTC (rev 1786) @@ -25,6 +25,7 @@ import com.mebigfatguy.fbcontrib.utils.BugType; import com.mebigfatguy.fbcontrib.utils.OpcodeUtils; import com.mebigfatguy.fbcontrib.utils.TernaryPatcher; +import com.mebigfatguy.fbcontrib.utils.ToString; import com.mebigfatguy.fbcontrib.utils.Values; import edu.umd.cs.findbugs.BugInstance; @@ -40,7 +41,7 @@ @CustomUserValue public class InefficientStringBuffering extends BytecodeScanningDetector { private enum AppendType { - NONE, CLEAR, NESTED, TOSTRING + CLEAR, NESTED, TOSTRING }; private BugReporter bugReporter; @@ -90,23 +91,24 @@ @Override public void sawOpcode(final int seen) { - AppendType apType = AppendType.NONE; + ISBUserValue userValue = null; + try { stack.precomputation(this); if (seen == INVOKESPECIAL) { - apType = sawInvokeSpecial(apType); + userValue = sawInvokeSpecial(userValue); } else if (seen == INVOKEVIRTUAL) { if (sawLDCEmpty) { dealWithEmptyString(); } - apType = sawInvokeVirtual(apType); + userValue = sawInvokeVirtual(userValue); } else if ((seen == GOTO) || (seen == GOTO_W)) { int depth = stack.getStackDepth(); for (int i = 0; i < depth; i++) { OpcodeStack.Item itm = stack.getStackItem(i); - itm.setUserValue(AppendType.NONE); + itm.setUserValue(null); } } else if ((seen == LDC) || (seen == LDC_W)) { Constant c = getConstantRefOperand(); @@ -117,14 +119,14 @@ } } } else if (OpcodeUtils.isALoad(seen)) { - apType = AppendType.CLEAR; + userValue = new ISBUserValue(AppendType.CLEAR, true); } } finally { handleOpcode(seen); - if (apType != AppendType.NONE) { + if (userValue != null) { if (stack.getStackDepth() > 0) { OpcodeStack.Item itm = stack.getStackItem(0); - itm.setUserValue(apType); + itm.setUserValue(userValue); } } } @@ -136,43 +138,60 @@ TernaryPatcher.post(stack, seen); } - private AppendType sawInvokeVirtual(AppendType apType) { + private ISBUserValue sawInvokeVirtual(ISBUserValue userValue) { String calledClass = getClassConstantOperand(); if (("java/lang/StringBuffer".equals(calledClass) || "java/lang/StringBuilder".equals(calledClass))) { String methodName = getNameConstantOperand(); if ("append".equals(methodName)) { OpcodeStack.Item itm = getStringBufferItemAt(1); - apType = (itm == null) ? AppendType.NONE : (AppendType) itm.getUserValue(); + userValue = (ISBUserValue) itm.getUserValue(); if (stack.getStackDepth() > 0) { itm = stack.getStackItem(0); - Object userVal = itm.getUserValue(); - AppendType apValue = (userVal instanceof AppendType ? (AppendType) userVal : AppendType.NONE); - switch (apValue) { - case NESTED: - bugReporter.reportBug(new BugInstance(this, BugType.ISB_INEFFICIENT_STRING_BUFFERING.name(), - "toString".equals(getMethodName()) ? LOW_PRIORITY : NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this)); - break; - case TOSTRING: - bugReporter.reportBug(new BugInstance(this, BugType.ISB_TOSTRING_APPENDING.name(), NORMAL_PRIORITY).addClass(this).addMethod(this) - .addSourceLine(this)); - break; - default: - break; + ISBUserValue uv = (ISBUserValue) itm.getUserValue(); + if (uv != null) { + switch (uv.getAppendType()) { + case NESTED: + bugReporter.reportBug(new BugInstance(this, BugType.ISB_INEFFICIENT_STRING_BUFFERING.name(), + "toString".equals(getMethodName()) ? LOW_PRIORITY : NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this)); + break; + case TOSTRING: + if (stack.getStackDepth() > 1) { + itm = stack.getStackItem(1); + if (itm != null) { + uv = (ISBUserValue) itm.getUserValue(); + + if ((uv != null) && uv.hasResolvedString()) { + bugReporter.reportBug(new BugInstance(this, BugType.ISB_TOSTRING_APPENDING.name(), NORMAL_PRIORITY).addClass(this).addMethod(this) + .addSourceLine(this)); + } + } + } + break; + default: + break; + } } } + + if (getSigConstantOperand().startsWith("(Ljava/lang/String;)")) { + if (userValue == null) { + userValue = new ISBUserValue(AppendType.CLEAR, true); + } else { + userValue = new ISBUserValue(userValue.getAppendType(), true); + } + } } else if ("toString".equals(methodName)) { OpcodeStack.Item itm = getStringBufferItemAt(0); - apType = (itm == null) ? AppendType.NONE : (AppendType) itm.getUserValue(); + userValue = (ISBUserValue) itm.getUserValue(); } } else if ("toString".equals(getNameConstantOperand()) && "()Ljava/lang/String;".equals(getSigConstantOperand())) { - // calls to this.toString() are okay, some people like to be - // explicit + // calls to this.toString() are okay, some people like to be explicit if ((stack.getStackDepth() > 0) && (stack.getStackItem(0).getRegisterNumber() != 0)) { - apType = AppendType.TOSTRING; + userValue = new ISBUserValue(AppendType.TOSTRING); } } - return apType; + return userValue; } private void dealWithEmptyString() { @@ -195,7 +214,7 @@ } } - private AppendType sawInvokeSpecial(AppendType apType) { + private ISBUserValue sawInvokeSpecial(ISBUserValue userValue) { String calledClass = getClassConstantOperand(); if (("java/lang/StringBuffer".equals(calledClass) || "java/lang/StringBuilder".equals(calledClass)) && Values.CONSTRUCTOR.equals(getNameConstantOperand())) { @@ -203,20 +222,24 @@ if ("()V".equals(signature)) { OpcodeStack.Item itm = getStringBufferItemAt(2); if (itm != null) { - apType = AppendType.NESTED; + userValue = new ISBUserValue(AppendType.NESTED); } } else if ("(Ljava/lang/String;)V".equals(signature)) { if (stack.getStackDepth() > 0) { OpcodeStack.Item itm = stack.getStackItem(0); - apType = (AppendType) itm.getUserValue(); - if (apType == AppendType.NESTED) { + userValue = (ISBUserValue) itm.getUserValue(); + if ((userValue != null) && userValue.getAppendType() == AppendType.NESTED) { bugReporter.reportBug(new BugInstance(this, BugType.ISB_INEFFICIENT_STRING_BUFFERING.name(), NORMAL_PRIORITY).addClass(this) .addMethod(this).addSourceLine(this)); } + + if (userValue == null) { + userValue = new ISBUserValue(AppendType.CLEAR, true); + } } } } - return apType; + return userValue; } private OpcodeStack.Item getStringBufferItemAt(int depth) { @@ -230,4 +253,53 @@ return null; } + + class ISBUserValue { + + private AppendType appendType; + private boolean hasResolvedString; + + public ISBUserValue(AppendType appType) { + this(appType, false); + } + + public ISBUserValue(AppendType appType, boolean resolved) { + appendType = appType; + hasResolvedString = resolved; + } + + public AppendType getAppendType() { + return appendType; + } + + public boolean hasResolvedString() { + return hasResolvedString; + } + + @Override + public int hashCode() { + return appendType.hashCode() ^ (hasResolvedString ? 1 : 0); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ISBUserValue)) { + return false; + } + + ISBUserValue that = (ISBUserValue) obj; + return (appendType == that.appendType) && (hasResolvedString == that.hasResolvedString); + } + + private InefficientStringBuffering getOuterType() { + return InefficientStringBuffering.this; + } + + @Override + public String toString() { + return ToString.build(this); + } + + + } } Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InvalidConstantArgument.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InvalidConstantArgument.java 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InvalidConstantArgument.java 2015-12-12 17:33:56 UTC (rev 1786) @@ -144,7 +144,7 @@ if (stack.getStackDepth() > parmOffset) { OpcodeStack.Item item = stack.getStackItem(parmOffset); - Comparable<?> cons = (Comparable<?>) item.getConstant(); + Comparable cons = (Comparable) item.getConstant(); if (!info.isValid(cons)) { int badParm = 1 + (info.fromStart ? info.parameterOffset : Type.getArgumentTypes(sig).length - info.parameterOffset - 1); bugReporter.reportBug(new BugInstance(this, BugType.ICA_INVALID_CONSTANT_ARGUMENT.name(), NORMAL_PRIORITY).addClass(this) @@ -169,7 +169,7 @@ * legal values, and what offset from the start or end of the method the parm * is */ - static class ParameterInfo<T extends Comparable<?>> { + static class ParameterInfo<T extends Comparable<T>> { private int parameterOffset; private boolean fromStart; private Set<T> validValues; @@ -198,7 +198,7 @@ return info; } - public boolean isValid(Comparable o) { + public boolean isValid(Comparable<T> o) { if (o == null) { return true; } @@ -211,7 +211,7 @@ } } - static class Range<T extends Comparable<?>> { + static class Range<T extends Comparable<T>> { T from; T to; Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LocalSynchronizedCollection.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LocalSynchronizedCollection.java 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LocalSynchronizedCollection.java 2015-12-12 17:33:56 UTC (rev 1786) @@ -26,6 +26,7 @@ import org.apache.bcel.Constants; import com.mebigfatguy.fbcontrib.utils.BugType; +import com.mebigfatguy.fbcontrib.utils.UnmodifiableSet; import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; @@ -61,12 +62,8 @@ synchClassMethods.put("java/util/Collections", syncMethods); } - private static final Set<String> selfReturningMethods = new HashSet<String>(); + private static final Set<String> selfReturningMethods = UnmodifiableSet.create("java/lang/StringBuffer.append"); - static { - selfReturningMethods.add("java/lang/StringBuffer.append"); - } - private BugReporter bugReporter; /** Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LoggerOddities.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LoggerOddities.java 2015-11-25 22:58:52 UTC (rev 1785) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LoggerOddities.java 2015-12-12 17:33:56 UTC (rev 1786) @@ -34,7 +34,6 @@ import com.mebigfatguy.fbcontrib.utils.BugType; import com.mebigfatguy.fbcontrib.utils.OpcodeUtils; -import com.mebigfat... [truncated message content] |