Program: 64301
Project: 64301
Buggy source:
/** 
 * Reads bytes from the current tar archive entry. This method is aware of the boundaries of the current entry in the archive and will deal with them as if they were this stream's start and EOF.
 * @param buf The buffer into which to place bytes read.
 * @param offset The offset at which to place bytes read.
 * @param count The number of bytes to read.
 * @return The number of bytes read, or -1 at EOF.
 */
public int read(final byte[] buffer,final int offset,final int count) throws IOException {
  int position=offset;
  int numToRead=count;
  int totalRead=0;
  if (m_entryOffset >= m_entrySize) {
    return -1;
  }
  if ((numToRead + m_entryOffset) > m_entrySize) {
    numToRead=(m_entrySize - m_entryOffset);
  }
  if (null != m_readBuf) {
    final int size=(numToRead > m_readBuf.length) ? m_readBuf.length : numToRead;
    System.arraycopy(m_readBuf,0,buffer,position,size);
    if (size >= m_readBuf.length) {
      m_readBuf=null;
    }
 else {
      final int newLength=m_readBuf.length - size;
      final byte[] newBuffer=new byte[newLength];
      System.arraycopy(m_readBuf,size,newBuffer,0,newLength);
      m_readBuf=newBuffer;
    }
    totalRead+=size;
    numToRead-=size;
    position+=size;
  }
  while (numToRead > 0) {
    final byte[] rec=m_buffer.readRecord();
    if (null == rec) {
      final String message="String_Node_Str" + numToRead + "String_Node_Str";
      throw new IOException(message);
    }
    int size=numToRead;
    final int recordLength=rec.length;
    if (recordLength > size) {
      System.arraycopy(rec,0,buffer,position,size);
      m_readBuf=new byte[recordLength - size];
      System.arraycopy(rec,size,m_readBuf,0,recordLength - size);
    }
 else {
      size=recordLength;
      System.arraycopy(rec,0,buffer,position,recordLength);
    }
    totalRead+=size;
    numToRead-=size;
    position+=size;
  }
  m_entryOffset+=totalRead;
  return totalRead;
}

Fixed version (ground truth):
/** 
 * Reads bytes from the current tar archive entry. This method is aware of the boundaries of the current entry in the archive and will deal with them as if they were this stream's start and EOF.
 * @param buffer The buffer into which to place bytes read.
 * @param offset The offset at which to place bytes read.
 * @param count The number of bytes to read.
 * @return The number of bytes read, or -1 at EOF.
 */
public int read(final byte[] buffer,final int offset,final int count) throws IOException {
  int position=offset;
  int numToRead=count;
  int totalRead=0;
  if (m_entryOffset >= m_entrySize) {
    return -1;
  }
  if ((numToRead + m_entryOffset) > m_entrySize) {
    numToRead=(m_entrySize - m_entryOffset);
  }
  if (null != m_readBuf) {
    final int size=(numToRead > m_readBuf.length) ? m_readBuf.length : numToRead;
    System.arraycopy(m_readBuf,0,buffer,position,size);
    if (size >= m_readBuf.length) {
      m_readBuf=null;
    }
 else {
      final int newLength=m_readBuf.length - size;
      final byte[] newBuffer=new byte[newLength];
      System.arraycopy(m_readBuf,size,newBuffer,0,newLength);
      m_readBuf=newBuffer;
    }
    totalRead+=size;
    numToRead-=size;
    position+=size;
  }
  while (numToRead > 0) {
    final byte[] rec=m_buffer.readRecord();
    if (null == rec) {
      final String message="String_Node_Str" + numToRead + "String_Node_Str";
      throw new IOException(message);
    }
    int size=numToRead;
    final int recordLength=rec.length;
    if (recordLength > size) {
      System.arraycopy(rec,0,buffer,position,size);
      m_readBuf=new byte[recordLength - size];
      System.arraycopy(rec,size,m_readBuf,0,recordLength - size);
    }
 else {
      size=recordLength;
      System.arraycopy(rec,0,buffer,position,recordLength);
    }
    totalRead+=size;
    numToRead-=size;
    position+=size;
  }
  m_entryOffset+=totalRead;
  return totalRead;
}