edu.umd.cs.findbugs.detect.ExplicitSerialization Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spotbugs Show documentation
Show all versions of spotbugs Show documentation
SpotBugs: Because it's easy!
The newest version!
/*
* FindBugs - Find bugs in Java programs
* Copyright (C) 2004-2006 University of Maryland
*
* 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 edu.umd.cs.findbugs.detect;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.apache.bcel.Const;
import org.apache.bcel.classfile.JavaClass;
import edu.umd.cs.findbugs.BugReporter;
import edu.umd.cs.findbugs.NonReportingDetector;
import edu.umd.cs.findbugs.OpcodeStack;
import edu.umd.cs.findbugs.ba.AnalysisContext;
import edu.umd.cs.findbugs.ba.XClass;
import edu.umd.cs.findbugs.ba.XFactory;
import edu.umd.cs.findbugs.ba.XMethod;
import edu.umd.cs.findbugs.ba.ch.Subtypes2;
import edu.umd.cs.findbugs.bcel.OpcodeStackDetector;
import edu.umd.cs.findbugs.classfile.CheckedAnalysisException;
import edu.umd.cs.findbugs.classfile.ClassDescriptor;
import edu.umd.cs.findbugs.classfile.DescriptorFactory;
import edu.umd.cs.findbugs.classfile.Global;
public class ExplicitSerialization extends OpcodeStackDetector implements NonReportingDetector {
// The availability of these depends on the current analysis, so they can't be static
private final XMethod writeObject = XFactory.createXMethod("java.io.ObjectOutputStream", "writeObject", "(Ljava/lang/Object;)V", false);
private final XMethod readObject = XFactory.createXMethod("java.io.ObjectInputStream", "readObject", "()Ljava/lang/Object;", false);
private static final ClassDescriptor ObjectOutputStream = DescriptorFactory.createClassDescriptor(ObjectOutputStream.class);
private static final ClassDescriptor ObjectInputStream = DescriptorFactory.createClassDescriptor(ObjectInputStream.class);
private final UnreadFieldsData unreadFields;
private final BugReporter bugReporter;
public ExplicitSerialization(BugReporter bugReporter) {
AnalysisContext context = AnalysisContext.currentAnalysisContext();
unreadFields = context.getUnreadFieldsData();
this.bugReporter = bugReporter;
}
@Override
public boolean shouldVisit(JavaClass obj) {
XClass xClass = getXClass();
return xClass.getCalledClassDescriptors().contains(ObjectOutputStream)
|| xClass.getCalledClassDescriptors().contains(ObjectInputStream);
}
@Override
public void sawOpcode(int seen) {
if (seen == Const.INVOKEVIRTUAL && writeObject.equals(getXMethodOperand())) {
OpcodeStack.Item top = stack.getStackItem(0);
String signature = top.getSignature();
while (signature.charAt(0) == '[') {
signature = signature.substring(1);
}
ClassDescriptor c = DescriptorFactory.createClassDescriptorFromFieldSignature(signature);
if (c == null || !Subtypes2.instanceOf(c, Serializable.class)) {
return;
}
try {
XClass xClass = Global.getAnalysisCache().getClassAnalysis(XClass.class, c);
if (xClass.isInterface()) {
return;
}
if (xClass.isSynthetic()) {
return;
}
if (xClass.isAbstract()) {
return;
}
unreadFields.strongEvidenceForIntendedSerialization(c);
} catch (CheckedAnalysisException e) {
bugReporter.logError("Error looking up xClass of " + c, e);
}
}
if (seen == Const.CHECKCAST) {
OpcodeStack.Item top = stack.getStackItem(0);
if (readObject.equals(top.getReturnValueOf())) {
ClassDescriptor c = getClassDescriptorOperand();
if (!Subtypes2.instanceOf(c, Serializable.class)) {
return;
}
try {
XClass xClass = Global.getAnalysisCache().getClassAnalysis(XClass.class, c);
if (xClass.isInterface()) {
return;
}
if (xClass.isSynthetic()) {
return;
}
if (xClass.isAbstract()) {
return;
}
unreadFields.strongEvidenceForIntendedSerialization(c);
} catch (CheckedAnalysisException e) {
bugReporter.logError("Error looking up xClass of " + c, e);
}
}
}
}
}