[Fb-contrib-commit] fb-contrib/src/com/mebigfatguy/fbcontrib/detect CustomBuiltXML.java,NONE,1.1
Brought to you by:
dbrosius
|
From: Dave B. <dbr...@us...> - 2005-12-30 06:33:54
|
Update of /cvsroot/fb-contrib/fb-contrib/src/com/mebigfatguy/fbcontrib/detect In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25229/src/com/mebigfatguy/fbcontrib/detect Added Files: CustomBuiltXML.java Log Message: initial checkin - new CBX detector --- NEW FILE: CustomBuiltXML.java --- /* * fb-contrib - Auxilliary detectors for Java programs * Copyright (C) 2005 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.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.bcel.classfile.Code; 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.StatelessDetector; public class CustomBuiltXML extends BytecodeScanningDetector implements StatelessDetector { private static final List<Pattern> xmlPatterns = new ArrayList<Pattern>(); static { xmlPatterns.add(Pattern.compile(".*<[a-zA-Z_](\\w)*>.*")); xmlPatterns.add(Pattern.compile(".*</[a-zA-Z_](\\w)*>.*")); xmlPatterns.add(Pattern.compile(".*<[a-zA-Z_](\\w)*/>.*")); xmlPatterns.add(Pattern.compile(".*<(//)?$")); xmlPatterns.add(Pattern.compile("^(//)?>.*")); xmlPatterns.add(Pattern.compile(".*=(\\s)*[\"'].*")); xmlPatterns.add(Pattern.compile("^[\"']>.*")); xmlPatterns.add(Pattern.compile(".*<!\\[CDATA\\[.*", Pattern.CASE_INSENSITIVE)); xmlPatterns.add(Pattern.compile(".*\\]\\]>.*")); xmlPatterns.add(Pattern.compile(".*xmlns:.*")); } private static final String CBX_MIN_REPORTABLE_ITEMS = "fb-contrib.cbx.minxmlitems"; private BugReporter bugReporter; private OpcodeStack stack = new OpcodeStack(); private int xmlItemCount = 0; private int lowReportingThreshold; private int midReportingThreshold; private int highReportingThreshold; private int firstPC; /** * constructs a CBX detector given the reporter to report bugs on * @param bugReporter the sync of bug reports */ public CustomBuiltXML(BugReporter bugReporter) { this.bugReporter = bugReporter; lowReportingThreshold = Integer.getInteger(CBX_MIN_REPORTABLE_ITEMS, 5); midReportingThreshold = lowReportingThreshold << 1; highReportingThreshold = lowReportingThreshold << 2; } /** * clone this detector so that it can be a StatelessDetector * * @return a clone of this object */ @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } /** * overrides the visitor reset the opcode stack * * @param obj the code object of the currently parsed method */ public void visitCode(Code obj) { stack.resetForMethodEntry(this); xmlItemCount = 0; firstPC = -1; super.visitCode(obj); if (xmlItemCount >= lowReportingThreshold) { bugReporter.reportBug( new BugInstance( this, "CBX_CUSTOM_BUILT_XML", (xmlItemCount >= highReportingThreshold) ? HIGH_PRIORITY : (xmlItemCount >= midReportingThreshold) ? NORMAL_PRIORITY : LOW_PRIORITY) .addClass(this) .addMethod(this) .addSourceLine(this, firstPC)); } } /** * overrides the visitor to find String concatenations including xml strings * * @param seen the opcode that is being visited */ public void sawOpcode(int seen) { String strCon = null; try { if (seen == INVOKESPECIAL) { String clsName = getClassConstantOperand(); if ("java/lang/StringBuffer".equals(clsName) || "java/lang/StringBuilder".equals(clsName)) { String methodName = getNameConstantOperand(); String methodSig = getSigConstantOperand(); if ("<init>".equals(methodName) && ("(Ljava/lang/String;)L" + clsName + ";").equals(methodSig)) { if (stack.getStackDepth() > 0) { OpcodeStack.Item itm = stack.getStackItem(0); strCon = (String)itm.getConstant(); } } } } else if (seen == INVOKEVIRTUAL) { String clsName = getClassConstantOperand(); if ("java/lang/StringBuffer".equals(clsName) || "java/lang/StringBuilder".equals(clsName)) { String methodName = getNameConstantOperand(); String methodSig = getSigConstantOperand(); if ("append".equals(methodName) && ("(Ljava/lang/String;)L" + clsName + ";").equals(methodSig)) { if (stack.getStackDepth() > 0) { OpcodeStack.Item itm = stack.getStackItem(0); strCon = (String)itm.getConstant(); } } } } if (strCon != null) { if (strCon.trim().length() == 0) return; for (Pattern p : xmlPatterns) { Matcher m = p.matcher(strCon); if (m.matches()) { xmlItemCount++; if (firstPC < 0) firstPC = getPC(); break; } } } } finally { stack.sawOpcode(this, seen); } } } |