[Fb-contrib-commit] SF.net SVN: fb-contrib:[1742] trunk/fb-contrib
Brought to you by:
dbrosius
|
From: <dbr...@us...> - 2013-03-04 04:48:05
|
Revision: 1742
http://fb-contrib.svn.sourceforge.net/fb-contrib/?rev=1742&view=rev
Author: dbrosius
Date: 2013-03-04 04:47:55 +0000 (Mon, 04 Mar 2013)
Log Message:
-----------
sync from github
Modified Paths:
--------------
trunk/fb-contrib/etc/findbugs.xml
trunk/fb-contrib/etc/messages.xml
trunk/fb-contrib/samples/SPP_Sample.java
trunk/fb-contrib/samples/WOC_Sample.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CommonsEqualsBuilderToEquals.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CommonsHashcodeBuilderToHashcode.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LoggerOddities.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/WriteOnlyCollection.java
Added Paths:
-----------
trunk/fb-contrib/samples/CAAL_Sample.java
trunk/fb-contrib/samples/CU_Sample.java
trunk/fb-contrib/samples/PSC_Sample.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CloneUsability.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConfusingArrayAsList.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PresizeCollections.java
Modified: trunk/fb-contrib/etc/findbugs.xml
===================================================================
--- trunk/fb-contrib/etc/findbugs.xml 2013-02-10 02:29:13 UTC (rev 1741)
+++ trunk/fb-contrib/etc/findbugs.xml 2013-03-04 04:47:55 UTC (rev 1742)
@@ -132,7 +132,7 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.SuspiciousComparatorReturnValues" speed="fast" reports="SC_SUSPICIOUS_COMPARATOR_RETURN_VALUES" />
<Detector class="com.mebigfatguy.fbcontrib.detect.SillynessPotPourri" speed="fast"
- reports="SPP_NEGATIVE_BITSET_ITEM,SPP_INTERN_ON_CONSTANT,SPP_NO_CHAR_SB_CTOR,SPP_USE_MATH_CONSTANT,SPP_STUTTERED_ASSIGNMENT,SPP_USE_ISNAN,SPP_USE_BIGDECIMAL_STRING_CTOR,SPP_STRINGBUFFER_WITH_EMPTY_STRING,SPP_EQUALS_ON_ENUM,SPP_INVALID_BOOLEAN_NULL_CHECK,SPP_USE_CHARAT,SPP_USELESS_TRINARY,SPP_SUSPECT_STRING_TEST,SPP_USE_STRINGBUILDER_LENGTH,SPP_INVALID_CALENDAR_COMPARE,SPP_USE_CONTAINSKEY,SPP_USE_ISEMPTY,SPP_USE_GETPROPERTY,SPP_USELESS_CASING,SPP_NON_ARRAY_PARM,SPP_EMPTY_CASING,SPP_TEMPORARY_TRIM" />
+ reports="SPP_NEGATIVE_BITSET_ITEM,SPP_INTERN_ON_CONSTANT,SPP_NO_CHAR_SB_CTOR,SPP_USE_MATH_CONSTANT,SPP_STUTTERED_ASSIGNMENT,SPP_USE_ISNAN,SPP_USE_BIGDECIMAL_STRING_CTOR,SPP_STRINGBUFFER_WITH_EMPTY_STRING,SPP_EQUALS_ON_ENUM,SPP_INVALID_BOOLEAN_NULL_CHECK,SPP_USE_CHARAT,SPP_USELESS_TRINARY,SPP_SUSPECT_STRING_TEST,SPP_USE_STRINGBUILDER_LENGTH,SPP_INVALID_CALENDAR_COMPARE,SPP_USE_CONTAINSKEY,SPP_USE_ISEMPTY,SPP_USE_GETPROPERTY,SPP_USELESS_CASING,SPP_NON_ARRAY_PARM,SPP_EMPTY_CASING,SPP_TEMPORARY_TRIM,SPP_STRINGBUILDER_IS_MUTABLE" />
<Detector class="com.mebigfatguy.fbcontrib.detect.BloatedAssignmentScope" speed="fast" reports="BAS_BLOATED_ASSIGNMENT_SCOPE" hidden="true" />
@@ -165,7 +165,7 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.SuspiciousClusteredSessionSupport" speed="fast" reports="SCSS_SUSPICIOUS_CLUSTERED_SESSION_SUPPORT" />
- <Detector class="com.mebigfatguy.fbcontrib.detect.LoggerOddities" speed="fast" reports="LO_SUSPECT_LOG_CLASS,LO_SUSPECT_LOG_PARAMETER,LO_STUTTERED_MESSAGE" />
+ <Detector class="com.mebigfatguy.fbcontrib.detect.LoggerOddities" speed="fast" reports="LO_LOGGER_LOST_EXCEPTION_STACK_TRACE,LO_SUSPECT_LOG_CLASS,LO_SUSPECT_LOG_PARAMETER,LO_STUTTERED_MESSAGE" />
<Detector class="com.mebigfatguy.fbcontrib.detect.IncorrectInternalClassUse" speed="fast" reports="IICU_INCORRECT_INTERNAL_CLASS_USE" />
@@ -237,6 +237,8 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.CloneUsability" speed="fast" reports="CU_CLONE_USABILITY_OBJECT_RETURN,CU_CLONE_USABILITY_THROWS" />
<Detector class="com.mebigfatguy.fbcontrib.detect.ConfusingArrayAsList" speed="fast" reports="CAAL_CONFUSING_ARRAY_AS_LIST" />
+
+ <Detector class="com.mebigfatguy.fbcontrib.detect.PresizeCollections" speed="fast" reports="PSC_PRESIZE_COLLECTIONS" />
<!-- BugPattern -->
@@ -334,7 +336,8 @@
<BugPattern abbrev="SPP" type="SPP_SERIALVER_SHOULD_BE_PRIVATE" category="STYLE" />
<BugPattern abbrev="SPP" type="SPP_NON_ARRAY_PARM" category="CORRECTNESS" />
<BugPattern abbrev="SPP" type="SPP_EMPTY_CASING" category="STYLE" />
- <BugPattern abbrev="SPP" type="SPP_TEMPORARY_TRIM" category="STYLE" />
+ <BugPattern abbrev="SPP" type="SPP_TEMPORARY_TRIM" category="STYLE" />
+ <BugPattern abbrev="SPP" type="SPP_STRINGBUILDER_IS_MUTABLE" category="CORRECTNESS" />
<BugPattern abbrev="BAS" type="BAS_BLOATED_ASSIGNMENT_SCOPE" category="PERFORMANCE" />
<BugPattern abbrev="SCII" type="SCII_SPOILED_CHILD_INTERFACE_IMPLEMENTOR" category="STYLE" />
<BugPattern abbrev="DWI" type="DWI_DELETING_WHILE_ITERATING" category="CORRECTNESS" />
@@ -356,6 +359,7 @@
<BugPattern abbrev="SCA" type="SCA_SUSPICIOUS_CLONE_ALGORITHM" category="CORRECTNESS" />
<BugPattern abbrev="WEM" type="WEM_WEAK_EXCEPTION_MESSAGING" category="STYLE" />
<BugPattern abbrev="SCSS" type="SCSS_SUSPICIOUS_CLUSTERED_SESSION_SUPPORT" category="CORRECTNESS" />
+ <BugPattern abbrev="LO" type="LO_LOGGER_LOST_EXCEPTION_STACK_TRACE" category="CORRECTNESS" />
<BugPattern abbrev="LO" type="LO_SUSPECT_LOG_CLASS" category="CORRECTNESS" />
<BugPattern abbrev="LO" type="LO_SUSPECT_LOG_PARAMETER" category="CORRECTNESS" />
<BugPattern abbrev="LO" type="LO_STUTTERED_MESSAGE" category="STYLE" />
@@ -413,4 +417,5 @@
<BugPattern abbrev="CU" type="CU_CLONE_USABILITY_OBJECT_RETURN" category="STYLE" />
<BugPattern abbrev="CU" type="CU_CLONE_USABILITY_THROWS" category="STYLE" />
<BugPattern abbrev="CAAL" type="CAAL_CONFUSING_ARRAY_AS_LIST" category="CORRECTNESS" />
+ <BugPattern abbrev="PSC" type="PSC_PRESIZE_COLLECTIONS" category="PERFORMANCE" />
</FindbugsPlugin>
Modified: trunk/fb-contrib/etc/messages.xml
===================================================================
--- trunk/fb-contrib/etc/messages.xml 2013-02-10 02:29:13 UTC (rev 1741)
+++ trunk/fb-contrib/etc/messages.xml 2013-03-04 04:47:55 UTC (rev 1742)
@@ -145,9 +145,10 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.DubiousListCollection">
<Details>
<![CDATA[
- <p> Looks for constructors of non final classes that make method calls to non final methods.
- As these methods could be overridden, the overridden method will be accessing an object that
- is only partially constructed, perhaps causing problems.</p>
+ <p> looks for fields that are implementations of java.util.List, but that are used in a set-like fashion.
+ Since lookup type operations are performed using a linear search for Lists, the performance for large
+ Lists will be poor. Consideration should be made as to whether these fields should be sets. In the
+ case that order is important, consider using LinkedHashSet.</p>
<p>It is a fast detector</p>
]]>
</Details>
@@ -284,8 +285,7 @@
thread itself, introducing client calls will confuse the thread state of the object
in question, and will cause spurious thread state changes, either waking threads up
when not intended, or removing the the thread from the runnable state.</p>
- </p>
- <p>It is a fast detector</p>
+ <p>It is a fast detector</p>
]]>
</Details>
</Detector>
@@ -319,8 +319,7 @@
<![CDATA[
<p>Looks for methods that store the return result in a local variable, and
then immediately returns that local variable.</p>
- </p>
- <p>It is a fast detector</p>
+ <p>It is a fast detector</p>
]]>
</Details>
</Detector>
@@ -329,8 +328,7 @@
<Details>
<![CDATA[
<p>Looks for methods that are direct copies of the implementation in the super class</p>
- </p>
- <p>It is a fast detector</p>
+ <p>It is a fast detector</p>
]]>
</Details>
</Detector>
@@ -343,8 +341,7 @@
do not, and cannot define an equals method, reference equality is used for these
collections, which is probably not desired. If it is, consider using the IdentityHashMap
class when using Maps in this case, to better document your intentions.</p>
- </p>
- <p>It is a fast detector</p>
+ <p>It is a fast detector</p>
]]>
</Details>
</Detector>
@@ -1256,6 +1253,7 @@
Comparing class name ignores the class loader.
</p>
+ <p>It is a fast detector</p>
]]>
</Details>
</Detector>
@@ -1267,6 +1265,7 @@
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>It is a fast detector</p>
]]>
</Details>
</Detector>
@@ -1278,6 +1277,7 @@
not swallow CloneNotSupportedException. Not doing so makes the clone method not as simple to use,
and should be harmless to do so.
</p>
+ <p>It is a fast detector</p>
]]>
</Details>
</Detector>
@@ -1289,10 +1289,24 @@
This does not produce a list that holds the primitive boxed values, but a list of
one item, the array itself.
</p>
+ <p>It is a fast detector</p>
]]>
</Details>
</Detector>
+ <Detector class="com.mebigfatguy.fbcontrib.detect.PresizeCollections">
+ <Details>
+ <![CDATA[
+ <p> Looks for methods that create collections using the default constructor,
+ even though the number of elements that will be placed in the collection is known
+ apriori, and thus could be pre-allocated. Not doing so just causes more intermediate
+ reallocations which is unnecessary.
+ </p>
+ <p>It is a fast detector</p>
+ ]]>
+ </Details>
+ </Detector>
+
<!-- BugPattern -->
<BugPattern type="ISB_INEFFICIENT_STRING_BUFFERING">
@@ -1499,7 +1513,7 @@
<Details>
<![CDATA[
<p>This method uses floating point variables to index a loop. Since floating point
- math is inprecise, rounding errors will accumulate over time each time the loop is
+ math is imprecise, rounding errors will accumulate over time each time the loop is
executed. It is usually better to use integer indexing, and calculate the new value
of the floating point number at the top of the loop body.</p>
]]>
@@ -2542,6 +2556,19 @@
</Details>
</BugPattern>
+ <BugPattern type="SPP_STRINGBUILDER_IS_MUTABLE">
+ <ShortDescription>Method needlessly assigns a StringBuilder to itself, as it's mutable</ShortDescription>
+ <LongDescription>Method {1} needlessly assigns a StringBuilder to itself, as it's mutable</LongDescription>
+ <Details>
+ <![CDATA[
+ This method calls StringBuilder.append and assigns the results to the same StringBuilder as
+ <pre>sb = sb.append("foo")</pre>
+ As StringBuilder is mutable this is not necessary.
+ This is also true of StringBuffer.
+ ]]>
+ </Details>
+ </BugPattern>
+
<BugPattern type="BAS_BLOATED_ASSIGNMENT_SCOPE">
<ShortDescription>Method assigns a variable in a larger scope then is needed</ShortDescription>
<LongDescription>Method {1} assigns a variable in a larger scope then is needed</LongDescription>
@@ -2815,6 +2842,19 @@
</Details>
</BugPattern>
+ <BugPattern type="LO_LOGGER_LOST_EXCEPTION_STACK_TRACE">
+ <ShortDescription>Method incorrectly passes exception as first argument to logger method</ShortDescription>
+ <LongDescription>Method {1} incorrectly passes exception as first argument to logger method</LongDescription>
+ <Details>
+ <![CDATA[
+ <p>This method passes an exception as the first argument to a logger method. The stack
+ trace is potentially lost due to the logger emitting the exception using toString(). It
+ is better to construct a log message with sufficient context and pass the exception as
+ the second argument to capture the stack trace.</p>
+ ]]>
+ </Details>
+ </BugPattern>
+
<BugPattern type="LO_SUSPECT_LOG_CLASS">
<ShortDescription>Method specifies an unrelated class when allocating a Logger</ShortDescription>
<LongDescription>Method {1} specifies an unrelated class when allocating a Logger</LongDescription>
@@ -3096,7 +3136,7 @@
<Details>
<![CDATA[
<p>This method tests a field to make sure it's not null before executing a conditional block of
- code. However in the conditional block is reassigns the field. It is likely that the guard
+ code. However in the conditional block it reassigns the field. It is likely that the guard
should have been a check to see if the field is null, not that the field was not null.</p>
]]>
</Details>
@@ -3108,7 +3148,7 @@
<Details>
<![CDATA[
<p>This method tests a local variable to make sure it's not null before executing a conditional block of
- code. However in the conditional block is reassigns the local variable. It is likely that the guard
+ code. However in the conditional block it reassigns the local variable. It is likely that the guard
should have been a check to see if the local variable is null, not that the local variable was not null.</p>
]]>
</Details>
@@ -3518,6 +3558,19 @@
]]>
</Details>
</BugPattern>
+
+ <BugPattern type="PSC_PRESIZE_COLLECTIONS">
+ <ShortDescription>Method does not presize the allocation of a collection</ShortDescription>
+ <LongDescription>Method {1} does not presize the allocation of a collection</LongDescription>
+ <Details>
+ <![CDATA[
+ <p> This method allocates a collection using the default constructor even though it is known
+ apriori how many items are going to be placed in the collection (or at least a reasonable guess)
+ and thus needlessly causes intermediate reallocations of the collection.
+ </p>
+ ]]>
+ </Details>
+ </BugPattern>"
<!-- BugCode -->
@@ -3628,4 +3681,5 @@
<BugCode abbrev="BRPI">Backport concurrent reuse of public identifiers</BugCode>
<BugCode abbrev="CU">Clone Usability</BugCode>
<BugCode abbrev="CAAL">Confusing Array asList</BugCode>
+ <BugCode abbrev="PSC">Presize Collection</BugCode>
</MessageCollection>
Added: trunk/fb-contrib/samples/CAAL_Sample.java
===================================================================
--- trunk/fb-contrib/samples/CAAL_Sample.java (rev 0)
+++ trunk/fb-contrib/samples/CAAL_Sample.java 2013-03-04 04:47:55 UTC (rev 1742)
@@ -0,0 +1,38 @@
+import java.util.Arrays;
+import java.util.List;
+
+
+public class CAAL_Sample {
+
+ public void testCAAL(int[] v) {
+ List l = Arrays.asList(v);
+ }
+
+ public void testCAAL(char[] v) {
+ List l = Arrays.asList(v);
+ }
+
+ public void testCAAL(byte[] v) {
+ List l = Arrays.asList(v);
+ }
+
+ public void testCAAL(short[] v) {
+ List l = Arrays.asList(v);
+ }
+
+ public void testCAAL(long[] v) {
+ List l = Arrays.asList(v);
+ }
+
+ public void testCAAL(float[] v) {
+ List l = Arrays.asList(v);
+ }
+
+ public void testCAAL(double[] v) {
+ List l = Arrays.asList(v);
+ }
+
+ public void testCAAL(boolean[] v) {
+ List l = Arrays.asList(v);
+ }
+}
Property changes on: trunk/fb-contrib/samples/CAAL_Sample.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Added: trunk/fb-contrib/samples/CU_Sample.java
===================================================================
--- trunk/fb-contrib/samples/CU_Sample.java (rev 0)
+++ trunk/fb-contrib/samples/CU_Sample.java 2013-03-04 04:47:55 UTC (rev 1742)
@@ -0,0 +1,17 @@
+
+public class CU_Sample implements Cloneable {
+
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+
+ class CU_FP implements Cloneable {
+ public CU_FP clone() {
+ try {
+ return (CU_FP) super.clone();
+ } catch (CloneNotSupportedException cnse) {
+ throw new Error("Won't happen");
+ }
+ }
+ }
+}
Property changes on: trunk/fb-contrib/samples/CU_Sample.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Added: trunk/fb-contrib/samples/PSC_Sample.java
===================================================================
--- trunk/fb-contrib/samples/PSC_Sample.java (rev 0)
+++ trunk/fb-contrib/samples/PSC_Sample.java 2013-03-04 04:47:55 UTC (rev 1742)
@@ -0,0 +1,45 @@
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+
+public class PSC_Sample {
+
+ public void testPSC(List<PSC_Sample> samples) {
+ Set<String> names = new HashSet<String>();
+ for (PSC_Sample s : samples) {
+ names.add(s.toString());
+ }
+ }
+
+ public void testPSCEnumerated() {
+ Set<String> commonWords = new HashSet<String>();
+ commonWords.add("a");
+ commonWords.add("an");
+ commonWords.add("the");
+ commonWords.add("by");
+ commonWords.add("of");
+ commonWords.add("and");
+ commonWords.add("or");
+ commonWords.add("in");
+ commonWords.add("with");
+ commonWords.add("my");
+ commonWords.add("I");
+ commonWords.add("on");
+ commonWords.add("over");
+ commonWords.add("under");
+ commonWords.add("it");
+ commonWords.add("they");
+ commonWords.add("them");
+ }
+
+ public void testFPDontHaveCollectionForSizing(Iterator<Long> it) {
+ Deque<Long> ad = new ArrayDeque<Long>();
+ while (it.hasNext()) {
+ ad.add(it.next());
+ }
+ }
+}
Property changes on: trunk/fb-contrib/samples/PSC_Sample.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Modified: trunk/fb-contrib/samples/SPP_Sample.java
===================================================================
--- trunk/fb-contrib/samples/SPP_Sample.java 2013-02-10 02:29:13 UTC (rev 1741)
+++ trunk/fb-contrib/samples/SPP_Sample.java 2013-03-04 04:47:55 UTC (rev 1742)
@@ -18,40 +18,40 @@
public class SPP_Sample implements Serializable
{
public static final long serialVersionUID = -2766574418713802220L;
-
+
private static final double pi = 3.14;
private static final double e = 2.72;
public static final String FALSE_POSITIVE = "INTERN_OK_HERE".intern();
-
+
static enum Flap { Smack, Jack };
-
+
public void testSPPBitSet(BitSet b)
{
b.set(-1);
}
-
+
public String testSPPIntern()
{
return "FOO".intern(); //and yes i've seen this!
}
-
+
public String testSBWithChars()
{
StringBuffer sb = new StringBuffer('v');
sb.append("ictory");
return sb.toString();
}
-
+
public double area(double radius)
{
return pi * radius * radius;
}
-
+
public void testStutter(String s)
{
String a = a = s;
}
-
+
public void testNAN(double d)
{
if (d == Double.NaN)
@@ -59,7 +59,7 @@
System.out.println("It's a nan");
}
}
-
+
public void testNAN(float f)
{
if (f == Float.NaN)
@@ -67,17 +67,17 @@
System.out.println("It's a nan");
}
}
-
+
public void testBigDecimal()
{
BigDecimal d = new BigDecimal(2.1);
}
-
+
public void testEmptySB()
{
StringBuffer sb = new StringBuffer("");
}
-
+
public void equalsOnEnum(Flap f)
{
if (f.equals(Flap.Jack))
@@ -85,7 +85,7 @@
System.out.println("Flap Jacks");
}
}
-
+
public void testCPPBoolean(Boolean a, Boolean b, Boolean c, Boolean d, Boolean e)
{
if (b && b.booleanValue())
@@ -97,7 +97,7 @@
System.out.println("Booya");
}
}
-
+
public char usechatAt(String s)
{
if (s.length() > 0)
@@ -106,32 +106,32 @@
}
return ' ';
}
-
+
public boolean testUselessTrinary(boolean b)
{
return (b ? true : false);
}
-
+
public boolean testFPUselessTrinary(boolean a, boolean b)
{
if (a && b)
{
return a || b;
}
-
+
return a && b;
}
-
+
public boolean testFPTrinaryOnInt(String s)
{
return (s.length() != 0);
}
-
+
public void testSuspiciousStringTests(String s)
{
int a = 0, b = 0, c = 0, d = 0;
String e = "Foo";
-
+
if ((s == null) || (s.length() > 0))
{
System.out.println("Booya");
@@ -144,7 +144,7 @@
{
System.out.println("Booya");
}
-
+
if ((e == null) || (e.length() > 0))
{
System.out.println("Booya");
@@ -158,42 +158,42 @@
System.out.println("Booya");
}
}
-
+
public void testFPSST(String s)
{
int a = 0, b = 0, c = 0, d = 0;
String e = "Foo";
-
+
if ((s == null) || (s.length() == 0))
{
System.out.println("Booya");
}
-
+
if ((s != null) && (s.length() >= 0))
{
System.out.println("Booya");
}
-
+
if ((s != null) && (s.length() != 0))
{
System.out.println("Booya");
}
-
+
if ((e == null) || (e.length() == 0))
{
System.out.println("Booya");
}
-
+
if ((e != null) && (e.length() >= 0))
{
System.out.println("Booya");
}
-
+
if ((e != null) && (e.length() != 0))
{
System.out.println("Booya");
}
-
+
Set<String> m = new HashSet<String>();
Iterator<String> it = m.iterator();
while (it.hasNext())
@@ -203,11 +203,11 @@
{
continue;
}
-
+
System.out.println("Booya");
}
}
-
+
public void sbToString(StringBuffer sb)
{
if (sb.toString().length() == 0)
@@ -219,7 +219,7 @@
System.out.println("Booya");
}
}
-
+
public String cpNullOrZero(StringTokenizer tokenizer)
{
while (tokenizer.hasMoreTokens())
@@ -233,15 +233,15 @@
return sField;
}
-
+
return null;
}
-
+
public boolean testCalBeforeAfter(Calendar c, Date d)
{
return c.after(d) || c.before(d);
}
-
+
public void testUseContainsKey(Map m)
{
if (m.keySet().contains("Foo"))
@@ -249,87 +249,92 @@
System.out.println("Yup");
}
}
-
+
public void testCollectionSizeEqualsZero(Set<String> s)
{
if (s.size() == 0)
{
System.out.println("empty");
}
-
+
if (s.size() <= 0)
{
System.out.println("empty");
}
}
-
+
public boolean testDerivedGregorianCalendar()
{
Calendar c = new GregorianCalendar() {};
Calendar s = new GregorianCalendar();
-
+
return s.after(c);
}
-
+
public void testGetProperties()
{
String lf = System.getProperties().getProperty("line.separator");
}
-
+
public boolean testCasing(String a, String b)
{
if (a.toUpperCase().equalsIgnoreCase(b)) {
return true;
}
-
+
if (a.toLowerCase().compareToIgnoreCase(b) == 0) {
return true;
}
-
+
return false;
}
-
+
public void castRandomToInt() {
int i = (int)Math.random();
-
+
Random r = new Random();
i = (int) r.nextDouble();
-
+
i = (int) r.nextFloat();
}
-
+
public void testSAC(List<String> input)
{
String[] copy = new String[input.size()];
System.arraycopy(input, 0, copy, 0, copy.length);
-
+
System.arraycopy(copy, 0, input, 0, copy.length);
}
-
+
public void testArray()
{
List<String> notAnArray = new ArrayList<String>();
-
+
Array.getLength(notAnArray);
-
+
Array.getBoolean(notAnArray, 0);
-
+
Array.setInt(notAnArray, 0, 1);
}
-
+
public boolean testEmptyIgnoreCase(String s)
{
return (s.equalsIgnoreCase(""));
}
-
+
public void testTrim(String s)
{
if (s.trim().length() > 0)
System.out.println(s);
-
+
if (s.trim().equals("Booyah"))
{
System.out.println("Booyah->" + s);
}
}
+
+ public void testSBAssigning(StringBuilder sb) {
+ sb = sb.append("foo");
+ sb = sb.append("foo").append("boo").append("hoo");
+ }
}
Modified: trunk/fb-contrib/samples/WOC_Sample.java
===================================================================
--- trunk/fb-contrib/samples/WOC_Sample.java 2013-02-10 02:29:13 UTC (rev 1741)
+++ trunk/fb-contrib/samples/WOC_Sample.java 2013-03-04 04:47:55 UTC (rev 1742)
@@ -101,4 +101,22 @@
{
return ws.fpList;
}
+
+ public static class FpContains {
+ private List<String> fpSet;
+
+ public FpContains() {
+ fpSet = new ArrayList<String>();
+ }
+ public void add() {
+ fpSet.add("Foo");
+ }
+ protected void contains() {
+ for (int i = 0; i < 10; i++) {
+ if (fpSet.get(i) != null) {
+ System.out.println("Contains");
+ }
+ }
+ }
+ }
}
Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CloneUsability.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CloneUsability.java (rev 0)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CloneUsability.java 2013-03-04 04:47:55 UTC (rev 1742)
@@ -0,0 +1,110 @@
+/*
+ * fb-contrib - Auxiliary detectors for Java programs
+ * Copyright (C) 2005-2013 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 org.apache.bcel.Repository;
+import org.apache.bcel.classfile.ExceptionTable;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.Method;
+
+import edu.umd.cs.findbugs.BugInstance;
+import edu.umd.cs.findbugs.BugReporter;
+import edu.umd.cs.findbugs.Detector;
+import edu.umd.cs.findbugs.ba.ClassContext;
+import edu.umd.cs.findbugs.visitclass.PreorderVisitor;
+
+/**
+ * finds classes that implement clone() that do not specialize the return value, and do
+ * not swallow CloneNotFoundException. Not doing so makes the clone method not as simple
+ * to use, and should be harmless to do.
+ */
+public class CloneUsability extends PreorderVisitor implements Detector {
+
+ private static JavaClass CLONE_CLASS;
+
+ static {
+ try {
+ CLONE_CLASS = Repository.lookupClass("java.lang.Cloneable");
+ } catch (ClassNotFoundException cnfe) {
+ CLONE_CLASS = null;
+ }
+ }
+
+ private BugReporter bugReporter;
+ private String clsName;
+
+ /**
+ * constructs a CU detector given the reporter to report bugs on
+ * @param bugReporter the sync of bug reports
+ */
+ public CloneUsability(BugReporter bugReporter) {
+ this.bugReporter = bugReporter;
+ }
+
+ /**
+ * overrides the visitor to check for classes that implement Cloneable.
+ *
+ * @param classContext the context object that holds the JavaClass being parsed
+ */
+ public void visitClassContext(ClassContext classContext) {
+ try {
+ JavaClass cls = classContext.getJavaClass();
+ if (cls.implementationOf(CLONE_CLASS)) {
+ clsName = cls.getClassName();
+ cls.accept(this);
+ }
+ } catch (ClassNotFoundException cnfe) {
+ bugReporter.reportMissingClass(cnfe);
+ }
+ }
+
+ /**
+ * overrides the visitor to grab the method name and reset the state.
+ *
+ * @param obj the method being parsed
+ */
+ @Override
+ public void visitMethod(Method obj) {
+ if (obj.isPublic() && !obj.isSynthetic() && obj.getName().equals("clone") && (obj.getArgumentTypes().length == 0)) {
+
+ String returnClsName = obj.getReturnType().getSignature();
+ returnClsName = returnClsName.substring(1, returnClsName.length() - 1).replaceAll("/", ".");
+ if (!clsName.equals(returnClsName))
+ {
+ bugReporter.reportBug(new BugInstance(this, "CU_CLONE_USABILITY_OBJECT_RETURN", NORMAL_PRIORITY)
+ .addClass(this)
+ .addMethod(this));
+ }
+
+ ExceptionTable et = obj.getExceptionTable();
+
+ if ((et != null) && (et.getLength() > 0)) {
+ bugReporter.reportBug(new BugInstance(this, "CU_CLONE_USABILITY_THROWS", NORMAL_PRIORITY)
+ .addClass(this)
+ .addMethod(this));
+ }
+ }
+ }
+
+ /**
+ * implements the Detector with a nop
+ */
+ public void report() {
+ }
+}
Property changes on: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CloneUsability.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:mimetype
+ text/plain
Added: svn:eol-style
+ native
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CommonsEqualsBuilderToEquals.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CommonsEqualsBuilderToEquals.java 2013-02-10 02:29:13 UTC (rev 1741)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CommonsEqualsBuilderToEquals.java 2013-03-04 04:47:55 UTC (rev 1742)
@@ -81,7 +81,7 @@
String calledClass = stack.getStackItem(1).getSignature();
if ("Lorg/apache/commons/lang3/builder/EqualsBuilder;"
.equals(calledClass)
- || "org/apache/commons/lang/builder/EqualsBuilder"
+ || "Lorg/apache/commons/lang/builder/EqualsBuilder;"
.equals(calledClass)) {
bugReporter.reportBug(new BugInstance(this,
"CEBE_COMMONS_EQUALS_BUILDER_ISEQUALS",
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CommonsHashcodeBuilderToHashcode.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CommonsHashcodeBuilderToHashcode.java 2013-02-10 02:29:13 UTC (rev 1741)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CommonsHashcodeBuilderToHashcode.java 2013-03-04 04:47:55 UTC (rev 1742)
@@ -81,7 +81,7 @@
String calledClass = stack.getStackItem(0).getSignature();
if ("Lorg/apache/commons/lang3/builder/HashCodeBuilder;"
.equals(calledClass)
- || "org/apache/commons/lang/builder/HashCodeBuilder"
+ || "Lorg/apache/commons/lang/builder/HashCodeBuilder;"
.equals(calledClass)) {
bugReporter.reportBug(new BugInstance(this,
"CHTH_COMMONS_HASHCODE_BUILDER_TOHASHCODE",
Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConfusingArrayAsList.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConfusingArrayAsList.java (rev 0)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConfusingArrayAsList.java 2013-03-04 04:47:55 UTC (rev 1742)
@@ -0,0 +1,119 @@
+/*
+ * fb-contrib - Auxiliary detectors for Java programs
+ * Copyright (C) 2005-2013 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.HashSet;
+import java.util.Set;
+
+import org.apache.bcel.classfile.Code;
+
+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.ba.ClassContext;
+
+/**
+ *
+ * looks for calls to Arrays.asList where the parameter is a primitive array.
+ * This does not produce a list that holds the primitive boxed value, but a list of
+ * one item, the array itself.
+ *
+ */
+public class ConfusingArrayAsList extends BytecodeScanningDetector {
+
+ private static Set<String> PRIMITIVE_ARRAYS = new HashSet<String>();
+ static {
+ PRIMITIVE_ARRAYS.add("[[B");
+ PRIMITIVE_ARRAYS.add("[[C");
+ PRIMITIVE_ARRAYS.add("[[S");
+ PRIMITIVE_ARRAYS.add("[[I");
+ PRIMITIVE_ARRAYS.add("[[J");
+ PRIMITIVE_ARRAYS.add("[[F");
+ PRIMITIVE_ARRAYS.add("[[D");
+ PRIMITIVE_ARRAYS.add("[[Z");
+
+ }
+ private BugReporter bugReporter;
+ private OpcodeStack stack;
+
+ /**
+ * constructs a CAAL detector given the reporter to report bugs on
+ * @param bugReporter the sync of bug reports
+ */
+ public ConfusingArrayAsList(BugReporter bugReporter) {
+ this.bugReporter = bugReporter;
+ }
+
+ /**
+ * implements the visitor to create and teardown the opcode stack
+ *
+ * @param classContext the context object of the currently parsed class
+ */
+ @Override
+ public void visitClassContext(ClassContext classContext) {
+ try {
+ stack = new OpcodeStack();
+ super.visitClassContext(classContext);
+ } finally {
+ stack = null;
+ }
+ }
+
+ /**
+ * implements the visitor to clear the opcode stack
+ *
+ * @param seen the currently code block
+ */
+ public void visitCode(Code obj) {
+ stack.resetForMethodEntry(this);
+ super.visitCode(obj);
+ }
+
+ /**
+ * implements the visitor to find calls to Arrays.asList with a primitive array
+ *
+ * @param seen the currently visitor opcode
+ */
+ @Override
+ public void sawOpcode(int seen) {
+ try {
+ if (seen == INVOKESTATIC) {
+ String clsName = getClassConstantOperand();
+ if ("java/util/Arrays".equals(clsName)) {
+ String methodName = getNameConstantOperand();
+ if ("asList".equals(methodName)) {
+ if (stack.getStackDepth() == 1) {
+ OpcodeStack.Item item = stack.getStackItem(0);
+ String sig = item.getSignature();
+ if (PRIMITIVE_ARRAYS.contains(sig)) {
+ bugReporter.reportBug(new BugInstance(this, "CAAL_CONFUSING_ARRAY_AS_LIST", NORMAL_PRIORITY)
+ .addClass(this)
+ .addMethod(this)
+ .addSourceLine(this));
+ }
+ }
+ }
+ }
+ }
+ } finally {
+ stack.sawOpcode(this, seen);
+ }
+ }
+}
Property changes on: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConfusingArrayAsList.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:mimetype
+ text/plain
Added: svn:eol-style
+ native
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LoggerOddities.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LoggerOddities.java 2013-02-10 02:29:13 UTC (rev 1741)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LoggerOddities.java 2013-03-04 04:47:55 UTC (rev 1742)
@@ -266,7 +266,15 @@
}
}
}
- }
+ } else if ("(Ljava/lang/Object;)V".equals(sig)) {
+ final JavaClass clazz = stack.getStackItem(0).getJavaClass();
+ if(clazz.instanceOf(THROWABLE_CLASS)) {
+ bugReporter.reportBug(new BugInstance(this, "LO_LOGGER_LOST_EXCEPTION_STACK_TRACE", NORMAL_PRIORITY)
+ .addClass(this)
+ .addMethod(this)
+ .addSourceLine(this));
+ }
+ }
}
}
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java 2013-02-10 02:29:13 UTC (rev 1741)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java 2013-03-04 04:47:55 UTC (rev 1742)
@@ -74,7 +74,10 @@
riskyMethodNameContents.add("clone");
riskyMethodNameContents.add("close");
riskyMethodNameContents.add("copy");
- riskyMethodNameContents.add("currentTimeMillis");
+ riskyMethodNameContents.add("currentTimeMillis");
+ riskyMethodNameContents.add("newInstance");
+ riskyMethodNameContents.add("noneOf");
+ riskyMethodNameContents.add("allOf");
String userNameProp = System.getProperty(PRMC_RISKY_FIELD_USER_KEY);
if (userNameProp != null) {
Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PresizeCollections.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PresizeCollections.java (rev 0)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PresizeCollections.java 2013-03-04 04:47:55 UTC (rev 1742)
@@ -0,0 +1,179 @@
+/*
+ * fb-contrib - Auxiliary detectors for Java programs
+ * Copyright (C) 2005-2013 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.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.bcel.classfile.Code;
+import org.apache.bcel.generic.Type;
+
+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.ba.ClassContext;
+
+/**
+ * finds methods that create and populate collections, and while knowing
+ * the end size of those collections, does not pre allocate the collection
+ * to be big enough. This just causes unneeded reallocations putting strain
+ * on the garbage collector. */
+public class PresizeCollections extends BytecodeScanningDetector {
+
+ private static final Set<String> PRESIZEABLE_COLLECTIONS = new HashSet<String>();
+ static {
+ PRESIZEABLE_COLLECTIONS.add("java/util/ArrayBlockingQueue");
+ PRESIZEABLE_COLLECTIONS.add("java/util/ArrayDeque");
+ PRESIZEABLE_COLLECTIONS.add("java/util/ArrayList");
+ PRESIZEABLE_COLLECTIONS.add("java/util/HashSet");
+ PRESIZEABLE_COLLECTIONS.add("java/util/LinkedBlockingQueue");
+ PRESIZEABLE_COLLECTIONS.add("java/util/LinkedHashSet");
+ PRESIZEABLE_COLLECTIONS.add("java/util/PriorityBlockingQueue");
+ PRESIZEABLE_COLLECTIONS.add("java/util/PriorityQueue");
+ PRESIZEABLE_COLLECTIONS.add("java/util/TreeSet");
+ PRESIZEABLE_COLLECTIONS.add("java/util/Vector");
+ }
+
+ private BugReporter bugReporter;
+ private OpcodeStack stack;
+ private int allocNumber;
+ private Map<Integer, List<Integer>> allocToAddPCs;
+
+ public PresizeCollections(BugReporter bugReporter) {
+ this.bugReporter = bugReporter;
+ }
+
+ /**
+ * overrides the visitor to initialize the opcode stack
+ *
+ * @param classContext the context object that holds the JavaClass being parsed
+ */
+ public void visitClassContext(ClassContext classContext) {
+ try {
+ stack = new OpcodeStack();
+ allocToAddPCs = new HashMap<Integer, List<Integer>>();
+ super.visitClassContext(classContext);
+ } finally {
+ stack = null;
+ allocToAddPCs = null;
+ }
+ }
+
+ /**
+ * implements the visitor to reset the opcode stack
+ * @param obj the context object of the currently parsed code block
+ */
+ @Override
+ public void visitCode(Code obj) {
+ stack.resetForMethodEntry(this);
+ allocNumber = 0;
+ allocToAddPCs.clear();
+ super.visitCode(obj);
+
+ for (List<Integer> pcs : allocToAddPCs.values()) {
+ if (pcs.size() > 16) {
+ bugReporter.reportBug(new BugInstance(this, "PSC_PRESIZE_COLLECTIONS", NORMAL_PRIORITY)
+ .addClass(this)
+ .addMethod(this)
+ .addSourceLine(this, pcs.get(0)));
+ }
+ }
+ }
+
+ /**
+ * implements the visitor to look for creation of collections
+ * that are then populated with a known number of elements usually
+ * based on another collection, but the new collection is not presized.
+ * @param seen the opcode of the currently parsed instruction
+ */
+ @Override
+ public void sawOpcode(int seen) {
+ boolean sawAlloc = false;
+ try {
+ switch (seen) {
+ case INVOKESPECIAL:
+ String clsName = getClassConstantOperand();
+ if (PRESIZEABLE_COLLECTIONS.contains(clsName)) {
+ String methodName = getNameConstantOperand();
+ if ("<init>".equals(methodName)) {
+ String signature = getSigConstantOperand();
+ if ("()V".equals(signature)) {
+ sawAlloc = true;
+ }
+ }
+ }
+ break;
+
+ case INVOKEINTERFACE:
+ String methodName = getNameConstantOperand();
+ if ("add".equals(methodName) || "addAll".equals(methodName)) {
+ String signature = getSigConstantOperand();
+ Type[] argTypes = Type.getArgumentTypes(signature);
+ if ((argTypes.length == 1) && (stack.getStackDepth() > 1)) {
+ OpcodeStack.Item item = stack.getStackItem(1);
+ Integer allocNum = (Integer) item.getUserValue();
+ if (allocNum != null) {
+ List<Integer> lines = allocToAddPCs.get(allocNum);
+ if (lines == null) {
+ lines = new ArrayList<Integer>();
+ allocToAddPCs.put(allocNum, lines);
+ }
+ lines.add(getPC());
+ }
+ }
+ }
+ break;
+
+ case GOTO:
+ case GOTO_W:
+ if (getBranchOffset() < 0) {
+ int target = getBranchTarget();
+ Iterator<List<Integer>> it = allocToAddPCs.values().iterator();
+ while (it.hasNext()) {
+ List<Integer> pcs = it.next();
+ for (Integer pc : pcs) {
+ if (pc > target) {
+ bugReporter.reportBug(new BugInstance(this, "PSC_PRESIZE_COLLECTIONS", NORMAL_PRIORITY)
+ .addClass(this)
+ .addMethod(this)
+ .addSourceLine(this, pc));
+ it.remove();
+ break;
+ }
+ }
+ }
+ }
+ }
+ } finally {
+ stack.sawOpcode(this, seen);
+ if (sawAlloc) {
+ if (stack.getStackDepth() > 0) {
+ OpcodeStack.Item item = stack.getStackItem(0);
+ item.setUserValue(Integer.valueOf(++allocNumber));
+ }
+ }
+ }
+ }
+}
Property changes on: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PresizeCollections.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:mimetype
+ text/plain
Added: svn:eol-style
+ native
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2013-02-10 02:29:13 UTC (rev 1741)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2013-03-04 04:47:55 UTC (rev 1742)
@@ -1,17 +1,17 @@
/*
* fb-contrib - Auxiliary detectors for Java programs
* Copyright (C) 2005-2013 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
@@ -51,7 +51,7 @@
/**
* looks for silly bugs that are simple but do not fit into one large pattern.
*/
-public class SillynessPotPourri extends BytecodeScanningDetector
+public class SillynessPotPourri extends BytecodeScanningDetector
{
private static final Set<String> collectionInterfaces = new HashSet<String>();
static {
@@ -62,7 +62,7 @@
collectionInterfaces.add("java/util/Map");
collectionInterfaces.add("java/util/SortedMap");
}
-
+
private static JavaClass calendarClass;
static {
try {
@@ -71,7 +71,7 @@
calendarClass = null;
}
}
-
+
private final BugReporter bugReporter;
private OpcodeStack stack;
private int lastPCs[];
@@ -81,7 +81,7 @@
private boolean lastLoadWasString;
/** branch targets, to a set of branch instructions */
private Map<Integer, Set<Integer>> branchTargets;
-
+
/**
* constructs a SPP detector given the reporter to report bugs on
* @param bugReporter the sync of bug reports
@@ -89,7 +89,7 @@
public SillynessPotPourri(BugReporter bugReporter) {
this.bugReporter = bugReporter;
}
-
+
@Override
public void visitField(Field field) {
if ("serialVersionUID".equals(field.getName())
@@ -100,7 +100,7 @@
.addField(this));
}
}
-
+
@Override
public void visitClassContext(ClassContext classContext) {
try {
@@ -114,10 +114,10 @@
branchTargets = null;
}
}
-
+
/**
* implements the visitor to reset the opcode stack
- *
+ *
* @param obj the context object for the currently parsed Code
*/
@Override
@@ -131,17 +131,17 @@
branchTargets.clear();
super.visitCode(obj);
}
-
+
/**
* implements the visitor to look for various silly bugs
- *
+ *
* @param seen the opcode of the currently parsed instruction
*/
@Override
public void sawOpcode(int seen) {
int reg = -1;
String userValue = null;
- try {
+ try {
if (((seen >= IFEQ) && (seen <= GOTO)) || (seen == IFNULL) || (seen == IFNONNULL) || (seen == GOTO_W)) {
Integer branchTarget = Integer.valueOf(getBranchTarget());
Set<Integer> branchInsSet = branchTargets.get(branchTarget);
@@ -152,13 +152,13 @@
}
branchInsSet.add(Integer.valueOf(getPC()));
}
-
+
if ((seen == IFEQ) || (seen == IFLE) || (seen == IFNE)) {
if (lastLoadWasString && (lastPCs[0] != -1)) {
byte[] bytes = getCode().getCode();
int loadIns = CodeByteUtils.getbyte(bytes, lastPCs[2]);
int brOffset = (loadIns == ALOAD) ? 11 : 10;
-
+
if ((((loadIns >= ALOAD_0) && (loadIns <= ALOAD_3)) || (loadIns == ALOAD))
&& (CodeByteUtils.getbyte(bytes, lastPCs[3]) == INVOKEVIRTUAL)
&& (CodeByteUtils.getbyte(bytes, lastPCs[2]) == loadIns)
@@ -183,7 +183,7 @@
}
}
}
-
+
if ((seen == IFEQ) || (seen == IFNE) || (seen == IFGT)) {
if (stack.getStackDepth() == 1) {
OpcodeStack.Item item = stack.getStackItem(0);
@@ -195,7 +195,7 @@
}
}
}
-
+
if (seen == IFNE) {
byte[] bytes = getCode().getCode();
if (lastPCs[2] != -1) {
@@ -228,7 +228,7 @@
OpcodeStack.Item itm = stack.getStackItem(0);
lastIfEqWasBoolean = "Z".equals(itm.getSignature());
}
-
+
byte[] bytes = getCode().getCode();
if (lastPCs[1] != -1) {
int loadIns = CodeByteUtils.getbyte(bytes, lastPCs[2]);
@@ -266,7 +266,7 @@
} else if ((seen == IRETURN) && lastIfEqWasBoolean) {
byte[] bytes = getCode().getCode();
if ((lastPCs[0] != -1)
- && ((0x00FF & bytes[lastPCs[3]]) == ICONST_0)
+ && ((0x00FF & bytes[lastPCs[3]]) == ICONST_0)
&& ((0x00FF & bytes[lastPCs[2]]) == GOTO)
&& ((0x00FF & bytes[lastPCs[1]]) == ICONST_1)
&& ((0x00FF & bytes[lastPCs[0]]) == IFEQ)) {
@@ -282,7 +282,7 @@
{
bug = false;
}
-
+
if (bug) {
bugReporter.reportBug(new BugInstance(this, "SPP_USELESS_TRINARY", NORMAL_PRIORITY)
.addClass(this)
@@ -297,7 +297,7 @@
double d = ((ConstantDouble) con).getBytes();
double piDelta = Math.abs(d - Math.PI);
double eDelta = Math.abs(d - Math.E);
-
+
if (((piDelta > 0.0) && (piDelta < 0.002))
|| ((eDelta > 0.0) && (eDelta < 0.002))) {
bugReporter.reportBug(new BugInstance(this, "SPP_USE_MATH_CONSTANT", NORMAL_PRIORITY)
@@ -312,7 +312,7 @@
Double d1 = (Double)item.getConstant();
item = stack.getStackItem(1);
Double d2 = (Double)item.getConstant();
-
+
if (((d1 != null) && d1.isNaN()) || ((d2 != null) && d2.isNaN())) {
bugReporter.reportBug(new BugInstance(this, "SPP_USE_ISNAN", NORMAL_PRIORITY)
.addClass(this)
@@ -326,7 +326,7 @@
Float f1 = (Float)item.getConstant();
item = stack.getStackItem(1);
Float f2 = (Float)item.getConstant();
-
+
if (((f1 != null) && f1.isNaN()) || ((f2 != null) && f2.isNaN())) {
bugReporter.reportBug(new BugInstance(this, "SPP_USE_ISNAN", NORMAL_PRIORITY)
.addClass(this)
@@ -346,8 +346,17 @@
}
if (stack.getStackDepth() > 0) {
OpcodeStack.Item item = stack.getStackItem(0);
- if ("trim".equals(item.getUserValue())) {
+ String mName = (String) item.getUserValue();
+ if ("trim".equals(mName)) {
item.setUserValue(null);
+ } else if ((mName != null) && (mName.startsWith("append:"))) {
+ int appendReg = Integer.parseInt(mName.substring("append:".length()));
+ if (reg == appendReg) {
+ bugReporter.reportBug(new BugInstance(this, "SPP_STRINGBUILDER_IS_MUTABLE", NORMAL_PRIORITY)
+ .addClass(this)
+ .addMethod(this)
+ .addSourceLine(this));
+ }
}
}
} else if (((seen >= ALOAD_0) && (seen <= ASTORE_3)) || (seen == ALOAD)) {
@@ -425,7 +434,7 @@
}
}
}
-
+
}
} else if (seen == INVOKEVIRTUAL) {
String className = getClassConstantOperand();
@@ -448,6 +457,16 @@
}
}
}
+ } else if ("java/lang/StringBuilder".equals(className) || "java/lang/StringBuffer".equals(className)) {
+ if ("append".equals(methodName)) {
+ if (stack.getStackDepth() > 1) {
+ OpcodeStack.Item item = stack.getStackItem(1);
+ if (item.getRegisterNumber() > -1)
+ userValue = "append:" + item.getRegisterNumber();
+ else
+ userValue = (String) item.getUserValue();
+ }
+ }
} else if ("java/lang/String".equals(className)) {
if ("intern".equals(methodName)) {
String owningMethod = getMethod().getName();
@@ -468,7 +487,7 @@
} else if ("toLowerCase".equals(methodName)
|| "toUpperCase".equals(methodName)) {
userValue = "IgnoreCase";
- } else if ("equalsIgnoreCase".equals(methodName)
+ } else if ("equalsIgnoreCase".equals(methodName)
|| "compareToIgnoreCase".equals(methodName)) {
if (stack.getStackDepth() > 1) {
OpcodeStack.Item item = stack.getStackItem(1);
@@ -506,7 +525,7 @@
bugReporter.reportBug(new BugInstance(this, "SPP_TEMPORARY_TRIM", NORMAL_PRIORITY)
.addClass(this)
.addMethod(this)
- .addSourceLine(this));
+ .addSourceLine(this));
}
}
}
@@ -539,7 +558,7 @@
break;
}
}
-
+
if (found) {
bugReporter.reportBug(new BugInstance(this, "SPP_INVALID_BOOLEAN_NULL_CHECK", NORMAL_PRIORITY)
.addClass(this)
@@ -563,11 +582,11 @@
.addClass(this)
.addMethod(this)
.addSourceLine(this));
- }
+ }
} catch (ClassNotFoundException cnfe) {
bugReporter.reportMissingClass(cnfe);
}
-
+
}
}
} else if ("java/util/Properties".equals(className)) {
@@ -597,10 +616,10 @@
Object o = item.getConstant();
if (o instanceof Integer) {
int parm = ((Integer) o).intValue();
- if ((parm > 32)
- && (parm < 127)
+ if ((parm > 32)
+ && (parm < 127)
&& (parm != 64)
- && ((parm % 10) != 0)
+ && ((parm % 10) != 0)
&& ((parm % 5) != 0)) {
bugReporter.reportBug(new BugInstance(this, "SPP_NO_CHAR_SB_CTOR", LOW_PRIORITY)
.addClass(this)
@@ -619,8 +638,8 @@
.addClass(this)
.addMethod(this)
.addSourceLine(this));
- }
- }
+ }
+ }
}
}
} else if ("java/math/BigDecimal".equals(className)) {
@@ -657,7 +676,7 @@
}
}
}
-
+
if (collectionInterfaces.contains(className)) {
String method = getNameConstantOperand();
if ("size".equals(method)) {
@@ -665,7 +684,7 @@
}
}
}
-
+
} finally {
TernaryPatcher.pre(stack, seen);
stack.sawOpcode(this, seen);
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/WriteOnlyCollection.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/WriteOnlyCollection.java 2013-02-10 02:29:13 UTC (rev 1741)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/WriteOnlyCollection.java 2013-03-04 04:47:55 UTC (rev 1742)
@@ -28,6 +28,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Queue;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
@@ -70,6 +71,7 @@
collectionClasses.add(Vector.class.getName());
collectionClasses.add(ArrayList.class.getName());
collectionClasses.add(LinkedList.class.getName());
+ collectionClasses.add(Queue.class.getName());
}
private static Set<String> writeMethods = new HashSet<String>();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|