Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * fb-contrib - Auxiliary detectors for Java programs
   * Copyright (C) 2005-2012 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.Set;
 
 import  org.apache.bcel.classfile.Constant;
 import  org.apache.bcel.classfile.ConstantString;
 import  org.apache.bcel.classfile.Field;
 import  org.apache.bcel.classfile.LocalVariable;
 import  org.apache.bcel.classfile.LocalVariableTable;
 import  org.apache.bcel.classfile.Method;
 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.ba.ClassContext;

looks for methods that use Class.forName("XXX") to load a class object for a class that is already referenced by this class. It is simpler to just use XXX.class, and doing so protects the integrity of this code from such transformations as obfuscation. Use of Class.forName should only be used when the class in question isn't already statically bound to this context.
 
 public class SloppyClassReflection extends BytecodeScanningDetector
 {
 	enum State {COLLECT, SEEN_NOTHING, SEEN_LDC}
 	
 	private final BugReporter bugReporter;
 	private Set<StringrefClasses;
 	private State state;
 	private String clsName;

constructs a SCR detector given the reporter to report bugs on

Parameters:
bugReporter the sync of bug reports
 
 	public SloppyClassReflection(BugReporter bugReporter) {
 		this. = bugReporter;
 	}

overrides the visitor to collect all class references

Parameters:
classContext the class context of the currently visited class
 
 	public void visitClassContext(ClassContext classContext) {
 		try {
 			 = new HashSet<String>();
 			.add(classContext.getJavaClass().getClassName());
 			super.visitClassContext(classContext);
 			super.visitClassContext(classContext);
 		} finally {
 			 = null;
 		}
 	}

overrides the visitor reset the opcode stack

Parameters:
obj the method object of the currently parsed method
 	
 	public void visitMethod(Method obj) {
 		if ("<clinit>".equals(obj.getName()))
 			return;
 		
 		if ( == .) {
 			Type[] argTypes = obj.getArgumentTypes();
 			for (Type t : argTypes)
 				addType(t);
 			Type resultType = obj.getReturnType();
 			addType(resultType);
 			LocalVariableTable lvt = obj.getLocalVariableTable();
 			if (lvt != null) {
 				LocalVariable[] lvs = lvt.getLocalVariableTable();
				if (lvs != null) {
                    for (LocalVariable lv : lvs) {
						if (lv != null) {
							Type t = Type.getType(lv.getSignature());
						}
					}
				}
			}
else
		super.visitMethod(obj);
	}
	public void visitField(Field obj) {
		if ( == .) {
			Type t = obj.getType();
		}
	}

overrides the visitor to find class loading that is non obfuscation proof

Parameters:
seen the opcode that is being visited
	public void sawOpcode(int seen) {
		switch () {
			case :
				if ((seen == INVOKESTATIC) 
			    ||  (seen == INVOKEVIRTUAL)
			    ||  (seen == INVOKEINTERFACE)
			    ||  (seen == INVOKESPECIAL)) {
					String signature = getSigConstantOperand();
					Type[] argTypes = Type.getArgumentTypes(signature);
					for (Type t : argTypes)
					Type resultType = Type.getReturnType(signature);
					addType(resultType);
				}
			break;
				if ((seen == LDC) || (seen == LDC_W)) {
					Constant c = getConstantRefOperand();
					if (c instanceof ConstantString) {
						 = ((ConstantString) c).getBytes(getConstantPool());
					}
				}
			break;
			case :
				if ((seen == INVOKESTATIC) 
				&&  ("forName".equals(getNameConstantOperand())) 
				&&  ("java/lang/Class".equals(getClassConstantOperand()))) {
						.reportBug(new BugInstance(this"SCR_SLOPPY_CLASS_REFLECTION", NORMAL_PRIORITY)
									.addClass(this)
									.addMethod(this)
									.addSourceLine(this));
					}
				}
			break;
		}
	}

add the type string represented by the type to the refClasses set if it is a reference

Parameters:
t the type to add
	private void addType(Type t) {
		String signature = t.getSignature();
		if (signature.charAt(0) == 'L')
			.add(signature.substring(1, signature.length() - 1));
	}
New to GrepCode? Check out our FAQ X