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.List;
 import java.util.Set;
 
 import  org.apache.bcel.classfile.Code;
 import  org.apache.bcel.classfile.ConstantFieldref;
 import  org.apache.bcel.classfile.ConstantNameAndType;
 
Looks for use of iterators on synchronized collections built from the Collections class. As the collection in question was built thru Collections.synchronizedXXX, an assumption is made that this collection must be multithreaded safe. However, iterator access is used, which is explicitly unsafe. When iterators are to be used, synchronization should be done manually.
 
 public class SyncCollectionIterators extends BytecodeScanningDetector
 {
 	private final BugReporter bugReporter;
 	private static Set<StringsynchCollectionNames = new HashSet<String>();
 	static {
 		.add("synchronizedSet");
 		.add("synchronizedMap");
 		.add("synchronizedList");
 		.add("synchronizedSortedSet");
 		.add("synchronizedSortedMap");
 	}
 	private static Set<StringmapToSetMethods = new HashSet<String>();
 	static {
 		.add("keySet");
 		.add("entrySet");
 		.add("values");
 	}
 	
 	enum State {SEEN_NOTHING, SEEN_SYNC, SEEN_LOAD}
 	
 	private State state;
 	private OpcodeStack stack;
 	private Object collectionInfo = null;

constructs a SCI detector given the reporter to report bugs on

Parameters:
bugReporter the sync of bug reports
 
 	public SyncCollectionIterators(final BugReporter bugReporter) {
 		this. = bugReporter;
 	}
 
 	public void visitClassContext(final ClassContext classContext) {
 		try {
 			 = new OpcodeStack();
 			super.visitClassContext(classContext);
 		} finally {
 			 = null;
 			 = null;
 			 = null;
 			 = null;
 		}
 	}
 	
 	public void visitCode(final Code obj) {
 		if (obj.getCode() != null) {
			super.visitCode(obj);
		}
	}
	public void sawOpcode(final int seen) {
		try {
	        .precomputation(this);
			switch () {
					if ((seen == INVOKESTATIC) && "java/util/Collections".equals(getClassConstantOperand())) {
						}
else if (seen == ALOAD) {
						int reg = getRegisterOperand();
						if (.contains(Integer.valueOf(reg))) {
							 = Integer.valueOf(reg);
						}
else if ((seen >= ALOAD_0) && (seen <= ALOAD_3)) {
						int reg = seen - ALOAD_0;
						if (.contains(Integer.valueOf(reg))) {
							 = Integer.valueOf(reg);
						}
else if (seen == GETFIELD) {
						ConstantFieldref ref = (ConstantFieldref)getConstantRefOperand();
						ConstantNameAndType nandt = (ConstantNameAndType)getConstantPool().getConstant(ref.getNameAndTypeIndex());
						String fieldName = nandt.getName(getConstantPool());
						if (.contains(fieldName)) {
							 = fieldName;
						}
					}
				break;
				case :
					if (seen == ASTORE) {
						int reg = getRegisterOperand();
else if ((seen >= ASTORE_0) && (seen <= ASTORE_3)) {
						int reg = seen - ASTORE_0;
					}
					else if (seen == PUTFIELD) {
						ConstantFieldref ref = (ConstantFieldref)getConstantRefOperand();
						ConstantNameAndType nandt = (ConstantNameAndType)getConstantPool().getConstant(ref.getNameAndTypeIndex());
					}
				break;
				case :
					if (seen == INVOKEINTERFACE) {
						String calledClass = getClassConstantOperand();
						if ("java/lang/Map".equals(calledClass)) {
else {
							}
else if (calledClass.startsWith("java/util/")) {
							if ("iterator".equals(getNameConstantOperand())) {
									.reportBugnew BugInstancethis"SCI_SYNCHRONIZED_COLLECTION_ITERATORS", NORMAL_PRIORITY)
										.addClass(this)
										.addMethod(this)
										.addSourceLine(this));
else {
									if (!syncIsMap(syncObj)) {
										.reportBugnew BugInstancethis"SCI_SYNCHRONIZED_COLLECTION_ITERATORS", NORMAL_PRIORITY)
												.addClass(this)
												.addMethod(this)
												.addSourceLine(this));
									}
								}
							}
else {
						}
else {
					}
				break;
			}
			if (seen == MONITORENTER) {
				if (.getStackDepth() > 0) {
					int reg = item.getRegisterNumber();
					if (reg >= 0)
						.add(Integer.valueOf(reg));
					else {
						XField field = item.getXField();
						if (field != null)
					}
				}
else if (seen == MONITOREXIT) {
				if (.size() > 0)
			}
finally {
			.sawOpcode(thisseen);
		}
	}
	private boolean syncIsMap(Object syncObjectObject colInfo) {
		if ((syncObject != null) && (colInfo != null) && syncObject.getClass().equals(colInfo.getClass()))
			return syncObject.equals(colInfo);
		//Something went wrong... don't report
		return true;
	}
New to GrepCode? Check out our FAQ X