Program: 92898
Project: 92898
Buggy source:
/** 
 * Processes a TIFF IFD. <p/> IFD Header: <ul> <li><b>2 bytes</b> number of tags</li> </ul> Tag structure: <ul> <li><b>2 bytes</b> tag type</li> <li><b>2 bytes</b> format code (values 1 to 12, inclusive)</li> <li><b>4 bytes</b> component count</li> <li><b>4 bytes</b> inline value, or offset pointer if too large to fit in four bytes</li> </ul>
 * @param handler the {@link com.drew.imaging.tiff.TiffHandler} that will coordinate processing and accept read values
 * @param reader the {@link com.drew.lang.RandomAccessReader} from which the data should be read
 * @param processedIfdOffsets the set of visited IFD offsets, to avoid revisiting the same IFD in an endless loop
 * @param ifdOffset the offset within <code>reader</code> at which the IFD data starts
 * @param tiffHeaderOffset the offset within <code>reader</code> at which the TIFF header starts
 * @throws IOException an error occurred while accessing the required data
 */
public static void processIfd(@NotNull final TiffHandler handler,@NotNull final RandomAccessReader reader,@NotNull final Set<Integer> processedIfdOffsets,final int ifdOffset,final int tiffHeaderOffset) throws IOException {
  try {
    if (processedIfdOffsets.contains(Integer.valueOf(ifdOffset))) {
      return;
    }
    processedIfdOffsets.add(ifdOffset);
    if (ifdOffset >= reader.getLength() || ifdOffset < 0) {
      handler.error("String_Node_Str");
      return;
    }
    int dirTagCount=reader.getUInt16(ifdOffset);
    int dirLength=(2 + (12 * dirTagCount) + 4);
    if (dirLength + ifdOffset > reader.getLength()) {
      handler.error("String_Node_Str");
      return;
    }
    for (int tagNumber=0; tagNumber < dirTagCount; tagNumber++) {
      final int tagOffset=calculateTagOffset(ifdOffset,tagNumber);
      final int tagId=reader.getUInt16(tagOffset);
      final int formatCode=reader.getUInt16(tagOffset + 2);
      final TiffDataFormat format=TiffDataFormat.fromTiffFormatCode(formatCode);
      if (format == null) {
        handler.error("String_Node_Str" + formatCode);
        return;
      }
      final int componentCount=reader.getInt32(tagOffset + 4);
      if (componentCount < 0) {
        handler.error("String_Node_Str");
        continue;
      }
      final int byteCount=componentCount * format.getComponentSizeBytes();
      final int tagValueOffset;
      if (byteCount > 4) {
        final int offsetVal=reader.getInt32(tagOffset + 8);
        if (offsetVal + byteCount > reader.getLength()) {
          handler.error("String_Node_Str");
          continue;
        }
        tagValueOffset=tiffHeaderOffset + offsetVal;
      }
 else {
        tagValueOffset=tagOffset + 8;
      }
      if (tagValueOffset < 0 || tagValueOffset > reader.getLength()) {
        handler.error("String_Node_Str");
        continue;
      }
      if (byteCount < 0 || tagValueOffset + byteCount > reader.getLength()) {
        handler.error("String_Node_Str" + byteCount);
        continue;
      }
      if (byteCount == 4 && handler.isTagIfdPointer(tagId)) {
        final int subDirOffset=tiffHeaderOffset + reader.getInt32(tagValueOffset);
        processIfd(handler,reader,processedIfdOffsets,subDirOffset,tiffHeaderOffset);
      }
 else {
        if (!handler.customProcessTag(tagValueOffset,processedIfdOffsets,tiffHeaderOffset,reader,tagId,byteCount)) {
          processTag(handler,tagId,tagValueOffset,componentCount,formatCode,reader);
        }
      }
    }
    final int finalTagOffset=calculateTagOffset(ifdOffset,dirTagCount);
    int nextIfdOffset=reader.getInt32(finalTagOffset);
    if (nextIfdOffset != 0) {
      nextIfdOffset+=tiffHeaderOffset;
      if (nextIfdOffset >= reader.getLength()) {
        return;
      }
 else       if (nextIfdOffset < ifdOffset) {
        return;
      }
      if (handler.hasFollowerIfd()) {
        processIfd(handler,reader,processedIfdOffsets,nextIfdOffset,tiffHeaderOffset);
      }
    }
  }
  finally {
    handler.endingIFD();
  }
}

Fixed version (ground truth):
/** 
 * Processes a TIFF IFD. IFD Header: <ul> <li><b>2 bytes</b> number of tags</li> </ul> Tag structure: <ul> <li><b>2 bytes</b> tag type</li> <li><b>2 bytes</b> format code (values 1 to 12, inclusive)</li> <li><b>4 bytes</b> component count</li> <li><b>4 bytes</b> inline value, or offset pointer if too large to fit in four bytes</li> </ul>
 * @param handler the {@link com.drew.imaging.tiff.TiffHandler} that will coordinate processing and accept read values
 * @param reader the {@link com.drew.lang.RandomAccessReader} from which the data should be read
 * @param processedIfdOffsets the set of visited IFD offsets, to avoid revisiting the same IFD in an endless loop
 * @param ifdOffset the offset within <code>reader</code> at which the IFD data starts
 * @param tiffHeaderOffset the offset within <code>reader</code> at which the TIFF header starts
 * @throws IOException an error occurred while accessing the required data
 */
public static void processIfd(@NotNull final TiffHandler handler,@NotNull final RandomAccessReader reader,@NotNull final Set<Integer> processedIfdOffsets,final int ifdOffset,final int tiffHeaderOffset) throws IOException {
  try {
    if (processedIfdOffsets.contains(Integer.valueOf(ifdOffset))) {
      return;
    }
    processedIfdOffsets.add(ifdOffset);
    if (ifdOffset >= reader.getLength() || ifdOffset < 0) {
      handler.error("String_Node_Str");
      return;
    }
    int dirTagCount=reader.getUInt16(ifdOffset);
    int dirLength=(2 + (12 * dirTagCount) + 4);
    if (dirLength + ifdOffset > reader.getLength()) {
      handler.error("String_Node_Str");
      return;
    }
    for (int tagNumber=0; tagNumber < dirTagCount; tagNumber++) {
      final int tagOffset=calculateTagOffset(ifdOffset,tagNumber);
      final int tagId=reader.getUInt16(tagOffset);
      final int formatCode=reader.getUInt16(tagOffset + 2);
      final TiffDataFormat format=TiffDataFormat.fromTiffFormatCode(formatCode);
      if (format == null) {
        handler.error("String_Node_Str" + formatCode);
        return;
      }
      final int componentCount=reader.getInt32(tagOffset + 4);
      if (componentCount < 0) {
        handler.error("String_Node_Str");
        continue;
      }
      final int byteCount=componentCount * format.getComponentSizeBytes();
      final int tagValueOffset;
      if (byteCount > 4) {
        final int offsetVal=reader.getInt32(tagOffset + 8);
        if (offsetVal + byteCount > reader.getLength()) {
          handler.error("String_Node_Str");
          continue;
        }
        tagValueOffset=tiffHeaderOffset + offsetVal;
      }
 else {
        tagValueOffset=tagOffset + 8;
      }
      if (tagValueOffset < 0 || tagValueOffset > reader.getLength()) {
        handler.error("String_Node_Str");
        continue;
      }
      if (byteCount < 0 || tagValueOffset + byteCount > reader.getLength()) {
        handler.error("String_Node_Str" + byteCount);
        continue;
      }
      if (byteCount == 4 && handler.isTagIfdPointer(tagId)) {
        final int subDirOffset=tiffHeaderOffset + reader.getInt32(tagValueOffset);
        processIfd(handler,reader,processedIfdOffsets,subDirOffset,tiffHeaderOffset);
      }
 else {
        if (!handler.customProcessTag(tagValueOffset,processedIfdOffsets,tiffHeaderOffset,reader,tagId,byteCount)) {
          processTag(handler,tagId,tagValueOffset,componentCount,formatCode,reader);
        }
      }
    }
    final int finalTagOffset=calculateTagOffset(ifdOffset,dirTagCount);
    int nextIfdOffset=reader.getInt32(finalTagOffset);
    if (nextIfdOffset != 0) {
      nextIfdOffset+=tiffHeaderOffset;
      if (nextIfdOffset >= reader.getLength()) {
        return;
      }
 else       if (nextIfdOffset < ifdOffset) {
        return;
      }
      if (handler.hasFollowerIfd()) {
        processIfd(handler,reader,processedIfdOffsets,nextIfdOffset,tiffHeaderOffset);
      }
    }
  }
  finally {
    handler.endingIFD();
  }
}