Buggy code:
public final class DataSourceStream implements Loadable , NonBlockingInputStream { public static class DataSourceStreamLoadException extends IOException { public DataSourceStreamLoadException ( IOException cause ) { } } private final DataSource dataSource ; private final DataSpec dataSpec ; private final Allocator allocator ; private final DataSourceStream . ReadHead readHead ; private Allocation allocation ; private volatile boolean loadCanceled ; private volatile long loadPosition ; private volatile long resolvedLength ; private int writeFragmentIndex ; private int writeFragmentOffset ; private int writeFragmentRemainingLength ; public DataSourceStream ( DataSource dataSource , DataSpec dataSpec , Allocator allocator ) { } public void resetReadPosition ( ) { } public long getReadPosition ( ) { } public long getLoadPosition ( ) { } public long getLength ( ) { } public boolean isLoadFinished ( ) { } public final byte [ ] getLoadedData ( ) { } @ Override public long getAvailableByteCount ( ) { } @ Override public boolean isEndOfStream ( ) { } @ Override public void close ( ) { } @ Override public int skip ( int skipLength ) { } @ Override public int read ( ByteBuffer target1 , int readLength ) { } @ Override public int read ( byte [ ] target , int offset , int readLength ) { } private int read ( ByteBuffer target , byte [ ] targetArray , int targetArrayOffset , DataSourceStream . ReadHead readHead , int readLength ) { <START_BUG> if ( ( readHead . position ) == ( dataSpec . length ) ) { <END_BUG> return - 1 ; } int bytesToRead = ( ( int ) ( Math . min ( ( ( loadPosition ) - ( readHead . position ) ) , readLength ) ) ) ; if ( bytesToRead == 0 ) { return 0 ; } if ( ( readHead . position ) == 0 ) { readHead . fragmentIndex = 0 ; readHead . fragmentOffset = allocation . getFragmentOffset ( 0 ) ; readHead . fragmentRemaining = allocation . getFragmentLength ( 0 ) ; } int bytesRead = 0 ; byte [ ] [ ] buffers = allocation . getBuffers ( ) ; while ( bytesRead < bytesToRead ) { int bufferReadLength = Math . min ( readHead . fragmentRemaining , ( bytesToRead - bytesRead ) ) ; if ( target != null ) { target . put ( buffers [ readHead . fragmentIndex ] , readHead . fragmentOffset , bufferReadLength ) ; } else if ( targetArray != null ) { System . arraycopy ( buffers [ readHead . fragmentIndex ] , readHead . fragmentOffset , targetArray , targetArrayOffset , bufferReadLength ) ; targetArrayOffset += bufferReadLength ; } readHead . position += bufferReadLength ; bytesRead += bufferReadLength ; readHead . fragmentOffset += bufferReadLength ; readHead . fragmentRemaining -= bufferReadLength ; if ( ( ( readHead . fragmentRemaining ) == 0 ) && ( ( readHead . position ) < ( resolvedLength ) ) ) { ( readHead . fragmentIndex ) ++ ; readHead . fragmentOffset = allocation . getFragmentOffset ( readHead . fragmentIndex ) ; readHead . fragmentRemaining = allocation . getFragmentLength ( readHead . fragmentIndex ) ; } } return bytesRead ; } @ Override public void cancelLoad ( ) { } @ Override public boolean isLoadCanceled ( ) { } @ Override public void load ( ) throws IOException , InterruptedException { } private static class ReadHead { private int position ; private int fragmentIndex ; private int fragmentOffset ; private int fragmentRemaining ; public void reset ( ) { } } }

Fix:
if ( isEndOfStream ( ) ) {