Item summary = fieldSummary.getSummary(getXField()); String fieldSig = summary.getSignature(); if (isSerializable && !isExternalizable) { seenTransientField = true; transientFieldsUpdates.put(getXField(), 0); } else if (reportTransientFieldOfNonSerializableClass) { bugReporter.reportBug(new BugInstance(this, "SE_TRANSIENT_FIELD_OF_NONSERIALIZABLE_CLASS", NORMAL_PRIORITY) .addClass(this).addVisitedField(this)); } else if (getClassName().indexOf("ObjectStreamClass") == -1 && isSerializable && !isExternalizable && fieldSig.indexOf('L') >= 0 && !obj.isTransient() && !obj.isStatic()) { if (DEBUG) { System.out.println("Examining non-transient field with name: " + getFieldName() + ", sig: " + fieldSig); XField xfield = getXField(); Type type = TypeFrameModelingVisitor.getType(xfield); if (type instanceof ReferenceType) { int priority = computePriority(isSerializable, 0); if (!strongEvidenceForIntendedSerialization()) { if (obj.getName().startsWith("this$")) { priority = Math.max(priority, NORMAL_PRIORITY); System.out.println("SE_BAD_FIELD: " + getThisClass().getClassName() + " " + obj.getName() + " " + isSerializable + " " + implementsSerializableDirectly + " " + sawSerialVersionUID + " " + isGUIClass + " " + isEjbImplClass); fieldWarningList.add(new BugInstance(this, "SE_BAD_FIELD_INNER_CLASS", priority).addClass(getThisClass()
@Override public void visitClassContext(ClassContext classContext) { classContext.getJavaClass().accept(this); flush(); }
@Override public void sawOpcode(int seen) { if (seen == Const.PUTFIELD) { XField xField = getXFieldOperand(); if (xField != null && xField.getClassDescriptor().equals(getClassDescriptor())) { Item first = stack.getStackItem(0); if (Const.CONSTRUCTOR_NAME.equals(getMethodName())) { transientFieldsSetToDefaultValueInConstructor.add(xField); String nameOfField = getNameConstantOperand(); if (Const.CONSTRUCTOR_NAME.equals(getMethodName())) { transientFieldsSetInConstructor.add(xField); } else { if (!sig.equals(genSig)) { double bias = 0.0; if (!Const.CONSTRUCTOR_NAME.equals(getMethodName())) { bias = 1.0; int priority = computePriority(isSerializable, bias); .addClass(getThisClass().getClassName()).addField(f).addType(genSig) .describe("TYPE_FOUND").addSourceLine(this));
if (Const.CONSTRUCTOR_NAME.equals(getMethodName()) && "()V".equals(getMethodSig()) && (accessFlags & Const.ACC_PUBLIC) != 0) { hasPublicVoidConstructor = true; if (!Const.CONSTRUCTOR_NAME.equals(getMethodName()) && isSynthetic(obj)) if ("readExternal".equals(getMethodName()) && "(Ljava/io/ObjectInput;)V".equals(getMethodSig())) { sawReadExternal = true; if (DEBUG && !obj.isPrivate()) { System.out.println("Non-private readExternal method in: " + getDottedClassName()); } else if ("writeExternal".equals(getMethodName()) && "(Ljava/io/Objectoutput;)V".equals(getMethodSig())) { sawWriteExternal = true; if (DEBUG && !obj.isPrivate()) { System.out.println("Non-private writeExternal method in: " + getDottedClassName()); } else if ("readResolve".equals(getMethodName()) && getMethodSig().startsWith("()") && isSerializable) { sawReadResolve = true; if (!"()Ljava/lang/Object;".equals(getMethodSig())) { bugReporter.reportBug(new BugInstance(this, "SE_READ_RESOLVE_MUST_RETURN_OBJECT", HIGH_PRIORITY) .addClassAndMethod(this)); try { Set<ClassDescriptor> subtypes = AnalysisContext.currentAnalysisContext().getSubtypes2() .getSubtypes(getClassDescriptor()); if (subtypes.size() > 1) { BugInstance bug = new BugInstance(this, "SE_PRIVATE_READ_RESOLVE_NOT_INHERITED", NORMAL_PRIORITY) boolean nasty = false; for (ClassDescriptor subclass : subtypes) {
System.out.println(getDottedClassName()); System.out.println(" hasPublicVoidConstructor: " + hasPublicVoidConstructor); System.out.println(" superClassHasVoidConstructor: " + superClassHasVoidConstructor); bugReporter.reportBug(new BugInstance(this, "SE_TRANSIENT_FIELD_NOT_RESTORED", priority).addClass(getThisClass()) .addField(fieldX)); priority++; bugReporter.reportBug(new BugInstance(this, "SE_NO_SUITABLE_CONSTRUCTOR", priority).addClass(getThisClass() .getClassName())); directlyImplementsExternalizable ? HIGH_PRIORITY : NORMAL_PRIORITY).addClass(getThisClass().getClassName()));
isAnonymousInnerClass = anonymousInnerClassNamePattern.matcher(getClassName()).matches(); innerClassHasOuterInstance = false; for (Field f : obj.getFields()) { isExternalizable = true; if (DEBUG) { System.out.println("Directly implements Externalizable: " + getClassName()); isSerializable = true; if (DEBUG) { System.out.println("Directly implements Serializable: " + getClassName()); isExternalizable = true; if (DEBUG) { System.out.println("Indirectly implements Externalizable: " + getClassName()); isSerializable = true; if (DEBUG) { System.out.println("Indirectly implements Serializable: " + getClassName()); superClassHasReadObject = false; superClassImplementsSerializable = isSerializable && !implementsSerializableDirectly; ClassDescriptor superclassDescriptor = getXClass().getSuperclassDescriptor(); if (superclassDescriptor != null) { try {
private boolean strongEvidenceForIntendedSerialization() { return implementsSerializableDirectly || sawReadObject || sawReadResolve || sawWriteObject || seenTransientField || AnalysisContext.currentAnalysisContext().getUnreadFieldsData() .existsStrongEvidenceForIntendedSerialization(this.getClassDescriptor()); }
if ("<init>".equals(getMethodName()) && "()V".equals(getMethodSig()) && (accessFlags & ACC_PUBLIC) != 0) { hasPublicVoidConstructor = true; if (!"<init>".equals(getMethodName()) && isSynthetic(obj)) if ("readExternal".equals(getMethodName()) && "(Ljava/io/ObjectInput;)V".equals(getMethodSig())) { sawReadExternal = true; if (DEBUG && !obj.isPrivate()) { System.out.println("Non-private readExternal method in: " + getDottedClassName()); } else if ("writeExternal".equals(getMethodName()) && "(Ljava/io/Objectoutput;)V".equals(getMethodSig())) { sawWriteExternal = true; if (DEBUG && !obj.isPrivate()) { System.out.println("Non-private writeExternal method in: " + getDottedClassName()); } else if ("readResolve".equals(getMethodName()) && getMethodSig().startsWith("()") && isSerializable) { sawReadResolve = true; if (!"()Ljava/lang/Object;".equals(getMethodSig())) { bugReporter.reportBug(new BugInstance(this, "SE_READ_RESOLVE_MUST_RETURN_OBJECT", HIGH_PRIORITY) .addClassAndMethod(this)); try { Set<ClassDescriptor> subtypes = AnalysisContext.currentAnalysisContext().getSubtypes2() .getSubtypes(getClassDescriptor()); if (subtypes.size() > 1) { BugInstance bug = new BugInstance(this, "SE_PRIVATE_READ_RESOLVE_NOT_INHERITED", NORMAL_PRIORITY) boolean nasty = false; for (ClassDescriptor subclass : subtypes) {
System.out.println(getDottedClassName()); System.out.println(" hasPublicVoidConstructor: " + hasPublicVoidConstructor); System.out.println(" superClassHasVoidConstructor: " + superClassHasVoidConstructor); bugReporter.reportBug(new BugInstance(this, "SE_TRANSIENT_FIELD_NOT_RESTORED", priority).addClass(getThisClass()) .addField(fieldX)); priority++; bugReporter.reportBug(new BugInstance(this, "SE_NO_SUITABLE_CONSTRUCTOR", priority).addClass(getThisClass() .getClassName())); directlyImplementsExternalizable ? HIGH_PRIORITY : NORMAL_PRIORITY).addClass(getThisClass().getClassName()));
isAnonymousInnerClass = anonymousInnerClassNamePattern.matcher(getClassName()).matches(); innerClassHasOuterInstance = false; for (Field f : obj.getFields()) { isExternalizable = true; if (DEBUG) { System.out.println("Directly implements Externalizable: " + getClassName()); isSerializable = true; if (DEBUG) { System.out.println("Directly implements Serializable: " + getClassName()); isExternalizable = true; if (DEBUG) { System.out.println("Indirectly implements Externalizable: " + getClassName()); isSerializable = true; if (DEBUG) { System.out.println("Indirectly implements Serializable: " + getClassName()); superClassHasReadObject = false; superClassImplementsSerializable = isSerializable && !implementsSerializableDirectly; ClassDescriptor superclassDescriptor = getXClass().getSuperclassDescriptor(); if (superclassDescriptor != null) { try {
private boolean strongEvidenceForIntendedSerialization() { return implementsSerializableDirectly || sawReadObject || sawReadResolve || sawWriteObject || seenTransientField || AnalysisContext.currentAnalysisContext().getUnreadFieldsData() .existsStrongEvidenceForIntendedSerialization(this.getClassDescriptor()); }
Item summary = fieldSummary.getSummary(getXField()); String fieldSig = summary.getSignature(); if (isSerializable && !isExternalizable) { seenTransientField = true; transientFieldsUpdates.put(getXField(), 0); } else if (reportTransientFieldOfNonSerializableClass) { bugReporter.reportBug(new BugInstance(this, "SE_TRANSIENT_FIELD_OF_NONSERIALIZABLE_CLASS", NORMAL_PRIORITY) .addClass(this).addVisitedField(this)); } else if (getClassName().indexOf("ObjectStreamClass") == -1 && isSerializable && !isExternalizable && fieldSig.indexOf('L') >= 0 && !obj.isTransient() && !obj.isStatic()) { if (DEBUG) { System.out.println("Examining non-transient field with name: " + getFieldName() + ", sig: " + fieldSig); XField xfield = getXField(); Type type = TypeFrameModelingVisitor.getType(xfield); if (type instanceof ReferenceType) { int priority = computePriority(isSerializable, 0); if (!strongEvidenceForIntendedSerialization()) { if (obj.getName().startsWith("this$")) { priority = Math.max(priority, NORMAL_PRIORITY); System.out.println("SE_BAD_FIELD: " + getThisClass().getClassName() + " " + obj.getName() + " " + isSerializable + " " + implementsSerializableDirectly + " " + sawSerialVersionUID + " " + isGUIClass + " " + isEjbImplClass); fieldWarningList.add(new BugInstance(this, "SE_BAD_FIELD_INNER_CLASS", priority).addClass(getThisClass()
@Override public void sawOpcode(int seen) { if (seen == PUTFIELD) { XField xField = getXFieldOperand(); if (xField != null && xField.getClassDescriptor().equals(getClassDescriptor())) { Item first = stack.getStackItem(0); if ("<init>".equals(getMethodName())) { transientFieldsSetToDefaultValueInConstructor.add(xField); String nameOfField = getNameConstantOperand(); if ("<init>".equals(getMethodName())) { transientFieldsSetInConstructor.add(xField); } else { if (!sig.equals(genSig)) { double bias = 0.0; if (!"<init>".equals(getMethodName())) { bias = 1.0; int priority = computePriority(isSerializable, bias); .addClass(getThisClass().getClassName()).addField(f).addType(genSig) .describe("TYPE_FOUND").addSourceLine(this));
@Override public void visitClassContext(ClassContext classContext) { classContext.getJavaClass().accept(this); flush(); }