[Fb-contrib-commit] SF.net SVN: fb-contrib: [811] trunk/fb-contrib
Brought to you by:
dbrosius
From: <dbr...@us...> - 2007-02-01 08:00:26
|
Revision: 811 http://svn.sourceforge.net/fb-contrib/?rev=811&view=rev Author: dbrosius Date: 2007-02-01 00:00:24 -0800 (Thu, 01 Feb 2007) Log Message: ----------- Initial checkin - SJVU .. not even close Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Added Paths: ----------- trunk/fb-contrib/samples/SJVU_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousJDKVersionUse.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2007-02-01 07:58:41 UTC (rev 810) +++ trunk/fb-contrib/etc/findbugs.xml 2007-02-01 08:00:24 UTC (rev 811) @@ -275,7 +275,13 @@ speed="fast" reports="USS_USE_STRING_SPLIT" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.SuspiciousJDKVersionUse" + speed="slow" + reports="SJVU_SUSPICIOUS_JDK_VERSION_USE" + hidden="true" + disabled="true" /> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -356,4 +362,5 @@ <BugPattern abbrev="SCII" type="SCII_SPOILED_CHILD_INTERFACE_IMPLEMENTATOR" category="STYLE" experimental="true" /> <BugPattern abbrev="DWI" type="DWI_DELETING_WHILE_ITERATING" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="USS" type="USS_USE_STRING_SPLIT" category="STYLE" experimental="true" /> + <BugPattern abbrev="SJVU" type="SJVU_SUSPICIOUS_JDK_VERSION_USE" category="CORRECTNESS" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2007-02-01 07:58:41 UTC (rev 810) +++ trunk/fb-contrib/etc/messages.xml 2007-02-01 08:00:24 UTC (rev 811) @@ -737,6 +737,13 @@ ]]> </Details> </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.SuspiciousJDKVersionUse"> + <Details> + <![CDATA[ + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -1763,6 +1770,15 @@ </Details> </BugPattern> + <BugPattern type="SJVU_SUSPICIOUS_JDK_VERSION_USE"> + <ShortDescription></ShortDescription> + <LongDescription></LongDescription> + <Details> + <![CDATA[ + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1826,4 +1842,5 @@ <BugCode abbrev="SCII">Spoiled Child Interface Implementor</BugCode> <BugCode abbrev="DWI">Deleting While Iterating</BugCode> <BugCode abbrev="USS">Use String Split</BugCode> + <BugCode abbrev="SJVU">Suspicious JDK VersionUse</BugCode> </MessageCollection> \ No newline at end of file Added: trunk/fb-contrib/samples/SJVU_Sample.java =================================================================== --- trunk/fb-contrib/samples/SJVU_Sample.java (rev 0) +++ trunk/fb-contrib/samples/SJVU_Sample.java 2007-02-01 08:00:24 UTC (rev 811) @@ -0,0 +1,8 @@ + +public class SJVU_Sample +{ + public void test14using15(int i) + { + Integer ii = Integer.valueOf(i); + } +} Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousJDKVersionUse.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousJDKVersionUse.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousJDKVersionUse.java 2007-02-01 08:00:24 UTC (rev 811) @@ -0,0 +1,178 @@ +/* + * fb-contrib - Auxilliary detectors for Java programs + * Copyright (C) 2005-2007 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.io.File; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLDecoder; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.bcel.Constants; +import org.apache.bcel.classfile.JavaClass; + +import com.mebigfatguy.fbcontrib.utils.Integer14; + +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; + +public class SuspiciousJDKVersionUse extends BytecodeScanningDetector +{ + private static final Map<Integer, String> verRegEx = new HashMap<Integer, String>(); + static { + verRegEx.put(Integer14.valueOf(Constants.MAJOR_1_1), "(jdk|jre)1.1"); + verRegEx.put(Integer14.valueOf(Constants.MAJOR_1_2), "(jdk|jre)1.2"); + verRegEx.put(Integer14.valueOf(Constants.MAJOR_1_3), "(jdk|jre)1.3"); + verRegEx.put(Integer14.valueOf(Constants.MAJOR_1_4), "(jdk|jre)1.4"); + verRegEx.put(Integer14.valueOf(Constants.MAJOR_1_5), "(jdk|jre)1.5"); + verRegEx.put(Integer14.valueOf(50), "jdk1.6"); + } + private static final Pattern jarPattern = Pattern.compile("jar:file:/*([^!]*)"); + + private Map<String, File> versionPaths; + private Map<Integer, Map<String, Set<String>>> validMethodsByVersion; + private File jdksRoot = null; + private URLClassLoader jdkLoader; + private Integer clsMajorVersion; + private BugReporter bugReporter; + + public SuspiciousJDKVersionUse(BugReporter bugReporter) { + this.bugReporter = bugReporter; + versionPaths = new HashMap<String, File>(); + validMethodsByVersion = new HashMap<Integer, Map<String, Set<String>>>(); + } + + @Override + public void visitClassContext(ClassContext classContext) { + try { + JavaClass cls = classContext.getJavaClass(); + clsMajorVersion = Integer14.valueOf(cls.getMajor()); + File rtJar = getRTJarFile(cls); + jdkLoader = new URLClassLoader(new URL[] {rtJar.toURL()}); + super.visitClassContext(classContext); + } catch (MalformedURLException mue) { + //Hmm, what to do + } finally { + jdkLoader = null; + } + } + + @Override + public void sawOpcode(int seen) { + + String clsName = null; + try { + if ((seen == INVOKEVIRTUAL) + || (seen == INVOKEINTERFACE) + || (seen == INVOKESTATIC) + || (seen == INVOKESPECIAL)) { + clsName = getClassConstantOperand(); + if ((clsName.startsWith("java/")) + || (clsName.startsWith("javax/"))) { + Map<String, Set<String>> validMethods = validMethodsByVersion.get(clsMajorVersion); + if (validMethods == null) { + validMethods = new HashMap<String, Set<String>>(); + validMethodsByVersion.put(clsMajorVersion, validMethods); + } + Set<String> methodInfos = validMethods.get(clsName); + if (methodInfos == null) { + Class c = jdkLoader.loadClass(clsName.replace('/', '.')); + Method[] methods = c.getDeclaredMethods(); + + methodInfos = new HashSet<String>(); + validMethods.put(clsName, methodInfos); + + for (Method m : methods) { + if ((m.getModifiers() & Modifier.PRIVATE) == 0) { + methodInfos.add(m.toString()); + } + } + } + } + } + } catch (ClassNotFoundException cnfe) { + if (clsName.startsWith("java/")) { + bugReporter.reportBug(new BugInstance(this, "SJVU_SUSPICIOUS_JDK_VERSION_USE", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + } + } + + private File getRTJarFile(JavaClass cls) { + String versionStr = verRegEx.get(clsMajorVersion); + if (versionStr == null) + return null; + + File rtPath = versionPaths.get(versionStr); + if (rtPath != null) + return rtPath; + + if (jdksRoot == null) { + URL jdkUrl = SuspiciousJDKVersionUse.class.getResource("/java/lang/Object.class"); + if (jdkUrl != null) { + Matcher m = jarPattern.matcher(jdkUrl.toExternalForm()); + + if (m.find()) { + String path = m.group(1); + jdksRoot = new File(path); + Pattern verPat = Pattern.compile(versionStr); + m = verPat.matcher(jdksRoot.getName()); + while ((jdksRoot.getParentFile() != null) && !m.find()) { + jdksRoot = jdksRoot.getParentFile(); + m = verPat.matcher(jdksRoot.getName()); + } + + if (jdksRoot.getParentFile() == null) + return null; + + jdksRoot = new File(URLDecoder.decode(jdksRoot.getParentFile().getPath())); + + File[] possibleJdks = jdksRoot.listFiles(); + for (File possibleJdk : possibleJdks) { + m = verPat.matcher(possibleJdk.getName()); + if (m.find()) { + File wantedRtJar = new File(possibleJdk, "lib/rt.jar"); + if (!wantedRtJar.exists()) { + wantedRtJar = new File(possibleJdk, "jre/lib/rt.jar"); + if (!wantedRtJar.exists()) + return null; + } + versionPaths.put(versionStr, wantedRtJar); + return wantedRtJar; + } + } + } + } + } + + return null; + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |