Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * fb-contrib - Auxiliary detectors for Java programs
   * Copyright (C) 2005-2014 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.Map;
 import java.util.Set;
 
 import  org.apache.bcel.Constants;
 import  org.apache.bcel.Repository;
 import  org.apache.bcel.classfile.Code;
 import  org.apache.bcel.classfile.Constant;
 import  org.apache.bcel.classfile.ConstantDouble;
 import  org.apache.bcel.classfile.ConstantMethodref;
 import  org.apache.bcel.classfile.ConstantNameAndType;
 import  org.apache.bcel.classfile.ConstantPool;
 import  org.apache.bcel.classfile.ConstantString;
 import  org.apache.bcel.classfile.ConstantValue;
 import  org.apache.bcel.classfile.Field;
 import  org.apache.bcel.classfile.JavaClass;
 import  org.apache.bcel.classfile.LocalVariable;
 import  org.apache.bcel.classfile.LocalVariableTable;
 
 
looks for silly bugs that are simple but do not fit into one large pattern.
 
 public class SillynessPotPourri extends BytecodeScanningDetector
 {
 	private static final Set<StringcollectionInterfaces = new HashSet<String>();
 	static {
 		.add("java/util/Collection");
 		.add("java/util/List");
 		.add("java/util/Set");
 		.add("java/util/SortedSet");
 		.add("java/util/Map");
 		.add("java/util/SortedMap");
 	}
 	
 	private static final String LITERAL = "literal";
 	private static final Pattern APPEND_PATTERN = Pattern.compile("append:([0-9]+):(.*)");
 
 	private static JavaClass calendarClass;
 	static {
 		try {
 			 = Repository.lookupClass("java/util/Calendar");
 		} catch (ClassNotFoundException cnfe) {
 			 = null;
 		}
 	}
 
 	private final BugReporter bugReporter;
 	private final Set<StringtoStringClasses;
 	private OpcodeStack stack;
 	private int lastPCs[];
 	private int lastOpcode;
 	private int lastReg;
 	private boolean lastIfEqWasBoolean;
 	private boolean lastLoadWasString;
branch targets, to a set of branch instructions
 
 	private Set<StringstaticConstants;

constructs a SPP detector given the reporter to report bugs on

Parameters:
bugReporter the sync of bug reports
	public SillynessPotPourri(BugReporter bugReporter) {
		this. = bugReporter;
	}
	public void visitField(Field field) {
	    if ("serialVersionUID".equals(field.getName())
	    &&  ((field.getAccessFlags() & ACC_STATIC) != 0)
	    &&  ((field.getAccessFlags() & ACC_PRIVATE) == 0)) {
	        .reportBug(new BugInstance(this"SPP_SERIALVER_SHOULD_BE_PRIVATE", LOW_PRIORITY)
	                                    .addClass(this)
	                                    .addField(this));
	    }
	}
	public void visitClassContext(ClassContext classContext) {
		try {
			 = new OpcodeStack();
			 = new int[4];
			super.visitClassContext(classContext);
finally {
			 = null;
			 = null;
			 = null;
		}
	}

implements the visitor to reset the opcode stack

Parameters:
obj the context object for the currently parsed Code
	public void visitCode(Code obj) {
		 = -1;
		 = -1;
		Arrays.fill(, -1);
		super.visitCode(obj);
	}

implements the visitor to look for various silly bugs

Parameters:
seen the opcode of the currently parsed instruction
	public void sawOpcode(int seen) {
		int reg = -1;
		String userValue = null;
		try {
	        .precomputation(this);
	        
			if (((seen >= IFEQ) && (seen <= GOTO)) || (seen == IFNULL) || (seen == IFNONNULL) || (seen == GOTO_W)) {
				Integer branchTarget = Integer.valueOf(getBranchTarget());
				BitSet branchInsSet = .get(branchTarget);
				if (branchInsSet == null)
				{
					branchInsSet = new BitSet();
					.put(branchTargetbranchInsSet);
				}
				branchInsSet.set(getPC());
			}
			if ((seen == IFEQ) || (seen == IFLE) || (seen == IFNE)) {
				if ( && ([0] != -1)) {
					byte[] bytes = getCode().getCode();
					int loadIns = CodeByteUtils.getbyte(bytes[2]);
					int brOffset = (loadIns == ALOAD) ? 11 : 10;
					if ((((loadIns >= ALOAD_0) && (loadIns <= ALOAD_3)) || (loadIns == ALOAD))
					&&  (CodeByteUtils.getbyte(bytes[3]) == INVOKEVIRTUAL)
					&&  (CodeByteUtils.getbyte(bytes[2]) == loadIns)
					&&  (CodeByteUtils.getbyte(bytes[1]) == IFNULL)
					&&  (CodeByteUtils.getbyte(bytes[0]) == loadIns)
					&&  ((loadIns != ALOAD) || (CodeByteUtils.getbyte(bytes[2]+1) == CodeByteUtils.getbyte(bytes[0]+1)))
					&&  ((seen == IFNE) ? CodeByteUtils.getshort(bytes[1]+1) > brOffset : CodeByteUtils.getshort(bytes[1]+1) == brOffset)) {
						int nextOp = CodeByteUtils.getbyte(bytesgetNextPC());
						if ((nextOp != GOTO) && (nextOp != GOTO_W)) {
							ConstantPool pool = getConstantPool();
							int mpoolIndex = CodeByteUtils.getshort(bytes[3]+1);
							ConstantMethodref cmr = (ConstantMethodref)pool.getConstant(mpoolIndex);
							int nandtIndex = cmr.getNameAndTypeIndex();
							ConstantNameAndType cnt = (ConstantNameAndType)pool.getConstant(nandtIndex);
							if ("length".equals(cnt.getName(pool))) {
								.reportBug(new BugInstance(this"SPP_SUSPECT_STRING_TEST", NORMAL_PRIORITY)
											.addClass(this)
											.addMethod(this)
											.addSourceLine(this));
							}
						}
					}
				}
			}
			if ((seen == IFEQ) || (seen == IFNE) || (seen == IFGT)) {
				if (.getStackDepth() == 1) {
					if ("size".equals(item.getUserValue())) {
						.reportBug(new BugInstance(this"SPP_USE_ISEMPTY", NORMAL_PRIORITY)
								   .addClass(this)
								   .addMethod(this)
								   .addSourceLine(this));
					}
				}
			}
			if (seen == IFEQ) {
			    byte[] bytes = getCode().getCode();
			    if (([0] != -1) && (CodeByteUtils.getbyte(bytes[1]) == IFNULL) && (CodeByteUtils.getbyte(bytes[3]) == INSTANCEOF)) {
    			    int ins0 = CodeByteUtils.getbyte(bytes[0]);
    			    if ((ins0 == ALOAD) || (ins0 == ALOAD_0) || (ins0 == ALOAD_1) || (ins0 == ALOAD_2) || (ins0 == ALOAD_3)) {
    			        int ins2 = CodeByteUtils.getbyte(bytes[0]);
    			        if (ins0 == ins2) {
    			            if ((ins0 != ALOAD) || (CodeByteUtils.getbyte(bytes[0] + 1) == CodeByteUtils.getbyte(bytes[2] + 1))) {
    			                int ifNullTarget = [1] + CodeByteUtils.getshort(bytes[1]+1);
    			                if (ifNullTarget == getBranchTarget()) {
        			                .reportBug(new BugInstance(this"SPP_NULL_BEFORE_INSTANCEOF", NORMAL_PRIORITY)
        			                        .addClass(this)
        			                        .addMethod(this)
        			                        .addSourceLine(this));
    			                }
    			            }
    			        }
    			    }
			    }
			}
			if (seen == IFNE) {
				byte[] bytes = getCode().getCode();
				if ([2] != -1) {
					if ((CodeByteUtils.getbyte(bytes[3]) == INVOKEVIRTUAL)
					&&  (CodeByteUtils.getbyte(bytes[2]) == INVOKEVIRTUAL)) {
						ConstantPool pool = getConstantPool();
						int toStringIndex = CodeByteUtils.getshort(bytes[2]+1);
						ConstantMethodref toStringMR = (ConstantMethodref)pool.getConstant(toStringIndex);
						String toStringCls = toStringMR.getClass(pool);
						if (toStringCls.startsWith("java.lang.StringBu")) {
							int nandtIndex = toStringMR.getNameAndTypeIndex();
							ConstantNameAndType cnt = (ConstantNameAndType)pool.getConstant(nandtIndex);
							if ("toString".equals(cnt.getName(pool))) {
								int lengthIndex = CodeByteUtils.getshort(bytes[3]+1);
								ConstantMethodref lengthMR = (ConstantMethodref)pool.getConstant(lengthIndex);
								nandtIndex = lengthMR.getNameAndTypeIndex();
								cnt = (ConstantNameAndType)pool.getConstant(nandtIndex);
								if ("length".equals(cnt.getName(pool))) {
									.reportBug(new BugInstance(this"SPP_USE_STRINGBUILDER_LENGTH", NORMAL_PRIORITY)
												.addClass(this)
												.addMethod(this)
												.addSourceLine(this));
								}
							}
						}
					}
				}
else if (seen == IFEQ) {
				if (.getStackDepth() > 0) {
				}
				byte[] bytes = getCode().getCode();
				if ([1] != -1) {
					if (CodeByteUtils.getbyte(bytes[3]) == INVOKEVIRTUAL) {
	                    int loadIns = CodeByteUtils.getbyte(bytes[2]);
    					if  (((loadIns == LDC) || (loadIns == LDC_W))
    					&&  (CodeByteUtils.getbyte(bytes[1]) == INVOKEVIRTUAL)) {
    						ConstantPool pool = getConstantPool();
    						int toStringIndex = CodeByteUtils.getshort(bytes[1]+1);
    						Constant cmr = pool.getConstant(toStringIndex);
    						if (cmr instanceof ConstantMethodref) {
        						ConstantMethodref toStringMR = (ConstantMethodref)cmr;
        						String toStringCls = toStringMR.getClass(pool);
        						if (toStringCls.startsWith("java.lang.&&StringBu")) {
        							int consIndex = CodeByteUtils.getbyte(bytes[2]+1);
        							Constant c = pool.getConstant(consIndex);
        							if (c instanceof ConstantString) {
        								if ("".equals(((ConstantString) c).getBytes(pool))) {
        									int nandtIndex = toStringMR.getNameAndTypeIndex();
        									ConstantNameAndType cnt = (ConstantNameAndType)pool.getConstant(nandtIndex);
        									if ("toString".equals(cnt.getName(pool))) {
        										int lengthIndex = CodeByteUtils.getshort(bytes[3]+1);
        										ConstantMethodref lengthMR = (ConstantMethodref)pool.getConstant(lengthIndex);
        										nandtIndex = lengthMR.getNameAndTypeIndex();
        										cnt = (ConstantNameAndType)pool.getConstant(nandtIndex);
        										if ("equals".equals(cnt.getName(pool))) {
        											.reportBug(new BugInstance(this"SPP_USE_STRINGBUILDER_LENGTH", NORMAL_PRIORITY)
        														.addClass(this)
        														.addMethod(this)
        														.addSourceLine(this));
        										}
        									}
        								}
        							}
        						}
    						}
    					}
					}
				}
else if ((seen == IRETURN) && ) {
				byte[] bytes = getCode().getCode();
				if (([0] != -1)
				&&  ((0x00FF & bytes[[3]]) == ICONST_0)
				&&  ((0x00FF & bytes[[2]]) == GOTO)
				&&  ((0x00FF & bytes[[1]]) == ICONST_1)
				&&  ((0x00FF & bytes[[0]]) == IFEQ)) {
					if (getMethod().getSignature().endsWith("Z")) {
						boolean bug = true;
						BitSet branchInsSet = .get(Integer.valueOf([1]));
						if (branchInsSet != null)
                        {
                            bug = false;
                        }
						branchInsSet = .get(Integer.valueOf([3]));
						if ((branchInsSet != null) && (branchInsSet.cardinality() > 1))
                        {
                            bug = false;
                        }
						if (bug) {
							.reportBug(new BugInstance(this"SPP_USELESS_TERNARY", NORMAL_PRIORITY)
										.addClass(this)
										.addMethod(this)
										.addSourceLine(this));
						}
					}
				}
else if (seen == LDC2_W) {
				if (con instanceof ConstantDouble) {
					double d = ((ConstantDouble) con).getBytes();
					double piDelta = Math.abs(d - .);
					double eDelta = Math.abs(d - .);
					if (((piDelta > 0.0) && (piDelta < 0.002))
					||  ((eDelta > 0.0) && (eDelta < 0.002))) {
						.reportBug(new BugInstance(this"SPP_USE_MATH_CONSTANT", NORMAL_PRIORITY)
								   .addClass(this)
								   .addMethod(this)
								   .addSourceLine(this));
					}
				}
else if (seen == DCMPL) {
				if (.getStackDepth() > 1) {
					Double d1 = (Double)item.getConstant();
					item = .getStackItem(1);
					Double d2 = (Double)item.getConstant();
					if (((d1 != null) && d1.isNaN()) || ((d2 != null) && d2.isNaN())) {
						.reportBug(new BugInstance(this"SPP_USE_ISNAN", NORMAL_PRIORITY)
								   .addClass(this)
								   .addMethod(this)
								   .addSourceLine(this));
					}
				}
else if (seen == FCMPL) {
				if (.getStackDepth() > 1) {
					Float f1 = (Float)item.getConstant();
					item = .getStackItem(1);
					Float f2 = (Float)item.getConstant();
					if (((f1 != null) && f1.isNaN()) || ((f2 != null) && f2.isNaN())) {
						.reportBug(new BugInstance(this"SPP_USE_ISNAN", NORMAL_PRIORITY)
								   .addClass(this)
								   .addMethod(this)
								   .addSourceLine(this));
					}
				}
else if (((seen >= ASTORE_0) && (seen <= ASTORE_3)) || (seen == ASTORE)) {
				reg = RegisterUtils.getAStoreReg(thisseen);
				if (seen == ) {
					if (reg == ) {
						.reportBug(new BugInstance(this"SPP_STUTTERED_ASSIGNMENT", NORMAL_PRIORITY)
								   .addClass(this)
								   .addMethod(this)
								   .addSourceLine(this));
					}
				}
				if (.getStackDepth() > 0) {
					String mName = (Stringitem.getUserValue();
					if (mName != null) {
    					if (mName.equals("trim")) {
    						item.setUserValue(null);
    					} else {
    					    Matcher m = .matcher(mName);
    					    if (m.matches()) {
        					    int appendReg = Integer.parseInt(m.group(1));
        					    if (reg == appendReg) {
        					        .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)) {
				LocalVariableTable lvt = getMethod().getLocalVariableTable();
				if (lvt != null) {
					LocalVariable lv = LVTHelper.getLocalVariableAtPC(lvt, RegisterUtils.getALoadReg(thisseen), getPC());
					if (lv != null) {
						 = "Ljava/lang/String;".equals(lv.getSignature());
					}
				}
else if ((seen >= ICONST_0) && (seen <= ICONST_3)) {
				if (.getStackDepth() > 0) {
					String tca = (String)item.getUserValue();
					if ("toCharArray".equals(tca)) {
						userValue = "iconst";
					}
				}
else if (seen == CALOAD) {
				if (.getStackDepth() > 0) {
					String ic = (String)item.getUserValue();
					if ("iconst".equals(ic)) {
						.reportBug(new BugInstance(this"SPP_USE_CHARAT", NORMAL_PRIORITY)
									.addClass(this)
									.addMethod(this)
									.addSourceLine(this));
					}
				}
else if (seen == INVOKESTATIC) {
				String methodName = getNameConstantOperand();
				if ("java/lang/System".equals(className)) {
	            	if ("getProperties".equals(methodName)) {
                        userValue = "getProperties";
                    } else if ("arraycopy".equals(methodName)) {
                    	if (.getStackDepth() >= 5) {
                    		OpcodeStack.Item item = .getStackItem(2);
                    		String sig = item.getSignature();
                    		if ((sig.charAt(0) != '[') && !"Ljava/lang/Object;".equals(sig)) {
                    			.reportBug(new BugInstance(this"SPP_NON_ARRAY_PARM", HIGH_PRIORITY)
                    						.addClass(this)
                    						.addMethod(this)
                    						.addSourceLine(this));
                    		}
                    		item = .getStackItem(4);
                    		sig = item.getSignature();
                    		if ((sig.charAt(0) != '[') && !"Ljava/lang/Object;".equals(sig)) {
                    			.reportBug(new BugInstance(this"SPP_NON_ARRAY_PARM", HIGH_PRIORITY)
        						.addClass(this)
        						.addMethod(this)
        						.addSourceLine(this));
                    		}
                    	}
                    }
else if ("java/lang/reflect/Array".equals(className)) {
					int offset = -1;
					if ("getLength".equals(methodName)) {
						offset = 0;
else if (methodName.startsWith("get")) {
						offset = 1;
else if (methodName.startsWith("set")) {
						offset = 2;
					}
					if (offset >= 0) {
						if (.getStackDepth() > offset) {
							String sig = item.getSignature();
							if ((sig.charAt(0) != '[') && !"Ljava/lang/Object;".equals(sig)) {
                    			.reportBug(new BugInstance(this"SPP_NON_ARRAY_PARM", HIGH_PRIORITY)
        						.addClass(this)
        						.addMethod(this)
        						.addSourceLine(this));
                    		}
						}
					}
				}
else if (seen == INVOKEVIRTUAL) {
				String methodName = getNameConstantOperand();
				if ("java/util/BitSet".equals(className)) {
					if ("clear".equals(methodName)
					||  "flip".equals(methodName)
					||  "get".equals(methodName)
					||  "set".equals(methodName)) {
						if (.getStackDepth() > 0) {
							Object o =item.getConstant();
							if (o instanceof Integer) {
								if (((Integero).intValue() < 0) {
									.reportBug(new BugInstance(this"SPP_NEGATIVE_BITSET_ITEM", NORMAL_PRIORITY)
											   .addClass(this)
											   .addMethod(this)
											   .addSourceLine(this));
								}
							}
						}
					}
else if ("java/lang/StringBuilder".equals(className) || "java/lang/StringBuffer".equals(className)) {
				    if ("append".equals(methodName)) {
				        if (.getStackDepth() > 1) {
				            OpcodeStack.Item valItem = .getStackItem(0);
				            OpcodeStack.Item sbItem = .getStackItem(1);
				            Object constant = valItem.getConstant();
				            boolean argIsLiteralString = (constant instanceof String) && (((Stringconstant).length() > 0);
				            argIsLiteralString = argIsLiteralString && !looksLikeStaticFieldValue((Stringconstant);
				            if (argIsLiteralString) {
    				            String existingAppend = (StringsbItem.getUserValue();
    				            if (existingAppend != null) {
    				                Matcher m = .matcher(existingAppend);
    				                if (m.matches() && .equals(m.group(2))) {
    				                    .reportBug(new BugInstance(this"SPP_DOUBLE_APPENDED_LITERALS", NORMAL_PRIORITY)
    				                                .addClass(this)
    				                                .addMethod(this)
    				                                .addSourceLine(this));
    				                    argIsLiteralString = false;
    				                }
    				            }
				            }
				            
				            String literal = argIsLiteralString ?  : "";
				            if (sbItem.getRegisterNumber() > -1) {
				                userValue = "append:" + sbItem.getRegisterNumber() + ":" + literal;
				            } else {
				                userValue = (StringsbItem.getUserValue();
				                if (userValue != null) {
				                    Matcher m = .matcher(userValue);
				                    if (m.matches()) {
				                        userValue = "append:" + m.group(1) + ":" + literal;
				                    }
				                }
				            }
				        }
				    }
else if ("java/lang/String".equals(className)) {
					if ("intern".equals(methodName)) {
						String owningMethod = getMethod().getName();
						if (!"<clinit>".equals(owningMethod))
						{
							if (.getStackDepth() > 0) {
								if (item.getConstant() != null) {
									.reportBug(new BugInstance(this"SPP_INTERN_ON_CONSTANT", NORMAL_PRIORITY)
											   .addClass(this)
											   .addMethod(this)
											   .addSourceLine(this));
								}
							}
						}
else if ("toCharArray".equals(methodName)) {
						userValue = "toCharArray";
else if ("toLowerCase".equals(methodName)
					       ||  "toUpperCase".equals(methodName)) {
						userValue = "IgnoreCase";
else if ("equalsIgnoreCase".equals(methodName)
						   ||  "compareToIgnoreCase".equals(methodName)) {
						if (.getStackDepth() > 1) {
							if ("IgnoreCase".equals(item.getUserValue())) {
		                		.reportBug(new BugInstance(this"SPP_USELESS_CASING", NORMAL_PRIORITY)
    							.addClass(this)
    							.addMethod(this)
    							.addSourceLine(this));
							}
							item = .getStackItem(0);
							String parm = (String)item.getConstant();
							if ((parm != null) && (parm.length() == 0)) {
								.reportBug(new BugInstance(this"SPP_EMPTY_CASING", NORMAL_PRIORITY)
								.addClass(this)
								.addMethod(this)
								.addSourceLine(this));
							}
						}
else if ("trim".equals(methodName)) {
						userValue = "trim";
else if ("length".equals(methodName)) {
						if (.getStackDepth() > 0) {
							if ("trim".equals(item.getUserValue())) {
								.reportBug(new BugInstance(this"SPP_TEMPORARY_TRIM", NORMAL_PRIORITY)
								.addClass(this)
								.addMethod(this)
								.addSourceLine(this));
							}
						}
else if ("equals".equals(methodName)) {
						if (.getStackDepth() > 1) {
							if ("trim".equals(item.getUserValue())) {
								.reportBug(new BugInstance(this"SPP_TEMPORARY_TRIM", NORMAL_PRIORITY)
								.addClass(this)
								.addMethod(this)
								.addSourceLine(this));
							}
						}
					}
    				else if ("toString".equals(methodName)) {
                        .reportBug(new BugInstance(this"SPP_TOSTRING_ON_STRING", NORMAL_PRIORITY)
                         .addClass(this)
                         .addMethod(this)
                         .addSourceLine(this));
                    }
                } else if ("equals(Ljava/lang/Object;)Z".equals(methodName + getSigConstantOperand())) {
                	try {
	                	JavaClass cls = Repository.lookupClass(className);
	                	if (cls.isEnum()) {
	                		.reportBug(new BugInstance(this"SPP_EQUALS_ON_ENUM", NORMAL_PRIORITY)
	                							.addClass(this)
	                							.addMethod(this)
	                							.addSourceLine(this));
	                	}
                	} catch (ClassNotFoundException cnfe) {
                		.reportMissingClass(cnfe);
                	}
                } else if ("java/lang/Boolean".equals(className)
                	&&     "booleanValue".equals(methodName)) {
                	if ([0] != -1) {
                		int range1Size = [2] - [0];
                		if (range1Size == (getNextPC() - [3])) {
                			byte[] bytes = getCode().getCode();
                			int ifeq = 0x000000FF & bytes[[2]];
                			if (ifeq == IFEQ) {
                				int start1 = [0];
                    			int start2 = [3];
                				boolean found = true;
                				for (int i = 0; i < range1Sizei++) {
                					if (bytes[start1+i] != bytes[start2+i]) {
                						found = false;
                						break;
                					}
                				}
                				if (found) {
                					.reportBug(new BugInstance(this"SPP_INVALID_BOOLEAN_NULL_CHECK", NORMAL_PRIORITY)
                								.addClass(this)
                								.addMethod(this)
                								.addSourceLine(this));
                				}
                			}
                		}
                	}
                } else if (("java/util/GregorianCalendar".equals(className) || "java/util/Calendar".equals(className))
                   &&      ("after".equals(methodName) || "before".equals(methodName))) {
                	if (.getStackDepth() > 1) {
                		OpcodeStack.Item item = .getStackItem(0);
                		String itemSig = item.getSignature();
                		//Rule out java.lang.Object as mergeJumps can throw away type info (BUG)
                		if (!"Ljava/lang/Object;".equals(itemSig) && !"Ljava/util/Calendar;".equals(itemSig) && !"Ljava/util/GregorianCalendar;".equals(itemSig)) {
                			try {
                				JavaClass cls = Repository.lookupClass(itemSig.substring(1, itemSig.length() - 1));
                				if (!cls.instanceOf()) {
                					.reportBug(new BugInstance(this"SPP_INVALID_CALENDAR_COMPARE", NORMAL_PRIORITY)
			                					.addClass(this)
			                					.addMethod(this)
			                					.addSourceLine(this));
                				}
                			} catch (ClassNotFoundException cnfe) {
                				.reportMissingClass(cnfe);
                			}
                		}
                	}
                } else if ("java/util/Properties".equals(className)) {
                	if (("get".equals(methodName) || "getProperty".equals(methodName))) {
                		if (.getStackDepth() > 1) {
                			OpcodeStack.Item item = .getStackItem(1);
                			if ("getProperties".equals(item.getUserValue())) {
                				.reportBug(new BugInstance(this"SPP_USE_GETPROPERTY", NORMAL_PRIORITY)
                				           .addClass(this)
                				           .addMethod(this)
                				           .addSourceLine(this));
                			}
                		}
                	}
                } else if ("toString".equals(methodName) && "java/lang/Object".equals(className)) {
                    if (.getStackDepth() >= 1) {
                        OpcodeStack.Item item = .getStackItem(0);
                        JavaClass toStringClass = item.getJavaClass();
                        String toStringClassName = toStringClass.getClassName();
                        if (!toStringClass.isInterface() && !toStringClass.isAbstract() && !"java.lang.Object".equals(toStringClassName) && !"java.lang.String".equals(toStringClassName) && .add(toStringClassName)) {
                            .reportBug(new BugInstance(this"SPP_NON_USEFUL_TOSTRING"toStringClass.isFinal() ? NORMAL_PRIORITY : LOW_PRIORITY)
                                        .addClass(this)
                                        .addMethod(this)
                                        .addSourceLine(this));
                        }
                    }
                }
else if (seen == INVOKESPECIAL) {
				if ("java/lang/StringBuffer".equals(className)
				||  "java/lang/StringBuilder".equals(className)) {
					String methodName = getNameConstantOperand();
					if ("<init>".equals(methodName)) {
						String signature = getSigConstantOperand();
						if ("(I)V".equals(signature)) {
							if ( == BIPUSH) {
								if (.getStackDepth() > 0) {
									Object o = item.getConstant();
									if (o instanceof Integer) {
										int parm = ((Integero).intValue();
										if ((parm > 32)
										&&  (parm < 127)
										&&  (parm != 64)
										&&  ((parm % 10) != 0)
										&&  ((parm % 5) != 0)) {
											.reportBug(new BugInstance(this"SPP_NO_CHAR_SB_CTOR", LOW_PRIORITY)
										   .addClass(this)
										   .addMethod(this)
										   .addSourceLine(this));
										}
									}
								}
							}
else if ("(Ljava/lang/String;)V".equals(signature)) {
							if (.getStackDepth() > 0) {
	                            OpcodeStack.Item item = .getStackItem(0);
	                            String con = (String)item.getConstant();
	                            if ("".equals(con)) {
	                                .reportBug(new BugInstance(this"SPP_STRINGBUFFER_WITH_EMPTY_STRING", NORMAL_PRIORITY)
	                                   .addClass(this)
	                                   .addMethod(this)
	                                   .addSourceLine(this));
	                            }
	                        }
                        }
					}
else if ("java/math/BigDecimal".equals(className)) {
					if (.getStackDepth() > 0) {
						Object constant = item.getConstant();
						if (constant instanceof Double)
						{
							.reportBug(new BugInstance(this"SPP_USE_BIGDECIMAL_STRING_CTOR", NORMAL_PRIORITY)
									   .addClass(this)
									   .addMethod(this)
									   .addSourceLine(this));
						}
					}
				}
else if (seen == INVOKEINTERFACE) {
				if ("java/util/Map".equals(className)) {
					if ("keySet".equals(method)) {
						userValue = "keySet";
					}
else if ("java/util/Set".equals(className)) {
					if ("contains".equals(method)) {
						if (.getStackDepth() >= 2) {
							if ("keySet".equals(item.getUserValue())) {
								.reportBug(new BugInstance(this"SPP_USE_CONTAINSKEY", NORMAL_PRIORITY)
										   .addClass(this)
										   .addMethod(this)
										   .addSourceLine(this));
							}
						}
					}
else if ("java/util/List".equals(className)) {
				    String method = getNameConstantOperand();
                    if ("iterator".equals(method)) {
                            userValue = "iterator";
                    }
else if ("java/util/Iterator".equals(className)) {
				    String method = getNameConstantOperand();
                    if ("next".equals(method)) {
                        if (.getStackDepth() >= 1) {
                            OpcodeStack.Item item = .getStackItem(0);
                            if ("iterator".equals(item.getUserValue())) {
                                .reportBug(new BugInstance(this"SPP_USE_GET0", NORMAL_PRIORITY)
                                            .addClass(this)
                                            .addMethod(this)
                                            .addSourceLine(this));
                            }
                        }
                    }
				}
				if (.contains(className)) {
					if ("size".equals(method)) {
						userValue = "size";
					}
				}
			}
catch (ClassNotFoundException cnfe) {
finally {
			TernaryPatcher.pre(seen);
			.sawOpcode(thisseen);
			TernaryPatcher.post(seen);
			if ((.getStackDepth() > 0)) {
                OpcodeStack.Item item = .getStackItem(0);
    			if (userValue != null) {
    				item.setUserValue(userValue);
    			} else if ("iterator".equals(item.getUserValue()) && (seen == GETFIELD) || (seen == ALOAD) || ((seen >= ALOAD_0) && (seen <= ALOAD_3))) {
    			    item.setUserValue(null);
    			}
			}
			 = seen;
			 = reg;
			System.arraycopy(, 1, , 0, 3);
			[3] = getPC();
		}
	}
	private boolean looksLikeStaticFieldValue(String constant) {
	    if ( == null) {
	         = new HashSet<String>();
	        
	        Field[] fields = getClassContext().getJavaClass().getFields();
	        for (Field f : fields) {
	            if (((f.getAccessFlags() & (Constants.ACC_FINAL|Constants.ACC_STATIC)) == (Constants.ACC_FINAL|Constants.ACC_STATIC)) && "Ljava/lang/String;".equals(f.getSignature())) {
	                ConstantValue cv = f.getConstantValue();
	                if (cv != null) {
    	                int cvIndex = cv.getConstantValueIndex();
    	                .add(getConstantPool().getConstantString(cvIndex, Constants.CONSTANT_String));
	                }
	            }
	        }
	    }
	    
	    return .contains(constant);
	}
New to GrepCode? Check out our FAQ X