Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * 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.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;

Looks for methods that create DOM Nodes but do not add them to any DOM Document.
 
 public class OrphanedDOMNode extends BytecodeScanningDetector
 {
 	private static final Set<StringdomCreationMethods = new HashSet<String>();
 	static {
 		.add("createAttribute:(Ljava/lang/String;)Lorg/w3c/dom/Attr;");
 		.add("createAttributeNS:(Ljava/lang/String;Ljava/lang/String;)Lorg/w3c/dom/Attr;");
 		.add("createCDATASection:(Ljava/lang/String;)Lorg/w3c/dom/CDATASection;");
 		.add("createComment:(Ljava/lang/String;)Lorg/w3c/dom/Comment;");
 		.add("createElement:(Ljava/lang/String;)Lorg/w3c/dom/Element;");
 		.add("createElementNS:(Ljava/lang/String;Ljava/lang/String;)Lorg/w3c/dom/Element;");
 		.add("createProcessingInstruction:(Ljava/lang/String;Ljava/lang/String;)Lorg/w3c/dom/ProcessingInstruction;");
 		.add("createTextNode:(Ljava/lang/String;)Lorg/w3c/dom/Text;");
 	}
 	
 	private BugReporter bugReporter;
 	private OpcodeStack stack;
 	private Map<OpcodeStack.Item, Integer> nodeCreations;
 	private Map<IntegerIntegernodeStores;

    
constructs a ODN detector given the reporter to report bugs on

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

implements the visitor to create and clear the stack, node creations and store maps

Parameters:
classContext the context object for the currently parsed class
 
 	public void visitClassContext(ClassContext classContext) {
 		try {
 			 = new OpcodeStack();
 			nodeCreations = new HashMap<OpcodeStack.Item, Integer>();
 			super.visitClassContext(classContext);
 		} finally {
 			 = null;
 			nodeCreations = null;
 			 = null;
 		}
 	}
implements the visitor to clear the opcode stack for the next code

Parameters:
obj the context object for the currently parsed code block
 
 	public void visitCode(Code obj) {
 		.resetForMethodEntry(this);
 		nodeCreations.clear();
 		super.visitCode(obj);
 		
 		Set<IntegerreportedPCs = new HashSet<Integer>();
 		for (Integer pc : nodeCreations.values()) {
			if (!reportedPCs.contains(pc)) {
				.reportBug(new BugInstance(this"ODN_ORPHANED_DOM_NODE", NORMAL_PRIORITY)
												.addClass(this)
												.addMethod(this)
												.addSourceLine(thispc.intValue()));
				reportedPCs.add(pc);
			}
		}
		for (Integer pc : .values()) {
			if (!reportedPCs.contains(pc)) {
				.reportBug(new BugInstance(this"ODN_ORPHANED_DOM_NODE", NORMAL_PRIORITY)
												.addClass(this)
												.addMethod(this)
												.addSourceLine(thispc.intValue()));
				reportedPCs.add(pc);
			}
		}
	}

implements the visitor to find DOM based nodes that are allocated but not appended to an existing node (or returned).

Parameters:
seen the currently parsed opcode
	public void sawOpcode(int seen) {
		boolean sawCreate = false;
		Integer itemPC = null;
		try {
			.mergeJumps(this);
			if (seen == INVOKEINTERFACE) {
				String methodInfo = getNameConstantOperand() + ":" + getSigConstantOperand();
				if ("org/w3c/dom/Document".equals(className)) {
					if (.contains(methodInfo)) {
						sawCreate = true;
						itemPC = Integer.valueOf(getPC());
					}
				}
else if ((seen == ASTORE) || ((seen >= ASTORE_0) && seen <= ASTORE_3)) {
				int reg = RegisterUtils.getAStoreReg(thisseen);
				if (pc != null)
					.put(Integer.valueOf(reg), pc);
				else
					.remove(Integer.valueOf(reg));
else if (seen == PUTFIELD) {
				//Stores to member variables are assumed ok
else if ((seen == ALOAD) || ((seen >= ALOAD_0) && (seen <= ALOAD_3))) {
				int reg = RegisterUtils.getALoadReg(thisseen);
				itemPC = .get(Integer.valueOf(reg));
				if (itemPC != null)
					sawCreate = true;
else if (seen == ARETURN) {
				if (.getStackDepth() > 0) {
					OpcodeStack.Item itm = .getStackItem(0);
					int reg = itm.getRegisterNumber();
					nodeCreations.remove(itm);
					.remove(Integer.valueOf(reg));
				}
			}
			if (!sawCreate) {
				if ((seen == INVOKEINTERFACE) 
				||  (seen == INVOKEVIRTUAL) 
				||  (seen == INVOKESTATIC)
				||  (seen == INVOKESPECIAL)) {
					String methodSig = getSigConstantOperand();
					int argCount = Type.getArgumentTypes(methodSig).length;
					if (.getStackDepth() >= argCount) {
						for (int a = 0; a < argCounta++) {
							OpcodeStack.Item itm = .getStackItem(a);
							if (nodeCreations.containsKey(itm)) {
								int reg = itm.getRegisterNumber();
								nodeCreations.remove(itm);
								.remove(Integer.valueOf(reg));
							}
						}
                        if ((seen != INVOKESTATIC) && (.getStackDepth() > argCount)) {
                            nodeCreations.remove(.getStackItem(argCount));
                        }
					}
				}
			}
finally {
			.sawOpcode(thisseen);
			if (sawCreate) {
				if (.getStackDepth() > 0)
					nodeCreations.put(.getStackItem(0), itemPC);
			}
		}
	}

returns the pc where this DOM Node was created, or null if this isn't a DOM node that was created

Parameters:
index the index into the stack of the item to be checked
Returns:
the pc where this NODE was created, or null
	private Integer findDOMNodeCreationPoint(int index) {
		if (.getStackDepth() > index)
			return nodeCreations.remove(.getStackItem(index));
		return null;
	}
New to GrepCode? Check out our FAQ X