Program: 3637
Project: 3637
Buggy source:
/** 
 * Directly examine contents of classfile binary header to determine annotations, implemented interfaces, the super-class etc.
 * @return the information obtained as a ClassInfo object, or null if the classfile is invalid.
 */
public static ClassInfo readClassInfoFromClassfileHeader(final String relativePath,final InputStream inputStream,final HashMap<String,HashMap<String,StaticFinalFieldMatchProcessor>> classNameToStaticFieldnameToMatchProcessor,final ArrayList<String> whitelistClassRefPrefix,final ArrayList<String> blacklistClassRefPrefix){
  try (final DataInputStream inp=new DataInputStream(new BufferedInputStream(inputStream,8192))){
    if (inp.readInt() != 0xCAFEBABE) {
      if (FastClasspathScanner.verbose) {
        Log.log("String_Node_Str" + relativePath);
      }
      return null;
    }
    inp.readUnsignedShort();
    inp.readUnsignedShort();
    final int cpCount=inp.readUnsignedShort();
    final Object[] constantPool=new Object[cpCount];
    final int[] indirectStringRef=new int[cpCount];
    Arrays.fill(indirectStringRef,-1);
    for (int i=1; i < cpCount; ++i) {
      final int tag=inp.readUnsignedByte();
switch (tag) {
case 1:
        constantPool[i]=inp.readUTF();
      break;
case 3:
    constantPool[i]=inp.readInt();
  break;
case 4:
constantPool[i]=inp.readFloat();
break;
case 5:
constantPool[i]=inp.readLong();
i++;
break;
case 6:
constantPool[i]=inp.readDouble();
i++;
break;
case 7:
case 8:
indirectStringRef[i]=inp.readUnsignedShort();
break;
case 9:
case 10:
case 11:
case 12:
inp.skipBytes(4);
break;
case 15:
inp.skipBytes(3);
break;
case 16:
inp.skipBytes(2);
break;
case 18:
inp.skipBytes(4);
break;
default :
break;
}
}
for (int i=1; i < cpCount; i++) {
if (indirectStringRef[i] >= 0) {
constantPool[i]=constantPool[indirectStringRef[i]];
}
}
final int flags=inp.readUnsignedShort();
final boolean isInterface=(flags & 0x0200) != 0;
final boolean isAnnotation=(flags & 0x2000) != 0;
final String classNamePath=readRefdString(inp,constantPool);
final String className=classNamePath.replace('/','.');
String superclassName=readRefdString(inp,constantPool);
if (superclassName != null) {
superclassName=superclassName.replace('/','.');
}
if (className.equals("String_Node_Str")) {
return null;
}
if (!className.equals(relativePath.substring(0,relativePath.length() - 6).replace('/','.'))) {
if (FastClasspathScanner.verbose) {
Log.log("String_Node_Str" + className + "String_Node_Str"+ relativePath+ "String_Node_Str");
}
return null;
}
final ClassInfo classInfo=new ClassInfo(className,isInterface && !isAnnotation,isAnnotation,superclassName);
final int interfaceCount=inp.readUnsignedShort();
classInfo.interfaceNames=interfaceCount > 0 ? new ArrayList<String>(interfaceCount) : null;
for (int i=0; i < interfaceCount; i++) {
classInfo.interfaceNames.add(readRefdString(inp,constantPool).replace('/','.'));
}
final HashMap<String,StaticFinalFieldMatchProcessor> staticFieldnameToMatchProcessor=classNameToStaticFieldnameToMatchProcessor.get(classInfo.className);
HashSet<String> whitelistedFieldTypes=null;
final int fieldCount=inp.readUnsignedShort();
for (int i=0; i < fieldCount; i++) {
final int accessFlags=inp.readUnsignedShort();
final boolean isStaticFinal=(accessFlags & 0x0018) == 0x0018;
final String fieldName=readRefdString(inp,constantPool);
final StaticFinalFieldMatchProcessor staticFinalFieldMatchProcessor=staticFieldnameToMatchProcessor != null ? staticFieldnameToMatchProcessor.get(fieldName) : null;
final String fieldTypeDescriptor=readRefdString(inp,constantPool);
final int attributesCount=inp.readUnsignedShort();
whitelistedFieldTypes=findWhitelistedTypeDescriptorParts(fieldTypeDescriptor,whitelistClassRefPrefix,blacklistClassRefPrefix,whitelistedFieldTypes);
if (!isStaticFinal && staticFinalFieldMatchProcessor != null) {
System.err.println(StaticFinalFieldMatchProcessor.class.getSimpleName() + "String_Node_Str" + classInfo.className+ "String_Node_Str"+ fieldName+ "String_Node_Str");
}
boolean foundConstantValue=false;
for (int j=0; j < attributesCount; j++) {
final String attributeName=readRefdString(inp,constantPool);
final int attributeLength=inp.readInt();
if (attributeName.equals("String_Node_Str") && isStaticFinal && staticFinalFieldMatchProcessor != null) {
Object constValue=constantPool[inp.readUnsignedShort()];
switch (fieldTypeDescriptor) {
case "String_Node_Str":
constValue=((Integer)constValue).byteValue();
break;
case "String_Node_Str":
constValue=(char)((Integer)constValue).intValue();
break;
case "String_Node_Str":
constValue=((Integer)constValue).shortValue();
break;
case "String_Node_Str":
constValue=((Integer)constValue).intValue() != 0;
break;
case "String_Node_Str":
case "String_Node_Str":
case "String_Node_Str":
case "String_Node_Str":
case "String_Node_Str":
break;
default :
break;
}
if (FastClasspathScanner.verbose) {
Log.log("String_Node_Str" + classInfo.className + "String_Node_Str"+ fieldName+ "String_Node_Str"+ constValue);
}
staticFinalFieldMatchProcessor.processMatch(classInfo.className,fieldName,constValue);
foundConstantValue=true;
}
 else if (attributeName.equals("String_Node_Str")) {
final String fieldTypeSignature=readRefdString(inp,constantPool);
whitelistedFieldTypes=findWhitelistedTypeDescriptorParts(fieldTypeSignature,whitelistClassRefPrefix,blacklistClassRefPrefix,whitelistedFieldTypes);
}
 else {
inp.skipBytes(attributeLength);
}
if (!foundConstantValue && isStaticFinal && staticFinalFieldMatchProcessor != null) {
System.err.println(StaticFinalFieldMatchProcessor.class.getSimpleName() + "String_Node_Str" + classInfo.className+ "String_Node_Str"+ fieldName+ "String_Node_Str"+ "String_Node_Str");
}
}
}
classInfo.whitelistedFieldTypes=whitelistedFieldTypes;
final int methodCount=inp.readUnsignedShort();
for (int i=0; i < methodCount; i++) {
inp.skipBytes(6);
final int attributesCount=inp.readUnsignedShort();
for (int j=0; j < attributesCount; j++) {
inp.skipBytes(2);
final int attributeLength=inp.readInt();
inp.skipBytes(attributeLength);
}
}
classInfo.annotationNames=null;
final int attributesCount=inp.readUnsignedShort();
for (int i=0; i < attributesCount; i++) {
final String attributeName=readRefdString(inp,constantPool);
final int attributeLength=inp.readInt();
if ("String_Node_Str".equals(attributeName)) {
final int annotationCount=inp.readUnsignedShort();
for (int m=0; m < annotationCount; m++) {
final String annotationName=readAnnotation(inp,constantPool);
if (!annotationName.startsWith("String_Node_Str")) {
if (classInfo.annotationNames == null) {
classInfo.annotationNames=new ArrayList<>();
}
classInfo.annotationNames.add(annotationName);
}
}
}
 else {
inp.skipBytes(attributeLength);
}
}
return classInfo;
}
 catch (final IOException e) {
Log.log("String_Node_Str" + relativePath + "String_Node_Str"+ e.getMessage());
return null;
}
}

Fixed version (ground truth):
/** 
 * Directly examine contents of classfile binary header to determine annotations, implemented interfaces, the super-class etc.
 * @return the information obtained as a ClassInfo object, or null if the classfile is invalid.
 */
public static ClassInfo readClassInfoFromClassfileHeader(final String relativePath,final InputStream inputStream,final HashMap<String,HashMap<String,StaticFinalFieldMatchProcessor>> classNameToStaticFieldnameToMatchProcessor,final ScanSpec scanSpec){
  try (final DataInputStream inp=new DataInputStream(new BufferedInputStream(inputStream,8192))){
    if (inp.readInt() != 0xCAFEBABE) {
      if (FastClasspathScanner.verbose) {
        Log.log("String_Node_Str" + relativePath);
      }
      return null;
    }
    inp.readUnsignedShort();
    inp.readUnsignedShort();
    final int cpCount=inp.readUnsignedShort();
    final Object[] constantPool=new Object[cpCount];
    final int[] indirectStringRef=new int[cpCount];
    Arrays.fill(indirectStringRef,-1);
    for (int i=1; i < cpCount; ++i) {
      final int tag=inp.readUnsignedByte();
switch (tag) {
case 1:
        constantPool[i]=inp.readUTF();
      break;
case 3:
    constantPool[i]=inp.readInt();
  break;
case 4:
constantPool[i]=inp.readFloat();
break;
case 5:
constantPool[i]=inp.readLong();
i++;
break;
case 6:
constantPool[i]=inp.readDouble();
i++;
break;
case 7:
case 8:
indirectStringRef[i]=inp.readUnsignedShort();
break;
case 9:
case 10:
case 11:
case 12:
inp.skipBytes(4);
break;
case 15:
inp.skipBytes(3);
break;
case 16:
inp.skipBytes(2);
break;
case 18:
inp.skipBytes(4);
break;
default :
break;
}
}
for (int i=1; i < cpCount; i++) {
if (indirectStringRef[i] >= 0) {
constantPool[i]=constantPool[indirectStringRef[i]];
}
}
final int flags=inp.readUnsignedShort();
final boolean isInterface=(flags & 0x0200) != 0;
final boolean isAnnotation=(flags & 0x2000) != 0;
final String classNamePath=readRefdString(inp,constantPool);
final String className=classNamePath.replace('/','.');
String superclassName=readRefdString(inp,constantPool);
if (superclassName != null) {
superclassName=superclassName.replace('/','.');
}
if (className.equals("String_Node_Str")) {
return null;
}
if (!className.equals(relativePath.substring(0,relativePath.length() - 6).replace('/','.'))) {
if (FastClasspathScanner.verbose) {
Log.log("String_Node_Str" + className + "String_Node_Str"+ relativePath+ "String_Node_Str");
}
return null;
}
final ClassInfo classInfo=new ClassInfo(className,isInterface && !isAnnotation,isAnnotation,superclassName);
final int interfaceCount=inp.readUnsignedShort();
classInfo.interfaceNames=interfaceCount > 0 ? new ArrayList<String>(interfaceCount) : null;
for (int i=0; i < interfaceCount; i++) {
classInfo.interfaceNames.add(readRefdString(inp,constantPool).replace('/','.'));
}
final HashMap<String,StaticFinalFieldMatchProcessor> staticFieldnameToMatchProcessor=classNameToStaticFieldnameToMatchProcessor.get(classInfo.className);
HashSet<String> whitelistedFieldTypes=null;
final int fieldCount=inp.readUnsignedShort();
for (int i=0; i < fieldCount; i++) {
final int accessFlags=inp.readUnsignedShort();
final boolean isStaticFinal=(accessFlags & 0x0018) == 0x0018;
final String fieldName=readRefdString(inp,constantPool);
final StaticFinalFieldMatchProcessor staticFinalFieldMatchProcessor=staticFieldnameToMatchProcessor != null ? staticFieldnameToMatchProcessor.get(fieldName) : null;
final String fieldTypeDescriptor=readRefdString(inp,constantPool);
final int attributesCount=inp.readUnsignedShort();
whitelistedFieldTypes=findWhitelistedTypeDescriptorParts(fieldTypeDescriptor,scanSpec,whitelistedFieldTypes);
if (!isStaticFinal && staticFinalFieldMatchProcessor != null) {
System.err.println(StaticFinalFieldMatchProcessor.class.getSimpleName() + "String_Node_Str" + classInfo.className+ "String_Node_Str"+ fieldName+ "String_Node_Str");
}
boolean foundConstantValue=false;
for (int j=0; j < attributesCount; j++) {
final String attributeName=readRefdString(inp,constantPool);
final int attributeLength=inp.readInt();
if (attributeName.equals("String_Node_Str") && isStaticFinal && staticFinalFieldMatchProcessor != null) {
Object constValue=constantPool[inp.readUnsignedShort()];
switch (fieldTypeDescriptor) {
case "String_Node_Str":
constValue=((Integer)constValue).byteValue();
break;
case "String_Node_Str":
constValue=(char)((Integer)constValue).intValue();
break;
case "String_Node_Str":
constValue=((Integer)constValue).shortValue();
break;
case "String_Node_Str":
constValue=((Integer)constValue).intValue() != 0;
break;
case "String_Node_Str":
case "String_Node_Str":
case "String_Node_Str":
case "String_Node_Str":
case "String_Node_Str":
break;
default :
break;
}
if (FastClasspathScanner.verbose) {
Log.log("String_Node_Str" + classInfo.className + "String_Node_Str"+ fieldName+ "String_Node_Str"+ constValue);
}
staticFinalFieldMatchProcessor.processMatch(classInfo.className,fieldName,constValue);
foundConstantValue=true;
}
 else if (attributeName.equals("String_Node_Str")) {
final String fieldTypeSignature=readRefdString(inp,constantPool);
whitelistedFieldTypes=findWhitelistedTypeDescriptorParts(fieldTypeSignature,scanSpec,whitelistedFieldTypes);
}
 else {
inp.skipBytes(attributeLength);
}
if (!foundConstantValue && isStaticFinal && staticFinalFieldMatchProcessor != null) {
System.err.println(StaticFinalFieldMatchProcessor.class.getSimpleName() + "String_Node_Str" + classInfo.className+ "String_Node_Str"+ fieldName+ "String_Node_Str"+ "String_Node_Str");
}
}
}
classInfo.whitelistedFieldTypes=whitelistedFieldTypes;
final int methodCount=inp.readUnsignedShort();
for (int i=0; i < methodCount; i++) {
inp.skipBytes(6);
final int attributesCount=inp.readUnsignedShort();
for (int j=0; j < attributesCount; j++) {
inp.skipBytes(2);
final int attributeLength=inp.readInt();
inp.skipBytes(attributeLength);
}
}
classInfo.annotationNames=null;
final int attributesCount=inp.readUnsignedShort();
for (int i=0; i < attributesCount; i++) {
final String attributeName=readRefdString(inp,constantPool);
final int attributeLength=inp.readInt();
if ("String_Node_Str".equals(attributeName)) {
final int annotationCount=inp.readUnsignedShort();
for (int m=0; m < annotationCount; m++) {
final String annotationName=readAnnotation(inp,constantPool);
if (!annotationName.startsWith("String_Node_Str")) {
if (classInfo.annotationNames == null) {
classInfo.annotationNames=new ArrayList<>();
}
classInfo.annotationNames.add(annotationName);
}
}
}
 else {
inp.skipBytes(attributeLength);
}
}
return classInfo;
}
 catch (final IOException e) {
Log.log("String_Node_Str" + relativePath + "String_Node_Str"+ e.getMessage());
return null;
}
}