diff --git a/library/core/src/androidTest/java/com/google/android/exoplayer2/upstream/ContentDataSourceTest.java b/library/core/src/androidTest/java/com/google/android/exoplayer2/upstream/ContentDataSourceTest.java index 39c12e1b75..76af346649 100644 --- a/library/core/src/androidTest/java/com/google/android/exoplayer2/upstream/ContentDataSourceTest.java +++ b/library/core/src/androidTest/java/com/google/android/exoplayer2/upstream/ContentDataSourceTest.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer2.upstream; import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.fail; +import static org.junit.Assert.assertThrows; import android.content.ContentProvider; import android.content.ContentResolver; @@ -27,10 +28,12 @@ import android.net.Uri; import android.os.Bundle; import android.os.ParcelFileDescriptor; import androidx.annotation.Nullable; -import androidx.test.InstrumentationRegistry; +import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.testutil.TestUtil; +import com.google.android.exoplayer2.upstream.ContentDataSource.ContentDataSourceException; +import java.io.EOFException; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; @@ -78,7 +81,7 @@ public final class ContentDataSourceTest { @Test public void readInvalidUri() throws Exception { ContentDataSource dataSource = - new ContentDataSource(InstrumentationRegistry.getTargetContext()); + new ContentDataSource(ApplicationProvider.getApplicationContext()); Uri contentUri = TestContentProvider.buildUri("does/not.exist", false); DataSpec dataSpec = new DataSpec(contentUri); try { @@ -92,14 +95,44 @@ public final class ContentDataSourceTest { } } + @Test + public void read_positionPastEndOfContent_throwsEOFException() throws Exception { + Uri contentUri = TestContentProvider.buildUri(DATA_PATH, /* pipeMode= */ false); + ContentDataSource dataSource = + new ContentDataSource(ApplicationProvider.getApplicationContext()); + DataSpec dataSpec = new DataSpec(contentUri, /* position= */ 1025, C.LENGTH_UNSET); + try { + ContentDataSourceException exception = + assertThrows(ContentDataSourceException.class, () -> dataSource.open(dataSpec)); + assertThat(exception).hasCauseThat().isInstanceOf(EOFException.class); + } finally { + dataSource.close(); + } + } + + @Test + public void readPipeMode_positionPastEndOfContent_throwsEOFException() throws Exception { + Uri contentUri = TestContentProvider.buildUri(DATA_PATH, /* pipeMode= */ true); + ContentDataSource dataSource = + new ContentDataSource(ApplicationProvider.getApplicationContext()); + DataSpec dataSpec = new DataSpec(contentUri, /* position= */ 1025, C.LENGTH_UNSET); + try { + ContentDataSourceException exception = + assertThrows(ContentDataSourceException.class, () -> dataSource.open(dataSpec)); + assertThat(exception).hasCauseThat().isInstanceOf(EOFException.class); + } finally { + dataSource.close(); + } + } + private static void assertData(int offset, int length, boolean pipeMode) throws IOException { Uri contentUri = TestContentProvider.buildUri(DATA_PATH, pipeMode); ContentDataSource dataSource = - new ContentDataSource(InstrumentationRegistry.getTargetContext()); + new ContentDataSource(ApplicationProvider.getApplicationContext()); try { DataSpec dataSpec = new DataSpec(contentUri, offset, length); byte[] completeData = - TestUtil.getByteArray(InstrumentationRegistry.getTargetContext(), DATA_PATH); + TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), DATA_PATH); byte[] expectedData = Arrays.copyOfRange(completeData, offset, length == C.LENGTH_UNSET ? completeData.length : offset + length); TestUtil.assertDataSourceContent(dataSource, dataSpec, expectedData, !pipeMode); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/ContentDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/ContentDataSource.java index baaa677127..40fba37671 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/ContentDataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/ContentDataSource.java @@ -90,9 +90,19 @@ public final class ContentDataSource extends BaseDataSource { // returns 0 then the remaining length cannot be determined. FileChannel channel = inputStream.getChannel(); long channelSize = channel.size(); - bytesRemaining = channelSize == 0 ? C.LENGTH_UNSET : channelSize - channel.position(); + if (channelSize == 0) { + bytesRemaining = C.LENGTH_UNSET; + } else { + bytesRemaining = channelSize - channel.position(); + if (bytesRemaining < 0) { + throw new EOFException(); + } + } } else { bytesRemaining = assetFileDescriptorLength - skipped; + if (bytesRemaining < 0) { + throw new EOFException(); + } } } } catch (IOException e) {