Throw EOFException if requested position is past end of content

PiperOrigin-RevId: 318046646
This commit is contained in:
olly 2020-06-24 13:26:54 +01:00 committed by Christos Tsilopoulos
parent 54eccd3893
commit 35cd367c4c
2 changed files with 48 additions and 5 deletions

View file

@ -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);

View file

@ -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) {