[Fb-contrib-commit] SF.net SVN: fb-contrib:[1800] trunk/fb-contrib
Brought to you by:
dbrosius
From: <dbr...@us...> - 2016-10-10 18:28:47
|
Revision: 1800 http://sourceforge.net/p/fb-contrib/code/1800 Author: dbrosius Date: 2016-10-10 18:28:44 +0000 (Mon, 10 Oct 2016) Log Message: ----------- sync from github Modified Paths: -------------- trunk/fb-contrib/.classpath trunk/fb-contrib/build.xml trunk/fb-contrib/etc/bugrank.txt trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/htdocs/index.shtml trunk/fb-contrib/htdocs/repository.html trunk/fb-contrib/pom.xml trunk/fb-contrib/samples/BRPI_Sample.java trunk/fb-contrib/samples/LEST_Sample.java trunk/fb-contrib/samples/samples.fbp trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/collect/CollectStatistics.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/collect/MethodInfo.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/AbnormalFinallyBlockReturn.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/AbstractCollectionScanningDetector.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ArrayBasedCollections.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BackportReusePublicIdentifiers.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BogusExceptionDeclaration.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BuryingLogic.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ClassEnvy.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CollectionNamingConfusion.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConstantListIndex.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ImmatureClass.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ListIndexedIterating.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LocalTypeDetector.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LoggerOddities.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LostExceptionStackTrace.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ParallelLists.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/StaticMethodInstanceInvocation.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/StringifiedTypes.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnrelatedCollectionContents.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/utils/BugType.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/utils/CollectionUtils.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/utils/FQMethod.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/utils/OpcodeUtils.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/utils/ToString.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/utils/Values.java trunk/fb-contrib/yank.xls Added Paths: ----------- trunk/fb-contrib/samples/CCI_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConcurrentCollectionIssues.java Modified: trunk/fb-contrib/.classpath =================================================================== --- trunk/fb-contrib/.classpath 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/.classpath 2016-10-10 18:28:44 UTC (rev 1800) @@ -34,5 +34,6 @@ <classpathentry kind="lib" path="lib/spring-beans-4.3.2.RELEASE.jar"/> <classpathentry kind="lib" path="lib/spring-tx-4.3.2.RELEASE.jar"/> <classpathentry kind="lib" path="lib/spring-context-4.3.2.RELEASE.jar"/> + <classpathentry kind="lib" path="lib/threetenbp-1.3.2.jar"/> <classpathentry kind="output" path="target/classes/main"/> </classpath> Modified: trunk/fb-contrib/build.xml =================================================================== --- trunk/fb-contrib/build.xml 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/build.xml 2016-10-10 18:28:44 UTC (rev 1800) @@ -28,7 +28,7 @@ <property name="javac.deprecation" value="on" /> <property name="javac.debug" value="on" /> - <property name="fb-contrib.version" value="6.6.3" /> + <property name="fb-contrib.version" value="6.9.0-SNAPSHOT" /> <property name="sonatype.dir" value="${user.home}/.fb-contrib-${fb-contrib.version}-sonatype" /> @@ -103,6 +103,7 @@ <pathelement location="${lib.dir}/commons-lang3-${commons-lang3.version}.jar" /> <pathelement location="${lib.dir}/commons-io-${commons-io.version}.jar" /> <pathelement location="${lib.dir}/backport-util-concurrent-${backport-util-concurrent.version}.jar" /> + <pathelement location="${lib.dir}/threetenbp-${threetenbp.version}.jar" /> <pathelement location="${lib.dir}/slf4j-api-${slf4j-api.version}.jar" /> <pathelement location="${lib.dir}/guava-${guava.version}.jar" /> <pathelement location="${lib.dir}/httpclient-cache-${httpclient-cache.version}.jar" /> Modified: trunk/fb-contrib/etc/bugrank.txt =================================================================== --- trunk/fb-contrib/etc/bugrank.txt 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/etc/bugrank.txt 2016-10-10 18:28:44 UTC (rev 1800) @@ -15,6 +15,7 @@ +0 BugPattern CAO_CONFUSING_AUTOBOXED_OVERLOADING +0 BugPattern CBC_CONTAINS_BASED_CONDITIONAL +0 BugPattern CBX_CUSTOM_BUILT_XML ++0 BugPattern CCI_CONCURRENT_COLLECTION_ISSUES_USE_PUT_IS_RACY +0 BugPattern CCNE_COMPARE_CLASS_EQUALS_NAME +2 BugPattern CC_CYCLOMATIC_COMPLEXITY +0 BugPattern CEBE_COMMONS_EQUALS_BUILDER_ISEQUALS Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/etc/findbugs.xml 2016-10-10 18:28:44 UTC (rev 1800) @@ -20,7 +20,7 @@ <!-- Detectors --> -<!-- COMMENT OUT FOR RELEASE +<!-- COMMENT OUT FOR RELEASE --> <Detector class="com.mebigfatguy.fbcontrib.debug.OCSDebugger" speed="fast"/> @@ -30,7 +30,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" /> @@ -296,17 +296,18 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.SuboptimalExpressionOrder" speed="fast" reports="SEO_SUBOPTIMAL_EXPRESSION_ORDER"/> <Detector class="com.mebigfatguy.fbcontrib.detect.IOIssues" speed="fast" reports="IOI_DOUBLE_BUFFER_COPY,IOI_COPY_WITH_READER"/> - - <!-- COMMENT OUT FOR POINT RELEASE - + <Detector class="com.mebigfatguy.fbcontrib.detect.DubiousMapCollection" speed="fast" reports="DMC_DUBIOUS_MAP_COLLECTION"/> <Detector class="com.mebigfatguy.fbcontrib.detect.BuryingLogic" speed="fast" reports="BL_BURYING_LOGIC"/> <Detector class="com.mebigfatguy.fbcontrib.detect.WiringIssues" speed="fast" reports="WI_DUPLICATE_WIRED_TYPES"/> - COMMENT OUT FOR POINT RELEASE --> + <Detector class="com.mebigfatguy.fbcontrib.detect.ConcurrentCollectionIssues" speed="fast" reports="CCI_CONCURRENT_COLLECTION_ISSUES_USE_PUT_IS_RACY"/> + <!-- COMMENT OUT FOR POINT RELEASE --> + <!-- COMMENT OUT FOR POINT RELEASE --> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -569,8 +570,8 @@ <BugPattern abbrev="SEO" type="SEO_SUBOPTIMAL_EXPRESSION_ORDER" category="PERFORMANCE"/> <BugPattern abbrev="IOI" type="IOI_DOUBLE_BUFFER_COPY" category="PERFORMANCE"/> <BugPattern abbrev="IOI" type="IOI_COPY_WITH_READER" category="PERFORMANCE"/> - <BugPattern abbrev="DMC" type="DMC_DUBIOUS_MAP_COLLECTION" category="CORRECTNESS" experimental="true"/> - <BugPattern abbrev="BL" type="BL_BURYING_LOGIC" category="STYLE" experimental="true" /> - <BugPattern abbrev="WI" type="WI_DUPLICATE_WIRED_TYPES" category="CORRECTNESS" experimental="true"/> - + <BugPattern abbrev="DMC" type="DMC_DUBIOUS_MAP_COLLECTION" category="CORRECTNESS"/> + <BugPattern abbrev="BL" type="BL_BURYING_LOGIC" category="STYLE"/> + <BugPattern abbrev="WI" type="WI_DUPLICATE_WIRED_TYPES" category="CORRECTNESS"/> + <BugPattern abbrev="CCI" type="CCI_CONCURRENT_COLLECTION_ISSUES_USE_PUT_IS_RACY" category="CORRECTNESS"/> </FindbugsPlugin> Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/etc/messages.xml 2016-10-10 18:28:44 UTC (rev 1800) @@ -1276,9 +1276,9 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.BackportReusePublicIdentifiers"> <Details> <![CDATA[ - <p>Detects use of Backport Utils concurrent classes. Updated/efficient versions of these - classes are available in versions of the JDK 5.0 and higher, and these - classes should only be used if you are targeting JDK 1.4 and lower.</p> + <p>Detects use of Backport Utils concurrent classes from Emory, or Time classes from ThreeTen. Updated/efficient versions of + classes from emory are available in versions of the JDK 5.0 and higher, and in JDK 8.0 and higher for ThreeTen, and these + classes should only be used if you are targeting a JDK lower than this.</p> <p>It is a fast detector.</p> ]]> </Details> @@ -1628,6 +1628,15 @@ ]]> </Details> </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.ConcurrentCollectionIssues"> + <Details> + <![CDATA[ + <p>Looks for problems with using concurrent collecctions</p> + <p>It is a fast detector.</p> + ]]> + </Details> + </Detector> <Detector class="com.mebigfatguy.fbcontrib.debug.OCSDebugger"> <Details></Details> @@ -4704,13 +4713,14 @@ </BugPattern> <BugPattern type="BRPI_BACKPORT_REUSE_PUBLIC_IDENTIFIERS"> - <ShortDescription>Method uses backport concurrency utils</ShortDescription> - <LongDescription>Method {1} backport concurrency utils</LongDescription> + <ShortDescription>Method uses backported libraries that are now built in</ShortDescription> + <LongDescription>Method {1} uses backported libraries that are now built in</LongDescription> <Details> <![CDATA[ - <p>This class uses Backport Utils concurrent classes. Updated/Efficient version of these - classes are available in versions of the JDK 5.0 and higher, and these - classes should only be used if you are targeting JDK 1.4 and lower.</p> + <p>This class uses either Backport Utils concurrent classes from Emory, or Time classes from ThreeTen Backport. + Updated/Efficient version of these classes are available in the version of the JDK that this code is compiled against; + JDK 1.5 for the concurrent classes, and JDK 1.8 for the time classes, and these + classes should only be used if you are targeting a JDK lower than this.</p> ]]> </Details> </BugPattern> @@ -5550,9 +5560,10 @@ <LongDescription>Method {1} buries logic to the right (indented) more than it needs to be</LongDescription> <Details> <![CDATA[ - <p>This method has an if statement where if the condition is false, it merely returns. The bulk of the logic - is found in the if brace code. This unnecessarily obfuscates the logic of the method. It would be more readable - if you inverted the logic of the if statement, and just returned if true.</p> + <p>Looks for relatively large if blocks of code, where you unconditionally return from them, and then follow that with an unconditional + return of a small block. This places the bulk of the logic to the right indentation-wise, making it more difficult to read than needed. + It would be better to invert the logic of the if block, and immediately return, allowing the bulk of the logic to be move to the left, + for easier reading.</p> ]]> </Details> </BugPattern> @@ -5568,6 +5579,22 @@ ]]> </Details> </BugPattern> + + <BugPattern type="CCI_CONCURRENT_COLLECTION_ISSUES_USE_PUT_IS_RACY"> + <ShortDescription>Method gets and sets a value of a ConcurrentHashMap in a racy manner</ShortDescription> + <LongDescription>Method {1} gets and sets a value of a ConcurrentHashMap in a racy manner </LongDescription> + <Details> + <![CDATA[ + <p>This method retrieves the value of a key from a ConcurrentHashMap, where the value is itself a collection. It checks this + value for null, and if it is so, creates a new collection and places in the map. This may cause thread race conditions + where two threads overwrite each other's values. You should be using + <code> + ConcurrentHashMap.putIfAbsent(K, V) + </code> + instead. + ]]> + </Details> + </BugPattern> <!-- BugCode --> @@ -5705,4 +5732,5 @@ <BugCode abbrev="DMC">Dubious Map Collection</BugCode> <BugCode abbrev="BL">Burying Logic</BugCode> <BugCode abbrev="WI">Wiring issues</BugCode> + <BugCode abbrev="CCI">Concurrent Collection Issues</BugCode> </MessageCollection> Modified: trunk/fb-contrib/htdocs/index.shtml =================================================================== --- trunk/fb-contrib/htdocs/index.shtml 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/htdocs/index.shtml 2016-10-10 18:28:44 UTC (rev 1800) @@ -68,7 +68,7 @@ </li> </ul> </p> - <p style="font-weight: bold;">The latest version of fb-contrib is 6.6.3 available for download + <p style="font-weight: bold;">The latest version of fb-contrib is 6.8.0 available for download <a href="http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22fb-contrib%22">here</a>.</p> <p style="font-weight: bold;">This version requires FindBugs 3.0.1 or better</p> <p style="font-weight: bold;">Please note that active development for this project is now done on @@ -81,6 +81,14 @@ Detectors added in git<br/> <div id="git" style="display:none;"> <ul> + <li>--none yet--</li> + </ul> + </div> + <hr/> + <img id="git_image" src="flip2.gif" onClick="toggleBlock('v6_8_0', 'v6_8_0_image');" align="top"/> + Detectors added in v6.8.0<br/> + <div id="v6_8_0" style="display:block;"> + <ul> <li><b>[DMC] Dubious Map Collection</b><br/> Looks for fields that are implementations of java.util.Map, but that are only ever iterated over. This probably means that this data structure should be a List of some class that holds two values, or at the least Pair. Map was probably choosen as it was the @@ -95,14 +103,21 @@ <li><b>[WI] Wiring Issues</b><br/> Looks for various issues around @Autowired/@Inject fields in DI classes <ul> - <li>Injecting the same bean twice into the same class hierarchy, even with different field names</li> + <li>Injecting the same bean twice into the same class hierarchy, even with different field names</li> + </ul> </li> + <li><b>[CCI] Concurrent Collection Issues</b><br/> + Looks for various issues around using concurrent collections including + <ul> + <li>Using get/put with collection values, when you should use putIfAbsent</li> + </ul> + </li> </ul> </div> <hr/> - <img id="git_image" src="flip2.gif" onClick="toggleBlock('v6_6_0', 'v6_6_0_image');" align="top"/> + <img id="git_image" src="flip1.gif" onClick="toggleBlock('v6_6_0', 'v6_6_0_image');" align="top"/> Detectors added in v6.6.0<br/> - <div id="v6_6_0" style="display:block;"> + <div id="v6_6_0" style="display:none;"> <ul> <li><b>[STB] Stacked Try Blocks</b><br/> Looks for two or more try catch blocks that are consecutive and catch the @@ -148,7 +163,7 @@ </ul> </div> <hr/> - <img id="v6_2_0_image" src="flip2.gif" onClick="toggleBlock('v6_2_0', 'v6_2_0_image');" align="top"/> + <img id="v6_2_0_image" src="flip1.gif" onClick="toggleBlock('v6_2_0', 'v6_2_0_image');" align="top"/> Detectors added in v6.2.0<br/> <div id="v6_2_0" style="display:none;"> <ul> Modified: trunk/fb-contrib/htdocs/repository.html =================================================================== --- trunk/fb-contrib/htdocs/repository.html 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/htdocs/repository.html 2016-10-10 18:28:44 UTC (rev 1800) @@ -22,7 +22,7 @@ <table style="margin-left: 40px; background-color: #A0A0FF; padding: 20px; border-width: 1px; border-style: outset; border-color: #000000;"> <tr><td><b>GroupId:</b></td><td>com.mebigfatguy.fb-contrib</td></tr> <tr><td><b>ArtifactId:</b></td><td>fb-contrib</td></tr> - <tr><td><b>Version:</b></td><td>6.6.3</td></tr> + <tr><td><b>Version:</b></td><td>6.8.0</td></tr> </table> </div> Modified: trunk/fb-contrib/pom.xml =================================================================== --- trunk/fb-contrib/pom.xml 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/pom.xml 2016-10-10 18:28:44 UTC (rev 1800) @@ -8,7 +8,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>com.mebigfatguy.fb-contrib</groupId> <artifactId>fb-contrib</artifactId> - <version>6.6.3</version> + <version>6.9.0-SNAPSHOT</version> <prerequisites> <maven>2.2.1</maven> @@ -173,6 +173,12 @@ <version>4.3.2.RELEASE</version> <scope>test</scope> </dependency> + <dependency> + <groupId>org.threeten</groupId> + <artifactId>threetenbp</artifactId> + <version>1.3.2</version> + <scope>test</scope> + </dependency> </dependencies> <build> Modified: trunk/fb-contrib/samples/BRPI_Sample.java =================================================================== --- trunk/fb-contrib/samples/BRPI_Sample.java 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/samples/BRPI_Sample.java 2016-10-10 18:28:44 UTC (rev 1800) @@ -1,3 +1,6 @@ + +import org.threeten.bp.LocalDate; + import edu.emory.mathcs.backport.java.util.Collections; import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap; import edu.emory.mathcs.backport.java.util.concurrent.Executors; @@ -3,8 +6,12 @@ public class BRPI_Sample { - public static void main(String[] arg) { + public void emory() { Collections.emptySet(); Executors.newCachedThreadPool(); new ConcurrentHashMap(); } + + public void threeten() { + LocalDate d = LocalDate.now(); + } } Added: trunk/fb-contrib/samples/CCI_Sample.java =================================================================== --- trunk/fb-contrib/samples/CCI_Sample.java (rev 0) +++ trunk/fb-contrib/samples/CCI_Sample.java 2016-10-10 18:28:44 UTC (rev 1800) @@ -0,0 +1,21 @@ +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +public class CCI_Sample { + + private Map<String, Set<String>> map = new ConcurrentHashMap<>(); + + public void update(String key, String value) { + + Set<String> values = map.get(key); + + if (values == null) { + values = Collections.<String> newSetFromMap(new ConcurrentHashMap<String, Boolean>()); + map.put(key, values); + } + + values.add(value); + } +} Property changes on: trunk/fb-contrib/samples/CCI_Sample.java ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Modified: trunk/fb-contrib/samples/LEST_Sample.java =================================================================== --- trunk/fb-contrib/samples/LEST_Sample.java 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/samples/LEST_Sample.java 2016-10-10 18:28:44 UTC (rev 1800) @@ -149,4 +149,14 @@ private static Exception wrapStatic(Exception e) { return new Exception(e); } + + public void testFPSuppressedLest(String s) { + try { + double d = Double.parseDouble(s); + } catch (NumberFormatException e) { + RuntimeException r = new RuntimeException(); + r.addSuppressed(e); + throw r; + } + } } Modified: trunk/fb-contrib/samples/samples.fbp =================================================================== --- trunk/fb-contrib/samples/samples.fbp 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/samples/samples.fbp 2016-10-10 18:28:44 UTC (rev 1800) @@ -1,23 +1,24 @@ <Project projectName="sample"> - <Jar>././../target/classes/samples</Jar> - <AuxClasspathEntry>././../lib/backport-util-concurrent-3.1.jar</AuxClasspathEntry> - <AuxClasspathEntry>././../lib/commons-collections-3.2.1.jar</AuxClasspathEntry> - <AuxClasspathEntry>././../lib/javax.servlet-api-3.1.0.jar</AuxClasspathEntry> - <AuxClasspathEntry>././../lib/javax.servlet.jsp-api-2.3.1.jar</AuxClasspathEntry> - <AuxClasspathEntry>././../lib/log4j-1.2.17.jar</AuxClasspathEntry> - <AuxClasspathEntry>././../lib/commons-lang3-3.3.jar</AuxClasspathEntry> - <AuxClasspathEntry>././../lib/slf4j-api-1.7.7.jar</AuxClasspathEntry> - <AuxClasspathEntry>././../lib/guava-17.0.jar</AuxClasspathEntry> - <AuxClasspathEntry>././../lib/httpclient-4.3.4.jar</AuxClasspathEntry> - <AuxClasspathEntry>././../lib/httpclient-cache-4.3.4.jar</AuxClasspathEntry> - <AuxClasspathEntry>././../lib/httpcore-4.3.2.jar</AuxClasspathEntry> - <AuxClasspathEntry>././../lib/commons-codec-1.6.jar</AuxClasspathEntry> - <AuxClasspathEntry>././../lib/commons-io-1.3.2.jar</AuxClasspathEntry> - <AuxClasspathEntry>././../lib/junit-4.12.jar</AuxClasspathEntry> - <AuxClasspathEntry>././../lib/testng-6.9.6.jar</AuxClasspathEntry> - <AuxClasspathEntry>././../lib/jsr311-api-1.1.1.jar</AuxClasspathEntry> - <AuxClasspathEntry>././../lib/javax.persistence-2.1.1.jar</AuxClasspathEntry> - <AuxClasspathEntry>./../lib/mockito-all-2.0.2-beta.jar</AuxClasspathEntry> - <AuxClasspathEntry>../lib/asm-debug-all-5.0.2.jar</AuxClasspathEntry> - <SrcDir>./././.</SrcDir> + <Jar>./././../target/classes/samples</Jar> + <AuxClasspathEntry>./././../lib/backport-util-concurrent-3.1.jar</AuxClasspathEntry> + <AuxClasspathEntry>./././../lib/commons-collections-3.2.1.jar</AuxClasspathEntry> + <AuxClasspathEntry>./././../lib/javax.servlet-api-3.1.0.jar</AuxClasspathEntry> + <AuxClasspathEntry>./././../lib/javax.servlet.jsp-api-2.3.1.jar</AuxClasspathEntry> + <AuxClasspathEntry>./././../lib/log4j-1.2.17.jar</AuxClasspathEntry> + <AuxClasspathEntry>./././../lib/commons-lang3-3.3.jar</AuxClasspathEntry> + <AuxClasspathEntry>./././../lib/slf4j-api-1.7.7.jar</AuxClasspathEntry> + <AuxClasspathEntry>./././../lib/guava-17.0.jar</AuxClasspathEntry> + <AuxClasspathEntry>./././../lib/httpclient-4.3.4.jar</AuxClasspathEntry> + <AuxClasspathEntry>./././../lib/httpclient-cache-4.3.4.jar</AuxClasspathEntry> + <AuxClasspathEntry>./././../lib/httpcore-4.3.2.jar</AuxClasspathEntry> + <AuxClasspathEntry>./././../lib/commons-codec-1.6.jar</AuxClasspathEntry> + <AuxClasspathEntry>./././../lib/commons-io-1.3.2.jar</AuxClasspathEntry> + <AuxClasspathEntry>./././../lib/junit-4.12.jar</AuxClasspathEntry> + <AuxClasspathEntry>./././../lib/testng-6.9.6.jar</AuxClasspathEntry> + <AuxClasspathEntry>./././../lib/jsr311-api-1.1.1.jar</AuxClasspathEntry> + <AuxClasspathEntry>./././../lib/javax.persistence-2.1.1.jar</AuxClasspathEntry> + <AuxClasspathEntry>././../lib/mockito-all-2.0.2-beta.jar</AuxClasspathEntry> + <AuxClasspathEntry>./../lib/asm-debug-all-5.0.2.jar</AuxClasspathEntry> + <AuxClasspathEntry>../lib/threetenbp-1.3.2.jar</AuxClasspathEntry> + <SrcDir>././././.</SrcDir> </Project> Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/collect/CollectStatistics.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/collect/CollectStatistics.java 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/collect/CollectStatistics.java 2016-10-10 18:28:44 UTC (rev 1800) @@ -40,6 +40,9 @@ import edu.umd.cs.findbugs.OpcodeStack; import edu.umd.cs.findbugs.ba.ClassContext; +/** + * a first pass detector to collect various statistics used in second pass detectors. + */ public class CollectStatistics extends BytecodeScanningDetector implements NonReportingDetector { private static final Set<String> COMMON_METHOD_SIGS = UnmodifiableSet.create( //@formatter:off @@ -59,10 +62,22 @@ private Map<QMethod, Set<CalledMethod>> selfCallTree; private QMethod curMethod; + /** + * constructs a CollectStatistics detector which clears the singleton that holds the statistics for all classes parsed in the first pass. + * + * @param bugReporter + * unused, but required by reflection contract + */ public CollectStatistics(@SuppressWarnings("unused") BugReporter bugReporter) { Statistics.getStatistics().clear(); } + /** + * implements the visitor to collect statistics on this class + * + * @param classContext + * the currently class + */ @Override public void visitClassContext(ClassContext classContext) { try { @@ -227,6 +242,9 @@ return (annotations != null) && (annotations.length > 0); } + /** + * represents a method that is called, and whether it is in the super class + */ static class CalledMethod { private QMethod callee; private boolean isSuper; Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/collect/MethodInfo.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/collect/MethodInfo.java 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/collect/MethodInfo.java 2016-10-10 18:28:44 UTC (rev 1800) @@ -22,6 +22,9 @@ import com.mebigfatguy.fbcontrib.utils.ToString; +/** + * represents statistics including attributes, mutability and sizes of a method + */ public class MethodInfo { public static final int PUBLIC_USE = 1; Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/AbnormalFinallyBlockReturn.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/AbnormalFinallyBlockReturn.java 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/AbnormalFinallyBlockReturn.java 2016-10-10 18:28:44 UTC (rev 1800) @@ -162,7 +162,7 @@ bugReporter.reportBug(new BugInstance(this, BugType.AFBR_ABNORMAL_FINALLY_BLOCK_RETURN.name(), NORMAL_PRIORITY).addClass(this).addMethod(this) .addSourceLine(this)); removeEarliestFinallyBlock(); - } else if (OpcodeUtils.isInvoke(seen)) { + } else if (OpcodeUtils.isStandardInvoke(seen)) { try { JavaClass cls = Repository.lookupClass(getClassConstantOperand()); Method m = findMethod(cls, getNameConstantOperand(), getSigConstantOperand()); Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/AbstractCollectionScanningDetector.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/AbstractCollectionScanningDetector.java 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/AbstractCollectionScanningDetector.java 2016-10-10 18:28:44 UTC (rev 1800) @@ -27,6 +27,9 @@ import edu.umd.cs.findbugs.OpcodeStack; import edu.umd.cs.findbugs.ba.ClassContext; +/** + * a base detector class for when you need to precess collections, provides methods for checking collection attributes + */ public class AbstractCollectionScanningDetector extends BytecodeScanningDetector { protected final JavaClass collectionClass; protected final BugReporter bugReporter; @@ -52,6 +55,7 @@ * @param classContext * the context object of the currently parsed class */ + @Override public void visitClassContext(ClassContext classContext) { if (collectionClass == null) { if (ex != null) { Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ArrayBasedCollections.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ArrayBasedCollections.java 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ArrayBasedCollections.java 2016-10-10 18:28:44 UTC (rev 1800) @@ -65,8 +65,8 @@ public void visitClassContext(ClassContext classContext) { try { stack = new OpcodeStack(); - mapBugs = new ArrayList<BugInstance>(); - setBugs = new ArrayList<BugInstance>(); + mapBugs = new ArrayList<>(); + setBugs = new ArrayList<>(); hasMapComparator = false; hasSetComparator = false; super.visitClassContext(classContext); @@ -147,7 +147,7 @@ found = true; } } - } else if ("java/util/List".equals(className) && "contains".equals(methodName) && "(Ljava/lang/Object;)Z".equals(methodSig) + } else if (Values.SLASHED_JAVA_UTIL_LIST.equals(className) && "contains".equals(methodName) && "(Ljava/lang/Object;)Z".equals(methodSig) && (stack.getStackDepth() > 0)) { OpcodeStack.Item itm = stack.getStackItem(0); String pushedSig = itm.getSignature(); Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BackportReusePublicIdentifiers.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BackportReusePublicIdentifiers.java 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BackportReusePublicIdentifiers.java 2016-10-10 18:28:44 UTC (rev 1800) @@ -19,10 +19,15 @@ */ package com.mebigfatguy.fbcontrib.detect; +import java.util.List; + import org.apache.bcel.Constants; import org.apache.bcel.classfile.JavaClass; +import com.mebigfatguy.fbcontrib.detect.BackportReusePublicIdentifiers.Backports.Library; import com.mebigfatguy.fbcontrib.utils.BugType; +import com.mebigfatguy.fbcontrib.utils.ToString; +import com.mebigfatguy.fbcontrib.utils.UnmodifiableList; import com.mebigfatguy.fbcontrib.utils.Values; import edu.umd.cs.findbugs.BugInstance; @@ -31,14 +36,25 @@ import edu.umd.cs.findbugs.bcel.OpcodeStackDetector; /** - * Detects use of Backport concurrent classes. Updated/Efficient version of these classes are available in versions of the JDK 5.0 and higher, and these classes - * should only be used if you are targeting JDK 1.4 and lower. - * - * Finds usage of classes from backport utils package. + * Detects use of backport libraries, when the code in question is compiled in a jdk that has the functionality available. Libraries include: + * <ul> + * <li>Use of Backport concurrent classes. Updated/Efficient version of these classes are available in versions of the JDK 1.5 and higher, and these classes + * should only be used if you are targeting JDK 1.4 and lower.</li> + * <li>Use of ThreeTen time backport classes, instead of java.time packages which are now available in JDK 1.8 and higher, and these classes should only be used + * if you are targeting JDK 1.7 and lower + * </ul> */ public class BackportReusePublicIdentifiers extends OpcodeStackDetector { + private static final List<Backports> BACKPORTS = UnmodifiableList.create( + // @formatter:off + new Backports("edu/emory/mathcs/backport/", Constants.MAJOR_1_5, Library.EMORY), + new Backports("org/threeten/bp/", Constants.MAJOR_1_8, Library.THREETEN) + // @formatter:on + ); + private final BugReporter bugReporter; + private int clsVersion; /** * constructs a BRPI detector given the reporter to report bugs on @@ -59,13 +75,13 @@ @Override public void visitClassContext(ClassContext classContext) { JavaClass cls = classContext.getJavaClass(); - if (cls.getMajor() >= Constants.MAJOR_1_5) { - super.visitClassContext(classContext); - } + clsVersion = cls.getMajor(); + super.visitClassContext(classContext); } /** - * overrides the visitor to look for method calls to the emory backport concurrent library when the now built in versions are available + * overrides the visitor to look for method calls to the emory backport concurrent library, or threeten bp library when the now built-in versions are + * available * * @param seen * the currently parsed opcode @@ -77,8 +93,13 @@ switch (seen) { case INVOKESTATIC: { String className = getClassConstantOperand(); - if (className.startsWith("edu/emory/mathcs/backport/")) { - reportBug(); + for (Backports backport : BACKPORTS) { + if (className.startsWith(backport.getPathPrefix())) { + if (clsVersion >= backport.getMinimumJDK()) { + reportBug(backport.getLibrary()); + break; + } + } } } break; @@ -86,11 +107,19 @@ case INVOKESPECIAL: { String className = getClassConstantOperand(); String methodName = getNameConstantOperand(); - if (className.startsWith("edu/emory/mathcs/backport/") && Values.CONSTRUCTOR.equals(methodName)) { - reportBug(); + for (Backports backport : BACKPORTS) { + if (Values.CONSTRUCTOR.equals(methodName)) { + if (className.startsWith(backport.getPathPrefix())) { + if (clsVersion >= backport.getMinimumJDK()) { + reportBug(backport.getLibrary()); + break; + } + } + } } } break; + default: break; } @@ -98,9 +127,51 @@ /** * issues a new bug at this location + * + * @param library + * the type of backport library that is in use */ - private void reportBug() { + private void reportBug(Library library) { bugReporter.reportBug(new BugInstance(this, BugType.BRPI_BACKPORT_REUSE_PUBLIC_IDENTIFIERS.name(), NORMAL_PRIORITY).addClass(this).addMethod(this) - .addSourceLine(this)); + .addSourceLine(this).addString(library.name())); } + + /** + * describes a library that is a backport of a package that is now included in the jdk by default + */ + static class Backports { + + enum Library { + EMORY, THREETEN + }; + + private String pathPrefix; + private int minimumJDK; + private Library library; + + public Backports(String pathPrefix, int minimumJDK, Library library) { + super(); + this.pathPrefix = pathPrefix; + this.minimumJDK = minimumJDK; + this.library = library; + } + + public String getPathPrefix() { + return pathPrefix; + } + + public int getMinimumJDK() { + return minimumJDK; + } + + public Library getLibrary() { + return library; + } + + @Override + public String toString() { + return ToString.build(this); + } + + } } Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BogusExceptionDeclaration.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BogusExceptionDeclaration.java 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BogusExceptionDeclaration.java 2016-10-10 18:28:44 UTC (rev 1800) @@ -221,7 +221,7 @@ stack.precomputation(this); - if (OpcodeUtils.isInvoke(seen)) { + if (OpcodeUtils.isStandardInvoke(seen)) { String clsName = getClassConstantOperand(); if (!safeClasses.contains(clsName)) { try { Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BuryingLogic.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BuryingLogic.java 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BuryingLogic.java 2016-10-10 18:28:44 UTC (rev 1800) @@ -209,7 +209,7 @@ .addClass(this).addMethod(this).addSourceLineRange(this, activeUnconditional.getStart(), activeUnconditional.getEnd())); throw new StopOpcodeParsingException(); } - } else if (!ifBlocks.isEmpty() && (getNextPC() == ifBlocks.getFirst().getEnd())) { + } else if (!ifBlocks.isEmpty() && (getNextPC() == ifBlocks.getFirst().getEnd()) && !gotoAcrossPC(getNextPC())) { activeUnconditional = ifBlocks.getFirst(); } } else if ((seen == TABLESWITCH) || (seen == LOOKUPSWITCH)) { @@ -224,6 +224,12 @@ } } + private boolean gotoAcrossPC(int pc) { + + int target = gotoBranchPCs.previousSetBit(Integer.MAX_VALUE); + return (target > pc); + } + /** * determines if this opcode couldn't be part of a conditional expression or at least is very unlikely to be so. * @@ -254,6 +260,9 @@ } } + /** + * represents the byte offset code range of code that is executed inside an if block + */ static class IfBlock { private int start; private int end; Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ClassEnvy.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ClassEnvy.java 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ClassEnvy.java 2016-10-10 18:28:44 UTC (rev 1800) @@ -144,7 +144,7 @@ return; } - clsAccessCount = new HashMap<String, BitSet>(); + clsAccessCount = new HashMap<>(); super.visitCode(obj); if (clsAccessCount.size() > 0) { @@ -182,7 +182,7 @@ try { stack.precomputation(this); - if (OpcodeUtils.isInvoke(seen)) { + if (OpcodeUtils.isStandardInvoke(seen)) { String calledClass = getClassConstantOperand().replace('/', '.'); if (seen == INVOKEINTERFACE) { Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CollectionNamingConfusion.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CollectionNamingConfusion.java 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CollectionNamingConfusion.java 2016-10-10 18:28:44 UTC (rev 1800) @@ -29,6 +29,7 @@ import com.mebigfatguy.fbcontrib.utils.BugType; import com.mebigfatguy.fbcontrib.utils.SignatureUtils; +import com.mebigfatguy.fbcontrib.utils.Values; import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; @@ -50,7 +51,7 @@ try { MAP_CLASS = Repository.lookupClass("java/util/Map"); SET_CLASS = Repository.lookupClass("java/util/Set"); - LIST_CLASS = Repository.lookupClass("java/util/List"); + LIST_CLASS = Repository.lookupClass(Values.SLASHED_JAVA_UTIL_LIST); QUEUE_CLASS = Repository.lookupClass("java/util/Queue"); } catch (ClassNotFoundException cnfe) { MAP_CLASS = null; Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConcurrentCollectionIssues.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConcurrentCollectionIssues.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConcurrentCollectionIssues.java 2016-10-10 18:28:44 UTC (rev 1800) @@ -0,0 +1,194 @@ +/* + * fb-contrib - Auxiliary detectors for Java programs + * Copyright (C) 2005-2016 Bhaskar Maddala + * Copyright (C) 2005-2016 Dave Brosius + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package com.mebigfatguy.fbcontrib.detect; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.bcel.Repository; +import org.apache.bcel.classfile.Code; +import org.apache.bcel.classfile.JavaClass; + +import com.mebigfatguy.fbcontrib.utils.BugType; + +import edu.umd.cs.findbugs.BugInstance; +import edu.umd.cs.findbugs.BugReporter; +import edu.umd.cs.findbugs.BytecodeScanningDetector; +import edu.umd.cs.findbugs.OpcodeStack; +import edu.umd.cs.findbugs.OpcodeStack.CustomUserValue; +import edu.umd.cs.findbugs.ba.ClassContext; + +/** + * looks for various issues with concurrent collections including + * <ul> + * <li>calls to checking and inserting a collection into a key on null, instead of using putIfAbsent</li> + * </ul> + */ +@CustomUserValue +public class ConcurrentCollectionIssues extends BytecodeScanningDetector { + + private final BugReporter bugReporter; + private JavaClass collectionClass; + private JavaClass mapClass; + private OpcodeStack stack; + private Map<String, CCIUserValue> fieldUserValues; + private int endNullCheckPC; + + private enum CCIUserValue { + CONCURRENT_HASHMAP, CONCURRENT_HASHMAP_VALUE; + }; + + /** + * constructs a CCI detector given the reporter to report bugs on + * + * @param bugReporter + * the sync of bug reports + */ + public ConcurrentCollectionIssues(final BugReporter bugReporter) { + this.bugReporter = bugReporter; + + try { + collectionClass = Repository.lookupClass("java/util/Collection"); + mapClass = Repository.lookupClass("java/util/Map"); + } catch (ClassNotFoundException e) { + bugReporter.reportMissingClass(e); + } + } + + /** + * overrides the visitor to initialize the opcode stack + * + * @param classContext + * the currently parsed class + */ + @Override + public void visitClassContext(ClassContext classContext) { + + try { + if ((collectionClass == null) || (mapClass == null)) { + return; + } + stack = new OpcodeStack(); + fieldUserValues = new HashMap<>(); + classContext.getJavaClass().accept(this); + } finally { + fieldUserValues = null; + stack = null; + } + } + + /** + * implements the visitor to see if reset the opcode stack + * + * @param obj + * the context object of the currently parsed code block + */ + @Override + public void visitCode(Code obj) { + stack.resetForMethodEntry(this); + endNullCheckPC = -1; + + super.visitCode(obj); + } + + /** + * implements the visitor to look for concurrent collection issue + */ + @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "SF_SWITCH_NO_DEFAULT", justification = "We don't need or want to handle every opcode") + @Override + public void sawOpcode(int seen) { + CCIUserValue userValue = null; + try { + stack.precomputation(this); + + switch (seen) { + case INVOKESPECIAL: + if ("java/util/concurrent/ConcurrentHashMap".equals(getClassConstantOperand()) && "<init>".equals(getNameConstantOperand())) { + userValue = CCIUserValue.CONCURRENT_HASHMAP; + } + break; + + case INVOKEINTERFACE: + case INVOKEVIRTUAL: + if ("get".equals(getNameConstantOperand())) { + if (stack.getStackDepth() >= 2) { + OpcodeStack.Item itm = stack.getStackItem(1); + if (itm.getUserValue() == CCIUserValue.CONCURRENT_HASHMAP) { + userValue = CCIUserValue.CONCURRENT_HASHMAP_VALUE; + } + } + } else if ("put".equals(getNameConstantOperand()) && (endNullCheckPC > getPC()) && (stack.getStackDepth() >= 3)) { + OpcodeStack.Item mapItem = stack.getStackItem(2); + + if (mapItem.getUserValue() == CCIUserValue.CONCURRENT_HASHMAP) { + OpcodeStack.Item valueItem = stack.getStackItem(0); + JavaClass valueClass = valueItem.getJavaClass(); + if ((valueClass != null) && (valueClass.instanceOf(collectionClass) || valueClass.instanceOf(mapClass))) { + + bugReporter.reportBug(new BugInstance(this, BugType.CCI_CONCURRENT_COLLECTION_ISSUES_USE_PUT_IS_RACY.name(), NORMAL_PRIORITY) + .addClass(this).addMethod(this).addSourceLine(this)); + } + } + } + break; + + case PUTFIELD: + case PUTSTATIC: + if (stack.getStackDepth() >= 1) { + OpcodeStack.Item itm = stack.getStackItem(0); + CCIUserValue uv = (CCIUserValue) itm.getUserValue(); + if (uv != null) { + fieldUserValues.put(getNameConstantOperand(), uv); + } else { + fieldUserValues.remove(getNameConstantOperand()); + } + } + break; + + case GETFIELD: + case GETSTATIC: + userValue = fieldUserValues.get(getNameConstantOperand()); + break; + + case IFNONNULL: + if ((getBranchOffset() > 0) && (stack.getStackDepth() > 0)) { + OpcodeStack.Item itm = stack.getStackItem(0); + if (itm.getUserValue() == CCIUserValue.CONCURRENT_HASHMAP_VALUE) { + endNullCheckPC = getBranchTarget(); + } + } + break; + } + + } catch (ClassNotFoundException e) { + bugReporter.reportMissingClass(e); + } finally { + stack.sawOpcode(this, seen); + if ((userValue != null) && (stack.getStackDepth() > 0)) { + OpcodeStack.Item itm = stack.getStackItem(0); + itm.setUserValue(userValue); + } + + if (getPC() >= endNullCheckPC) { + endNullCheckPC = -1; + } + } + } +} Property changes on: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConcurrentCollectionIssues.java ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConstantListIndex.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConstantListIndex.java 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConstantListIndex.java 2016-10-10 18:28:44 UTC (rev 1800) @@ -189,7 +189,7 @@ break; case INVOKEVIRTUAL: - if ("java/util/List".equals(getClassConstantOperand())) { + if (Values.SLASHED_JAVA_UTIL_LIST.equals(getClassConstantOperand())) { String methodName = getNameConstantOperand(); if ("get".equals(methodName)) { if (state == State.SAW_CONSTANT_0) { Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ImmatureClass.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ImmatureClass.java 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ImmatureClass.java 2016-10-10 18:28:44 UTC (rev 1800) @@ -119,11 +119,9 @@ */ @Override public void sawOpcode(int seen) { - if (seen == INVOKEVIRTUAL) { - if ("printStackTrace".equals(getNameConstantOperand()) && "()V".equals(getSigConstantOperand())) { - bugReporter.reportBug(new BugInstance(this, BugType.IMC_IMMATURE_CLASS_PRINTSTACKTRACE.name(), NORMAL_PRIORITY).addClass(this).addMethod(this) - .addSourceLine(this)); - } + if ((seen == INVOKEVIRTUAL) && "printStackTrace".equals(getNameConstantOperand()) && "()V".equals(getSigConstantOperand())) { + bugReporter.reportBug(new BugInstance(this, BugType.IMC_IMMATURE_CLASS_PRINTSTACKTRACE.name(), NORMAL_PRIORITY).addClass(this).addMethod(this) + .addSourceLine(this)); } } Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ListIndexedIterating.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ListIndexedIterating.java 2016-09-24 00:41:19 UTC (rev 1799) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ListIndexedIterating.java 2016-10-10 18:28:44 UTC (rev 1800) @@ -27,6 +27,8 @@ import org.apache.bcel.classfile.Code; import org.apache.bcel.classfile.Method; +import com.mebigfatguy.fbcontrib.utils.Values; + import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; import edu.umd.cs.findbugs.BytecodeScanningDetector; @@ -35,10 +37,8 @@ import edu.umd.cs.findbugs.ba.XField; /** - * looks for for loops that iterate over a java.util.List using an integer - * index, and get, rather than using an Iterator. An iterator may perform better - * depending List implementation, but more importantly will allow the code to be - * converted to other collections type. + * looks for for loops that iterate over a java.util.List using an integer index, and get, rather than using an Iterator. An iterator may perform better + * depending List implementation, but more importantly will allow the code to be converted to other collections type. */ public class ListIndexedIterating extends BytecodeScanningDetector { enum State { @@ -81,7 +81,7 @@ public void visitClassContext(ClassContext classContext) { try { stack = new OpcodeStack(); - possibleForLoops = new HashSet<ForLoop>(); + possibleForLoops = new HashSet<>(); super.visitClassContext(classContext); } finally { stack = null; @@ -135,10 +135,11 @@ */ @Override public void sawOpcode(final int seen) { - if (stage == Stage.FIND_LOOP_STAGE) + if (stage == Stage.FIND_LOOP_STAGE) { sawOpcodeLoop(seen); - else + } else { sawOpcodeBug(seen); + } } /** @@ -152,26 +153,26 @@ stack.mergeJumps(this); switch (state) { - case SAW_NOTHING: - if ((seen == IINC) && (getIntConstant() == 1)) { - loopReg = getRegisterOperand(); - state = State.SAW_IINC; - } + case SAW_NOTHING: + if ((seen == IINC) && (getIntConstant() == 1)) { + loopReg = getRegisterOperand(); + state = State.SAW_IINC; + } break; - case SAW_IINC: - if ((seen == GOTO) || (seen == GOTO_W)) { - int branchTarget = getBranchTarget(); - int pc = getPC(); - if (branchTarget < pc) { - possibleForLoops.add(new ForLoop(branchTarget, pc, loopReg)); + case SAW_IINC: + if ((seen == GOTO) || (seen == GOTO_W)) { + int branchTarget = getBranchTarget(); + int pc = getPC(); + if (branchTarget < pc) { + possibleForLoops.add(new ForLoop(branchTarget, pc, loopReg)); + } } - } - state = State.SAW_NOTHING; + state = State.SAW_NOTHING; break; } - if ((seen == INVOKEINTERFACE) && "java/util/List".equals(getClassConstantOperand()) && "size".equals(getNameConstantOperand()) + if ((seen == INVOKEINTERFACE) && Values.SLASHED_JAVA_UTIL_LIST.equals(getClassConstantOperand()) && "size".equals(getNameConstantOperand()) && "()I".equals(getSigConstantOperand())) { sawListSize = true; } @@ -194,73 +195,74 @@ while (it.hasNext()) { ForLoop fl = it.next(); switch (fl.getLoopState()) { - case LOOP_NOT_STARTED: - if (getPC() == fl.getLoopStart()) { - if ((seen == ILOAD) || ((seen >= ILOAD_0) && (seen <= ILOAD_3)) - && (getReg(seen, ILOAD, ILOAD_0) == fl.getLoopReg())) { - fl.setLoopState(LoopState.LOOP_INDEX_LOADED_FOR_TEST); - continue; + case LOOP_NOT_STARTED: + if (getPC() == fl.getLoopStart()) { + if ((seen == ILOAD) || (((seen >= ILOAD_0) && (seen <= ILOAD_3)) && (getReg(seen, ILOAD, ILOAD_0) == fl.getLoopReg()))) { + fl.setLoopState(LoopState.LOOP_INDEX_LOADED_FOR_TEST); + continue; + } + it.remove(); } - it.remove(); - } break; - case LOOP_INDEX_LOADED_FOR_TEST: - if (getPC() >= fl.getLoopEnd()) { - it.remove(); - continue; - } - if (seen == IF_ICMPGE) { - if (stack.getStackDepth() > 1) { - OpcodeStack.Item itm = stack.getStackItem(0); - if (itm.getConstant() != null) { - it.remove(); + case LOOP_INDEX_LOADED_FOR_TEST: + if (getPC() >= fl.getLoopEnd()) { + it.remove(); + continue; + } + if (seen == IF_ICMPGE) { + if (stack.getStackDepth() > 1) { + OpcodeStack.Item itm = stack.getStackItem(0); + if (itm.getConstant() != null) { + it.remove(); + continue; + } + } + int branchTarget = getBranchTarget(); + if ((branchTarget >= (fl.getLoopEnd() + 3)) && (branchTarget <= (fl.getLoopEnd() + 5))) { + fl.setLoopState(LoopState.LOOP_IN_BODY); continue; } } - int branchTarget = getBranchTarget(); - if ((branchTarget >= (fl.getLoopEnd() + 3)) && (branchTarget <= (fl.getLoopEnd() + 5))) { - fl.setLoopState(LoopState.LOOP_IN_BODY); - continue; - } - } break; - case LOOP_IN_BODY: - case LOOP_IN_BODY_WITH_GET: - if ((getPC() == fl.getLoopEnd()) && (fl.getLoopState() == LoopState.LOOP_IN_BODY_WITH_GET)) { - bugReporter.reportBug(new BugInstance(this, "LII_LIST_INDEXED_ITERATING", NORMAL_PRIORITY).addClass(this).addMethod(this) - .addSourceLineRange(this, fl.getLoopStart(), fl.getLoopEnd())); - it.remove(); - } - if (getPC() > fl.getLoopEnd()) { - it.remove(); - } + case LOOP_IN_BODY: + case LOOP_IN_BODY_WITH_GET: + if ((getPC() == fl.getLoopEnd()) && (fl.getLoopState() == LoopState.LOOP_IN_BODY_WITH_GET)) { + bugReporter.reportBug(new BugInstance(this, "LII_LIST_INDEXED_ITERATING", NORMAL_PRIORITY).addClass(this).addMethod(this) + .addSourceLineRange(this, fl.getLoopStart(), fl.getLoopEnd())); + it.remove(); + } + if (getPC() > fl.getLoopEnd()) { + it.remove(); + } - if ((seen == ILOAD) || ((seen >= ILOAD_0) && (seen <= ILOAD_3))) { - loopReg = getReg(seen, ILOAD, ILOAD_0); - if (loopReg == fl.getLoopReg()) - fl.setLoopRegLoaded(true); - } else if (fl.getLoopRegLoaded()) { - boolean sawGet = ((seen == INVOKEINTERFACE) && "java/util/List".equals(getClassConstantOperand()) - && "get".equals(getNameConstantOperand()) && "(I)Ljava/lang/Object;".equals(getSigConstantOperand())); - if (!sawGet) { - it.remove(); - } else { - fl.setLoopState(LoopState.LOOP_IN_BODY_WITH_GET); - if (stack.getStackDepth() > 1) { - OpcodeStack.Item itm = stack.getStackItem(0); - if (!itm.couldBeZero()) - it.remove(); - else { - itm = stack.getStackItem(1); - if (fl.isSecondItem(itm)) + if ((seen == ILOAD) || ((seen >= ILOAD_0) && (seen <= ILOAD_3))) { + loopReg = getReg(seen, ILOAD, ILOAD_0); + if (loopReg == fl.getLoopReg()) { + fl.setLoopRegLoaded(true); + } + ... [truncated message content] |