[Fb-contrib-commit] SF.net SVN: fb-contrib:[1839] trunk/fb-contrib
Brought to you by:
dbrosius
|
From: <dbr...@us...> - 2018-06-01 00:35:53
|
Revision: 1839
http://sourceforge.net/p/fb-contrib/code/1839
Author: dbrosius
Date: 2018-06-01 00:34:34 +0000 (Fri, 01 Jun 2018)
Log Message:
-----------
sync from github
Modified Paths:
--------------
trunk/fb-contrib/.classpath
trunk/fb-contrib/build.xml
trunk/fb-contrib/htdocs/index.shtml
trunk/fb-contrib/htdocs/repository.html
trunk/fb-contrib/pom.xml
trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/AbstractClassEmptyMethods.java
trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/AnnotationIssues.java
trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/ClassEnvy.java
trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/FunctionalInterfaceIssues.java
trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/JPAIssues.java
trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/LostExceptionStackTrace.java
trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/OptionalIssues.java
trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/PresizeCollections.java
trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/ReflectionIssues.java
trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/SpoiledChildInterfaceImplementor.java
trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/SuspiciousNullGuard.java
trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/utils/SignatureBuilder.java
trunk/fb-contrib/src/samples/java/ex/ACEM_Sample.java
trunk/fb-contrib/src/samples/java/ex/AI_Sample.java
trunk/fb-contrib/src/samples/java/ex/LEST_Sample.java
Modified: trunk/fb-contrib/.classpath
===================================================================
--- trunk/fb-contrib/.classpath 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/.classpath 2018-06-01 00:34:34 UTC (rev 1839)
@@ -25,7 +25,7 @@
</classpathentry>
<classpathentry kind="lib" path="lib/threetenbp-1.3.2.jar"/>
<classpathentry kind="lib" path="lib/commons-codec-1.10.jar"/>
- <classpathentry kind="lib" path="lib/commons-collections-3.2.2.jar"/>
+ <classpathentry kind="lib" path="lib/commons-collections-3.2.2.jar" sourcepath="/home/dave/.m2/repository/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2-sources.jar"/>
<classpathentry kind="lib" path="lib/commons-lang3-3.4.jar"/>
<classpathentry kind="lib" path="lib/findbugs-ant-3.0.0.jar"/>
<classpathentry kind="lib" path="lib/guava-19.0.jar" sourcepath="lib/sources/guava-19.0-sources.jar"/>
Modified: trunk/fb-contrib/build.xml
===================================================================
--- trunk/fb-contrib/build.xml 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/build.xml 2018-06-01 00:34:34 UTC (rev 1839)
@@ -31,7 +31,7 @@
<property name="javac.debug" value="on" />
<property name="test_reports.dir" value="${target.dir}/reports/test"/>
- <property name="fb-contrib.version" value="7.4.1" />
+ <property name="fb-contrib.version" value="7.4.2" />
<property name="sonatype.dir" value="${user.home}/.fb-contrib-${fb-contrib.version}-sonatype" />
@@ -51,7 +51,7 @@
<target name="yank" xmlns:yank="antlib:com.mebigfatguy.yank" unless="no.yank">
<mkdir dir="${lib.dir}" />
- <yank:yank yankFile="${basedir}/yank.xls" destination="${lib.dir}" proxyServer="${proxy.server}" source="true" separateClassifierTypes="true" checkSHADigests="true">
+ <yank:yank yankFile="${basedir}/yank.csv" destination="${lib.dir}" proxyServer="${proxy.server}" source="true" separateClassifierTypes="true" checkSHADigests="true">
<server url="http://repo1.maven.org/maven2" />
<generateVersions propertyFileName="${basedir}/version.properties" />
</yank:yank>
@@ -126,8 +126,10 @@
<pathelement location="${lib.dir}/javax.servlet-api-${javax.servlet-api.version}.jar" />
<pathelement location="${lib.dir}/log4j-${log4j.version}.jar" />
<pathelement location="${lib.dir}/log4j-api-${log4j-api.version}.jar" />
- <pathelement location="${lib.dir}/commons-lang3-${commons-lang3.version}.jar" />
- <pathelement location="${lib.dir}/commons-io-${commons-io.version}.jar" />
+ <pathelement location="${lib.dir}/commons-collections-${commons-collections.version}.jar" />
+ <pathelement location="${lib.dir}/commons-lang3-${commons-lang3.version}.jar" />
+ <pathelement location="${lib.dir}/commons-io-${commons-io.version}.jar" />
+ <pathelement location="${lib.dir}/dom4j-${dom4j.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" />
@@ -139,7 +141,8 @@
<pathelement location="${lib.dir}/spring-beans-${spring-beans.version}.jar" />
<pathelement location="${lib.dir}/spring-context-${spring-context.version}.jar" />
<pathelement location="${lib.dir}/spring-tx-${spring-tx.version}.jar" />
- <pathelement location="${lib.dir}/javax.persistence-${javax.persistence.version}.jar" />
+ <pathelement location="${lib.dir}/javax.persistence-${javax.persistence.version}.jar" />
+ <pathelement location="${lib.dir}/jaxen-${jaxen.version}.jar" />
<pathelement location="${lib.dir}/mockito-core-${mockito-core.version}.jar" />
<pathelement location="${lib.dir}/hamcrest-core-${hamcrest-core.version}.jar" />
<pathelement location="${lib.dir}/jena-shaded-guava-${jena-shaded-guava.version}.jar" />
@@ -248,7 +251,7 @@
<include name="**/*.license" />
<include name="**/*.txt" />
<include name="**/*.md" />
- <include name="**/*.xls" />
+ <include name="**/*.csv" />
<include name="**/*.example" />
<include name="**/*.fbp" />
</fileset>
Modified: trunk/fb-contrib/htdocs/index.shtml
===================================================================
--- trunk/fb-contrib/htdocs/index.shtml 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/htdocs/index.shtml 2018-06-01 00:34:34 UTC (rev 1839)
@@ -68,7 +68,7 @@
</li>
</ul>
</p>
- <p style="font-weight: bold;">The latest version of fb-contrib is 7.4.1 available for download
+ <p style="font-weight: bold;">The latest version of fb-contrib is 7.4.2 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
Modified: trunk/fb-contrib/htdocs/repository.html
===================================================================
--- trunk/fb-contrib/htdocs/repository.html 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/htdocs/repository.html 2018-06-01 00:34:34 UTC (rev 1839)
@@ -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>7.4.1 or 7.4.1.sb</td></tr>
+ <tr><td><b>Version:</b></td><td>7.4.2 or 7.4.2.sb</td></tr>
</table>
</div>
Modified: trunk/fb-contrib/pom.xml
===================================================================
--- trunk/fb-contrib/pom.xml 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/pom.xml 2018-06-01 00:34:34 UTC (rev 1839)
@@ -6,7 +6,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.mebigfatguy.fb-contrib</groupId>
<artifactId>fb-contrib</artifactId>
- <version>7.4.1</version>
+ <version>7.4.2</version>
<!-- TODO: Delete this and replace with enforcer plugin. This is for maven plugins only! Latest maven will through warnings. -->
<prerequisites>
Modified: trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/AbstractClassEmptyMethods.java
===================================================================
--- trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/AbstractClassEmptyMethods.java 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/AbstractClassEmptyMethods.java 2018-06-01 00:34:34 UTC (rev 1839)
@@ -112,7 +112,12 @@
return;
}
- if (!interfaceMethods.contains(new QMethod(methodName, getMethod().getSignature()))) {
+ Method m = getMethod();
+ if (m.isSynthetic()) {
+ return;
+ }
+
+ if (!interfaceMethods.contains(new QMethod(methodName, m.getSignature()))) {
super.visitCode(obj);
}
}
Modified: trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/AnnotationIssues.java
===================================================================
--- trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/AnnotationIssues.java 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/AnnotationIssues.java 2018-06-01 00:34:34 UTC (rev 1839)
@@ -18,9 +18,13 @@
*/
package com.mebigfatguy.fbcontrib.detect;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -33,9 +37,12 @@
import com.mebigfatguy.fbcontrib.collect.MethodInfo;
import com.mebigfatguy.fbcontrib.collect.Statistics;
import com.mebigfatguy.fbcontrib.utils.BugType;
+import com.mebigfatguy.fbcontrib.utils.CodeByteUtils;
import com.mebigfatguy.fbcontrib.utils.FQMethod;
+import com.mebigfatguy.fbcontrib.utils.OpcodeUtils;
import com.mebigfatguy.fbcontrib.utils.SignatureBuilder;
import com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException;
+import com.mebigfatguy.fbcontrib.utils.ToString;
import com.mebigfatguy.fbcontrib.utils.UnmodifiableSet;
import com.mebigfatguy.fbcontrib.utils.Values;
@@ -56,6 +63,13 @@
private static final String USER_NULLABLE_ANNOTATIONS = "fb-contrib.ai.annotations";
+ private static final Set<String> IS_EMPTY_SIGNATURES = UnmodifiableSet.create(
+ // @formatter:off
+ new SignatureBuilder().withParamTypes(Collection.class).withReturnType(boolean.class).build(),
+ new SignatureBuilder().withParamTypes(Map.class).withReturnType(boolean.class).build()
+ // @formatter:on
+ );
+
private static final Set<String> NULLABLE_ANNOTATIONS = new HashSet<>();
static {
@@ -82,8 +96,18 @@
// @formatter:on
);
- public enum NULLABLE {
- TRUE
+ public static class AIUserValue {
+
+ int reg;
+
+ public AIUserValue(int reg) {
+ this.reg = reg;
+ }
+
+ @Override
+ public String toString() {
+ return ToString.build(this);
+ }
};
private BugReporter bugReporter;
@@ -90,6 +114,7 @@
private Map<Integer, Integer> assumedNullTill;
private Map<Integer, Integer> assumedNonNullTill;
private Set<Integer> noAssumptionsPossible;
+ private List<Integer> branchTargets;
private OpcodeStack stack;
private boolean methodIsNullable;
@@ -117,6 +142,7 @@
assumedNullTill = new HashMap<>();
assumedNonNullTill = new HashMap<>();
noAssumptionsPossible = new HashSet<>();
+ branchTargets = new ArrayList<>();
super.visitClassContext(classContext);
}
}
@@ -125,6 +151,7 @@
assumedNullTill = null;
assumedNonNullTill = null;
noAssumptionsPossible = null;
+ branchTargets = null;
}
}
@@ -171,6 +198,7 @@
assumedNullTill.clear();
assumedNonNullTill.clear();
noAssumptionsPossible.clear();
+ branchTargets.clear();
try {
super.visitCode(obj);
@@ -190,11 +218,23 @@
@Override
public void sawOpcode(int seen) {
- boolean resultIsNullable = false;
+ AIUserValue userValue = null;
+ if (OpcodeUtils.isBranch(seen) && (getBranchOffset() > 0)) {
+ branchTargets.add(getBranchTarget());
+ Collections.sort(branchTargets);
+ }
+
+ clearBranchTargets(getPC());
+ convertNullToNonNull(getPC());
clearAssumptions(assumedNullTill, getPC());
clearAssumptions(assumedNonNullTill, getPC());
+ if (OpcodeUtils.isBranch(seen) && (getBranchOffset() > 0)) {
+ branchTargets.add(getBranchTarget());
+ Collections.sort(branchTargets);
+ }
+
try {
switch (seen) {
case ARETURN: {
@@ -201,8 +241,8 @@
if (!methodIsNullable && (stack.getStackDepth() > 0)) {
OpcodeStack.Item itm = stack.getStackItem(0);
Integer reg = Integer.valueOf(itm.getRegisterNumber());
- methodIsNullable = !noAssumptionsPossible.contains(reg) && ((assumedNullTill.containsKey(reg) && !assumedNonNullTill.containsKey(reg))
- || isStackElementNullable(getClassName(), getMethod(), itm));
+ methodIsNullable = !assumedNonNullTill.containsKey(reg) && (!noAssumptionsPossible.contains(reg)
+ && ((assumedNullTill.containsKey(reg)) || isStackElementNullable(getClassName(), getMethod(), itm)));
if (methodIsNullable) {
throw new StopOpcodeParsingException();
}
@@ -234,10 +274,39 @@
}
break;
+ case IFEQ:
+ if ((getBranchOffset() > 0) && (stack.getStackDepth() > 0)) {
+ OpcodeStack.Item itm = stack.getStackItem(0);
+ AIUserValue uv = (AIUserValue) itm.getUserValue();
+ if ((uv != null) && (uv.reg >= 0)) {
+ assumedNullTill.put(uv.reg, getBranchTarget());
+ }
+ }
+ break;
+
case INVOKESTATIC:
+ if (stack.getStackDepth() > 0) {
+ String signature = getSigConstantOperand();
+ if (IS_EMPTY_SIGNATURES.contains(signature)) {
+ String methodName = getNameConstantOperand();
+ if (methodName.equals("isEmpty")) {
+ OpcodeStack.Item item = stack.getStackItem(0);
+ int reg = item.getRegisterNumber();
+ if (reg >= 0) {
+ userValue = new AIUserValue(reg);
+ break;
+ }
+ }
+ }
+ }
+
+ // $FALL-THROUGH$
case INVOKEINTERFACE:
case INVOKEVIRTUAL: {
- resultIsNullable = (isMethodNullable(getClassConstantOperand(), getNameConstantOperand(), getSigConstantOperand()));
+ boolean resultIsNullable = (isMethodNullable(getClassConstantOperand(), getNameConstantOperand(), getSigConstantOperand()));
+ if (resultIsNullable) {
+ userValue = new AIUserValue(-1);
+ }
break;
}
@@ -250,9 +319,9 @@
}
} finally {
stack.sawOpcode(this, seen);
- if ((resultIsNullable) && (stack.getStackDepth() > 0)) {
+ if ((userValue != null) && (stack.getStackDepth() > 0)) {
OpcodeStack.Item itm = stack.getStackItem(0);
- itm.setUserValue(NULLABLE.TRUE);
+ itm.setUserValue(userValue);
}
}
}
@@ -269,7 +338,7 @@
}
public static boolean isStackElementNullable(String className, Method method, OpcodeStack.Item itm) {
- if (itm.isNull() || (itm.getUserValue() instanceof NULLABLE)) {
+ if (itm.isNull() || (itm.getUserValue() != null)) {
MethodInfo mi = Statistics.getStatistics().getMethodStatistics(className, method.getName(), method.getSignature());
if (mi != null) {
mi.setCanReturnNull(true);
@@ -321,6 +390,47 @@
}
}
+ public void convertNullToNonNull(int pc) {
+ for (Map.Entry<Integer, Integer> entry : assumedNullTill.entrySet()) {
+ if (entry.getValue().intValue() == pc) {
+ int lastOp = getPrevOpcode(1);
+ if ((lastOp == ARETURN) || (lastOp == ATHROW)) {
+ int nonNullTill = getNextBranchTarget();
+ assumedNonNullTill.put(entry.getKey(), nonNullTill);
+ } else if (OpcodeUtils.isBranch(lastOp)) {
+ int branchOffset = CodeByteUtils.getshort(getCode().getCode(), getPC() - 2);
+ if (branchOffset > 0) {
+ assumedNonNullTill.put(entry.getKey(), getPC() + branchOffset);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * remove branch targets that have been passed
+ *
+ * @param pc
+ * the current pc
+ */
+ public void clearBranchTargets(int pc) {
+ Iterator<Integer> it = branchTargets.iterator();
+ while (it.hasNext()) {
+ int target = it.next().intValue();
+ if (target <= pc) {
+ it.remove();
+ }
+ }
+ }
+
+ public int getNextBranchTarget() {
+ if (branchTargets.isEmpty()) {
+ return Integer.MAX_VALUE;
+ }
+
+ return branchTargets.get(0);
+ }
+
public void removeAssumptions(Map<Integer, Integer> assumptionsTill) {
noAssumptionsPossible.addAll(assumptionsTill.keySet());
}
Modified: trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/ClassEnvy.java
===================================================================
--- trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/ClassEnvy.java 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/ClassEnvy.java 2018-06-01 00:34:34 UTC (rev 1839)
@@ -347,7 +347,7 @@
private void addLineNumber(BitSet lineNumbers) {
LineNumberTable lnt = getCode().getLineNumberTable();
if (lnt == null) {
- lineNumbers.set(-lineNumbers.size());
+ lineNumbers.set(0);
} else {
int line = lnt.getSourceLine(getPC());
if (line < 0) {
Modified: trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/FunctionalInterfaceIssues.java
===================================================================
--- trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/FunctionalInterfaceIssues.java 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/FunctionalInterfaceIssues.java 2018-06-01 00:34:34 UTC (rev 1839)
@@ -44,6 +44,7 @@
import com.mebigfatguy.fbcontrib.utils.FQMethod;
import com.mebigfatguy.fbcontrib.utils.OpcodeUtils;
import com.mebigfatguy.fbcontrib.utils.QMethod;
+import com.mebigfatguy.fbcontrib.utils.SignatureBuilder;
import com.mebigfatguy.fbcontrib.utils.SignatureUtils;
import com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException;
import com.mebigfatguy.fbcontrib.utils.ToString;
@@ -65,14 +66,14 @@
private static final int REF_invokeStatic = 6;
- private static final QMethod CONTAINS = new QMethod("contains", "(Ljava/lang/Object;)Z");
- private static final QMethod SIZE = new QMethod("size", "()I");
+ private static final QMethod CONTAINS = new QMethod("contains", SignatureBuilder.SIG_OBJECT_TO_BOOLEAN);
+ private static final QMethod SIZE = new QMethod("size", SignatureBuilder.SIG_VOID_TO_INT);
private static final FQMethod COLLECT = new FQMethod("java/util/stream/Stream", "collect", "(Ljava/util/stream/Collector;)Ljava/lang/Object;");
private static final FQMethod FILTER = new FQMethod("java/util/stream/Stream", "filter", "(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;");
private static final FQMethod FINDFIRST = new FQMethod("java/util/stream/Stream", "findFirst", "()Ljava/util/Optional;");
- private static final FQMethod ISPRESENT = new FQMethod("java/util/Optional", "isPresent", "()Z");
- private static final FQMethod GET = new FQMethod("java/util/List", "get", "(I)Ljava/lang/Object;");
+ private static final FQMethod ISPRESENT = new FQMethod("java/util/Optional", "isPresent", SignatureBuilder.SIG_VOID_TO_BOOLEAN);
+ private static final FQMethod GET = new FQMethod("java/util/List", "get", SignatureBuilder.SIG_INT_TO_OBJECT);
enum ParseState {
NORMAL, LAMBDA;
@@ -367,7 +368,7 @@
@Nullable
private String getAnonymousName(ConstantMethodHandle cmh) {
- if (cmh.getReferenceKind() != REF_invokeStatic) {
+ if ((cmh == null) || (cmh.getReferenceKind() != REF_invokeStatic)) {
return null;
}
Modified: trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/JPAIssues.java
===================================================================
--- trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/JPAIssues.java 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/JPAIssues.java 2018-06-01 00:34:34 UTC (rev 1839)
@@ -268,10 +268,10 @@
/**
* parses the current class for spring-tx and jpa annotations, as well as hashCode and equals methods.
*
- * @param cls
+ * @param clz
* the currently parsed class
*/
- private void catalogClass(JavaClass cls) {
+ private void catalogClass(JavaClass clz) {
transactionalMethods = new HashMap<>();
isEntity = false;
hasId = false;
@@ -279,7 +279,7 @@
hasEagerOneToMany = false;
hasHCEquals = false;
- for (AnnotationEntry entry : cls.getAnnotationEntries()) {
+ for (AnnotationEntry entry : clz.getAnnotationEntries()) {
if ("Ljavax/persistence/Entity;".equals(entry.getAnnotationType())) {
isEntity = true;
break;
@@ -286,7 +286,7 @@
}
}
- for (Method m : cls.getMethods()) {
+ for (Method m : clz.getMethods()) {
catalogFieldOrMethod(m);
if (("equals".equals(m.getName()) && SignatureBuilder.SIG_OBJECT_TO_BOOLEAN.equals(m.getSignature()))
@@ -295,7 +295,7 @@
}
}
- for (Field f : cls.getFields()) {
+ for (Field f : clz.getFields()) {
catalogFieldOrMethod(f);
}
}
Modified: trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/LostExceptionStackTrace.java
===================================================================
--- trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/LostExceptionStackTrace.java 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/LostExceptionStackTrace.java 2018-06-01 00:34:34 UTC (rev 1839)
@@ -241,8 +241,9 @@
markAsValid = true; // Fixes javac generated code
}
}
- } else if (("getTargetException".equals(methodName) || "getCause".equals(methodName))
- && "java/lang/reflect/InvocationTargetException".equals(getClassConstantOperand())) {
+ } else if ((("getTargetException".equals(methodName) || "getCause".equals(methodName))
+ && "java/lang/reflect/InvocationTargetException".equals(getClassConstantOperand()))
+ || "java/io/UncheckedIOException".equals(getClassConstantOperand())) {
markAsValid = true;
} else if (isPossibleExBuilder(catchInfo.getRegister())) {
markAsValid = true;
Modified: trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/OptionalIssues.java
===================================================================
--- trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/OptionalIssues.java 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/OptionalIssues.java 2018-06-01 00:34:34 UTC (rev 1839)
@@ -55,7 +55,7 @@
private static Set<String> BOXED_OPTIONAL_TYPES = UnmodifiableSet.create("Ljava/lang/Integer;", "Ljava/lang/Long;", "Ljava/lang/Double;");
- private static final FQMethod OPTIONAL_OR_ELSE_METHOD = new FQMethod("java/util/Optional", "orElse", "(Ljava/lang/Object;)Ljava/lang/Object;");
+ private static final FQMethod OPTIONAL_OR_ELSE_METHOD = new FQMethod("java/util/Optional", "orElse", SignatureBuilder.SIG_OBJECT_TO_OBJECT);
private static final FQMethod OPTIONAL_OR_ELSE_GET_METHOD = new FQMethod("java/util/Optional", "orElseGet",
"(Ljava/util/function/Supplier;)Ljava/lang/Object;");
private static final FQMethod OPTIONAL_GET_METHOD = new FQMethod("java/util/Optional", "get", SignatureBuilder.SIG_VOID_TO_OBJECT);
@@ -64,8 +64,8 @@
// @formatter:off
OPTIONAL_OR_ELSE_METHOD,
new FQMethod("java/util/OptionalDouble", "orElse", "(D)D"),
- new FQMethod("java/util/OptionalInt", "orElse", "(I)I"),
- new FQMethod("java/util/OptionalLong", "orElse", "(J)J")
+ new FQMethod("java/util/OptionalInt", "orElse", SignatureBuilder.SIG_INT_TO_INT),
+ new FQMethod("java/util/OptionalLong", "orElse", SignatureBuilder.SIG_LONG_TO_LONG)
// @formatter:on
);
Modified: trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/PresizeCollections.java
===================================================================
--- trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/PresizeCollections.java 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/PresizeCollections.java 2018-06-01 00:34:34 UTC (rev 1839)
@@ -460,7 +460,7 @@
return true;
}
- if ((seen != IFNE) || (stack.getStackDepth() == 0)) {
+ if (((seen != IFNE) && (seen != IFEQ)) || (stack.getStackDepth() == 0)) {
return false;
}
Modified: trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/ReflectionIssues.java
===================================================================
--- trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/ReflectionIssues.java 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/ReflectionIssues.java 2018-06-01 00:34:34 UTC (rev 1839)
@@ -18,6 +18,8 @@
*/
package com.mebigfatguy.fbcontrib.detect;
+import java.lang.reflect.AccessibleObject;
+
import org.apache.bcel.Repository;
import org.apache.bcel.classfile.JavaClass;
@@ -24,6 +26,7 @@
import com.mebigfatguy.fbcontrib.utils.BugType;
import com.mebigfatguy.fbcontrib.utils.FQMethod;
import com.mebigfatguy.fbcontrib.utils.QMethod;
+import com.mebigfatguy.fbcontrib.utils.SignatureBuilder;
import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.BugReporter;
@@ -32,9 +35,9 @@
public class ReflectionIssues extends BytecodeScanningDetector {
- private static final QMethod SETACCESSIBLE = new QMethod("setAccessible", "(Z)V");
+ private static final QMethod SETACCESSIBLE = new QMethod("setAccessible", SignatureBuilder.SIG_BOOLEAN_TO_VOID);
private static final FQMethod SETACCESSIBLE_ARRAY = new FQMethod("java/lang/reflect/AccessibleObject", "setAccessible",
- "([Ljava/lang/reflect/AccessibleObject;Z)V");
+ new SignatureBuilder().withParamTypes(AccessibleObject.class).build());
private static final JavaClass ACCESSIBLE_OBJECT_CLASS;
static {
Modified: trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/SpoiledChildInterfaceImplementor.java
===================================================================
--- trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/SpoiledChildInterfaceImplementor.java 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/SpoiledChildInterfaceImplementor.java 2018-06-01 00:34:34 UTC (rev 1839)
@@ -28,6 +28,7 @@
import com.mebigfatguy.fbcontrib.utils.BugType;
import com.mebigfatguy.fbcontrib.utils.QMethod;
+import com.mebigfatguy.fbcontrib.utils.SignatureBuilder;
import com.mebigfatguy.fbcontrib.utils.ToString;
import com.mebigfatguy.fbcontrib.utils.UnmodifiableSet;
import com.mebigfatguy.fbcontrib.utils.Values;
@@ -46,15 +47,15 @@
private static final Set<QMethod> OBJECT_METHODS = UnmodifiableSet.create(
// @formatter:off
- new QMethod("equals", "(Ljava/lang/Object;)Z"),
- new QMethod(Values.HASHCODE, "()I"),
- new QMethod(Values.TOSTRING, "()Ljava/lang/String;"),
- new QMethod("clone", "()Ljava/lang/Object;"),
- new QMethod("notify", "()V"),
- new QMethod("notifyAll", "()V"),
- new QMethod("wait", "(J)V"),
+ new QMethod("equals", SignatureBuilder.SIG_OBJECT_TO_BOOLEAN),
+ new QMethod(Values.HASHCODE, SignatureBuilder.SIG_VOID_TO_INT),
+ new QMethod(Values.TOSTRING, SignatureBuilder.SIG_VOID_TO_STRING),
+ new QMethod("clone", SignatureBuilder.SIG_VOID_TO_OBJECT),
+ new QMethod("notify", SignatureBuilder.SIG_VOID_TO_VOID),
+ new QMethod("notifyAll", SignatureBuilder.SIG_VOID_TO_VOID),
+ new QMethod("wait", SignatureBuilder.SIG_LONG_TO_VOID),
new QMethod("wait", "(JI)V"),
- new QMethod("wait", "()V")
+ new QMethod("wait", SignatureBuilder.SIG_VOID_TO_VOID)
// @formatter:on
);
private final BugReporter bugReporter;
Modified: trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/SuspiciousNullGuard.java
===================================================================
--- trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/SuspiciousNullGuard.java 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/detect/SuspiciousNullGuard.java 2018-06-01 00:34:34 UTC (rev 1839)
@@ -25,6 +25,8 @@
import javax.annotation.Nullable;
import org.apache.bcel.classfile.Code;
+import org.apache.bcel.classfile.LocalVariable;
+import org.apache.bcel.classfile.LocalVariableTable;
import com.mebigfatguy.fbcontrib.utils.BugType;
import com.mebigfatguy.fbcontrib.utils.RegisterUtils;
@@ -101,8 +103,9 @@
try {
stack.precomputation(this);
- Integer pc = Integer.valueOf(getPC());
- nullGuards.remove(pc);
+ int pc = getPC();
+ nullGuards.remove(Integer.valueOf(pc));
+ clearEndOfLifeRegisters();
switch (seen) {
case IFNULL: {
@@ -111,12 +114,21 @@
int reg = itm.getRegisterNumber();
Integer target = Integer.valueOf(getBranchTarget());
if (reg >= 0) {
- nullGuards.put(target, new NullGuard(reg, pc.intValue(), itm.getSignature()));
+ int eol = Integer.MAX_VALUE;
+ LocalVariableTable lvt = getMethod().getLocalVariableTable();
+ if (lvt != null) {
+ LocalVariable lv = lvt.getLocalVariable(reg, pc);
+ if (lv != null) {
+ eol = pc + lv.getLength();
+ }
+ }
+
+ nullGuards.put(target, new NullGuard(reg, pc, eol, itm.getSignature()));
} else {
XField xf = itm.getXField();
Integer sourceFieldReg = (Integer) itm.getUserValue();
if ((xf != null) && (sourceFieldReg != null)) {
- nullGuards.put(target, new NullGuard(xf, sourceFieldReg.intValue(), pc.intValue(), itm.getSignature()));
+ nullGuards.put(target, new NullGuard(xf, sourceFieldReg.intValue(), pc, itm.getSignature()));
}
}
}
@@ -258,17 +270,30 @@
}
}
+ private void clearEndOfLifeRegisters() {
+ int pc = getPC();
+ Iterator<NullGuard> it = nullGuards.values().iterator();
+ while (it.hasNext()) {
+ NullGuard potentialEOL = it.next();
+ if (potentialEOL.isEOL(pc)) {
+ it.remove();
+ }
+ }
+ }
+
static class NullGuard {
int register;
XField field;
int fieldSourceReg;
int location;
+ int scopeEnd;
String signature;
- NullGuard(int reg, int start, String guardSignature) {
+ NullGuard(int reg, int start, int end, String guardSignature) {
register = reg;
field = null;
location = start;
+ scopeEnd = end;
signature = guardSignature;
}
@@ -277,6 +302,7 @@
field = xf;
fieldSourceReg = fieldSource;
location = start;
+ scopeEnd = Integer.MAX_VALUE;
signature = guardSignature;
}
@@ -296,6 +322,10 @@
return location;
}
+ boolean isEOL(int pc) {
+ return pc >= scopeEnd;
+ }
+
String getSignature() {
return signature;
}
Modified: trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/utils/SignatureBuilder.java
===================================================================
--- trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/utils/SignatureBuilder.java 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/src/main/java/com/mebigfatguy/fbcontrib/utils/SignatureBuilder.java 2018-06-01 00:34:34 UTC (rev 1839)
@@ -41,6 +41,8 @@
public static final String SIG_INT_TO_INT = new SignatureBuilder().withParamTypes(Values.SIG_PRIMITIVE_INT).withReturnType(Values.SIG_PRIMITIVE_INT)
.toString();
+ public static final String SIG_BOOLEAN_TO_VOID = new SignatureBuilder().withParamTypes(Values.SIG_PRIMITIVE_BOOLEAN).toString();
+
public static final String SIG_LONG_TO_VOID = new SignatureBuilder().withParamTypes(Values.SIG_PRIMITIVE_LONG).toString();
public static final String SIG_LONG_TO_LONG = new SignatureBuilder().withParamTypes(Values.SIG_PRIMITIVE_LONG).withReturnType(Values.SIG_PRIMITIVE_LONG)
.toString();
Modified: trunk/fb-contrib/src/samples/java/ex/ACEM_Sample.java
===================================================================
--- trunk/fb-contrib/src/samples/java/ex/ACEM_Sample.java 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/src/samples/java/ex/ACEM_Sample.java 2018-06-01 00:34:34 UTC (rev 1839)
@@ -1,6 +1,10 @@
package ex;
public abstract class ACEM_Sample implements Foo {
+
+ public static final Runnable fpNOP283 = () -> {
+ };
+
public void test() {
}
@@ -7,12 +11,11 @@
public int test1() {
throw new UnsupportedOperationException("Not implemented");
}
-
+
@Override
public void doFPFoo() {
}
-
-
+
}
interface Foo {
Modified: trunk/fb-contrib/src/samples/java/ex/AI_Sample.java
===================================================================
--- trunk/fb-contrib/src/samples/java/ex/AI_Sample.java 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/src/samples/java/ex/AI_Sample.java 2018-06-01 00:34:34 UTC (rev 1839)
@@ -4,9 +4,13 @@
import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.List;
import javax.annotation.Nullable;
+import org.apache.commons.collections.CollectionUtils;
+
public class AI_Sample {
@Nullable
@@ -65,7 +69,47 @@
return AI_Sample.class.newInstance();
}
+ public Object fpConditionalWithThrow291() {
+ Object t = create();
+ if (t != null) {
+ return t;
+ } else {
+ throw new RuntimeException();
+ }
+ }
+
+ public Object fpConditionalWithElseNotNull() {
+ Object t = create();
+ if (t == null) {
+ return new Object();
+ } else {
+ return t;
+ }
+ }
+
+ public Object fpIsEmpty(String s) {
+ List<String> ss = maybeGetList(s);
+
+ if (CollectionUtils.isEmpty(ss)) {
+ return Collections.emptyList();
+ }
+
+ return ss;
+ }
+
interface Stringer {
String get();
}
+
+ @Nullable
+ private static Object create() {
+ return Math.random() >= 0.5 ? new Object() : null;
+ }
+
+ private List<String> maybeGetList(String s) {
+ if (s == null) {
+ return null;
+ }
+ return Collections.singletonList(s);
+ }
}
Modified: trunk/fb-contrib/src/samples/java/ex/LEST_Sample.java
===================================================================
--- trunk/fb-contrib/src/samples/java/ex/LEST_Sample.java 2018-05-20 22:03:10 UTC (rev 1838)
+++ trunk/fb-contrib/src/samples/java/ex/LEST_Sample.java 2018-06-01 00:34:34 UTC (rev 1839)
@@ -3,6 +3,7 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.UncheckedIOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DateFormat;
@@ -9,6 +10,8 @@
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
import com.google.common.base.Throwables;
@@ -162,6 +165,20 @@
}
}
+ public void testFPUncheckedIOException290(List<String> s) throws IOException {
+ try {
+ List<FileInputStream> fis = s.stream().map(ss -> {
+ try {
+ return new FileInputStream(ss);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }).collect(Collectors.toList());
+ } catch (UncheckedIOException e) {
+ throw e.getCause();
+ }
+ }
+
static Class<?> testFP226(final String clazz) {
if (clazz != null) {
try {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|