[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] |