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  org.apache.bcel.Repository;
 import  org.apache.bcel.classfile.Code;
 import  org.apache.bcel.classfile.JavaClass;
 import  org.apache.bcel.classfile.Method;
 import  org.apache.bcel.generic.Type;
 
 
looks for implementation of clone() where a store is made to a member of the source object.
 
 public class SuspiciousCloneAlgorithm extends BytecodeScanningDetector {
 	
 	private static JavaClass cloneableClass;
 	private static Map<StringIntegerchangingMethods;
 	static {
 		try {
 			 = Repository.lookupClass("java/lang/Cloneable");
 			.put("add", Integer.valueOf(NORMAL_PRIORITY));
 			.put("addAll", Integer.valueOf(NORMAL_PRIORITY));
 			.put("put", Integer.valueOf(NORMAL_PRIORITY));
 			.put("putAll", Integer.valueOf(NORMAL_PRIORITY));
 			.put("insert", Integer.valueOf(LOW_PRIORITY));
 			.put("set", Integer.valueOf(LOW_PRIORITY));
 			
 		} catch (ClassNotFoundException cnfe) {
 			 = null;
 		}
 	}
 	
 	private OpcodeStack stack;

constructs a SCA detector given the reporter to report bugs on

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

override the visitor to look for classes that implement Cloneable

Parameters:
classContext the context object of the class to be checked
 
 	public void visitClassContext(ClassContext classContext) {
 		if ( == null)
 			return;
 		
 		try {
 			JavaClass cls = classContext.getJavaClass();
 			if (cls.implementationOf()) {
 				 = new OpcodeStack();
 				super.visitClassContext(classContext);
 			}
 		} catch (ClassNotFoundException cnfe) {
 		} finally {
 			 = null;
 		}
 	}

override the visitor to only continue for the clone method

Parameters:
obj the context object of the currently parsed method
	public void visitCode(Code obj) {
		Method m = getMethod();
		if (!m.isStatic() && "clone".equals(m.getName()) && "()Ljava/lang/Object;".equals(m.getSignature()))
			super.visitCode(obj);
	}

override the visitor to look for stores to member fields of the source object on a clone

Parameters:
seen the opcode of the currently parsed instruction
	public void sawOpcode(int seen) {
		boolean srcField = false;
		try {
	        .precomputation(this);
	        
			switch (seen) {
				case ALOAD_0:
					srcField = true;
				break;
				case DUP:
					if (.getStackDepth() > 0) {
						if (item.getUserValue() != null)
							srcField = true;
					}
				break;
				case GETFIELD:
					if (.getStackDepth() > 0) {
						if (item.getRegisterNumber() == 0) {
							srcField = true;
						}
					}
				break;
				case PUTFIELD:
					if (.getStackDepth() >= 2) {
						if ((item.getRegisterNumber() == 0) || (item.getUserValue() != null)) {
							.reportBug(new BugInstance(this"SCA_SUSPICIOUS_CLONE_ALGORITHM", NORMAL_PRIORITY)
									   .addClass(this)
									   .addMethod(this)
									   .addSourceLine(this));
						}
					}
				break;
				case INVOKEINTERFACE:
				case INVOKEVIRTUAL:
					int numArgs = Type.getArgumentTypes(sig).length;
					if (.getStackDepth() > numArgs) {
						OpcodeStack.Item item = .getStackItem(numArgs);
						if ((item.getRegisterNumber() == 0) || (item.getUserValue() != null)) {
							Integer priority = .get(name);
							if (priority != null)
								.reportBug(new BugInstance(this"SCA_SUSPICIOUS_CLONE_ALGORITHM"priority.intValue())
								   .addClass(this)
								   .addMethod(this)
								   .addSourceLine(this));
						}
					}
				break;
			}
finally {
			TernaryPatcher.pre(seen);
			.sawOpcode(thisseen);
			TernaryPatcher.post(seen);
			if (srcField && .getStackDepth() > 0) {
			}
		}
	}
New to GrepCode? Check out our FAQ X