From dd7b379dc0344316488eb816e06638182a9eed90 Mon Sep 17 00:00:00 2001 From: christosts Date: Tue, 22 Dec 2020 11:47:39 +0000 Subject: [PATCH] DataSource.open() throws if already opened. Update DataSource implementations to throw an error if open() is called when the DataSource is already open. PiperOrigin-RevId: 348609860 --- .../exoplayer2/ext/media2/PlayerTestRule.java | 9 +++++- .../ext/okhttp/OkHttpDataSource.java | 2 ++ .../exoplayer2/ext/rtmp/RtmpDataSource.java | 5 ++++ .../exoplayer2/upstream/AssetDataSource.java | 2 ++ .../upstream/ByteArrayDataSource.java | 2 ++ .../upstream/ContentDataSource.java | 3 ++ .../upstream/DataSchemeDataSource.java | 2 ++ .../upstream/DefaultHttpDataSource.java | 2 ++ .../exoplayer2/upstream/FileDataSource.java | 2 ++ .../upstream/PriorityDataSource.java | 9 +++++- .../upstream/RawResourceDataSource.java | 2 ++ .../upstream/ResolvingDataSource.java | 2 ++ .../exoplayer2/upstream/StatsDataSource.java | 6 ++++ .../exoplayer2/upstream/UdpDataSource.java | 3 ++ .../upstream/cache/CacheDataSource.java | 8 ++++-- .../upstream/crypto/AesCipherDataSource.java | 5 ++++ .../upstream/BaseDataSourceTest.java | 6 ++++ .../upstream/DataSchemeDataSourceTest.java | 28 ++++++++++--------- .../upstream/cache/CacheDataSourceTest.java | 1 + .../source/hls/Aes128DataSource.java | 7 ++++- .../source/hls/Aes128DataSourceTest.java | 2 ++ 21 files changed, 90 insertions(+), 18 deletions(-) diff --git a/extensions/media2/src/androidTest/java/com/google/android/exoplayer2/ext/media2/PlayerTestRule.java b/extensions/media2/src/androidTest/java/com/google/android/exoplayer2/ext/media2/PlayerTestRule.java index df6963c2fc..9400a90ffc 100644 --- a/extensions/media2/src/androidTest/java/com/google/android/exoplayer2/ext/media2/PlayerTestRule.java +++ b/extensions/media2/src/androidTest/java/com/google/android/exoplayer2/ext/media2/PlayerTestRule.java @@ -15,6 +15,8 @@ */ package com.google.android.exoplayer2.ext.media2; +import static com.google.android.exoplayer2.util.Assertions.checkState; + import android.content.Context; import android.net.Uri; import android.os.Looper; @@ -143,6 +145,7 @@ import org.junit.rules.ExternalResource; private final DataSource wrappedDataSource; private final DataSourceInstrumentation instrumentation; + private boolean opened; public InstrumentedDataSource( DataSource wrappedDataSource, DataSourceInstrumentation instrumentation) { @@ -157,8 +160,11 @@ import org.junit.rules.ExternalResource; @Override public long open(DataSpec dataSpec) throws IOException { + checkState(!opened); instrumentation.onPreOpen(dataSpec); - return wrappedDataSource.open(dataSpec); + long length = wrappedDataSource.open(dataSpec); + opened = true; + return length; } @Nullable @@ -180,6 +186,7 @@ import org.junit.rules.ExternalResource; @Override public void close() throws IOException { wrappedDataSource.close(); + opened = false; } } } diff --git a/extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSource.java b/extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSource.java index 92bf8281f5..b0f091ef45 100644 --- a/extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSource.java +++ b/extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSource.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer2.ext.okhttp; import static com.google.android.exoplayer2.ExoPlayerLibraryInfo.DEFAULT_USER_AGENT; +import static com.google.android.exoplayer2.util.Assertions.checkState; import static com.google.android.exoplayer2.util.Util.castNonNull; import static java.lang.Math.min; @@ -277,6 +278,7 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource { @Override public long open(DataSpec dataSpec) throws HttpDataSourceException { + checkState(!opened); this.dataSpec = dataSpec; this.bytesRead = 0; this.bytesSkipped = 0; diff --git a/extensions/rtmp/src/main/java/com/google/android/exoplayer2/ext/rtmp/RtmpDataSource.java b/extensions/rtmp/src/main/java/com/google/android/exoplayer2/ext/rtmp/RtmpDataSource.java index 587e310d64..d228972ca0 100644 --- a/extensions/rtmp/src/main/java/com/google/android/exoplayer2/ext/rtmp/RtmpDataSource.java +++ b/extensions/rtmp/src/main/java/com/google/android/exoplayer2/ext/rtmp/RtmpDataSource.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.ext.rtmp; +import static com.google.android.exoplayer2.util.Assertions.checkState; import static com.google.android.exoplayer2.util.Util.castNonNull; import android.net.Uri; @@ -37,6 +38,7 @@ public final class RtmpDataSource extends BaseDataSource { @Nullable private RtmpClient rtmpClient; @Nullable private Uri uri; + private boolean opened; public RtmpDataSource() { super(/* isNetwork= */ true); @@ -44,12 +46,14 @@ public final class RtmpDataSource extends BaseDataSource { @Override public long open(DataSpec dataSpec) throws RtmpIOException { + checkState(!opened); transferInitializing(dataSpec); rtmpClient = new RtmpClient(); rtmpClient.open(dataSpec.uri.toString(), false); this.uri = dataSpec.uri; transferStarted(dataSpec); + opened = true; return C.LENGTH_UNSET; } @@ -73,6 +77,7 @@ public final class RtmpDataSource extends BaseDataSource { rtmpClient.close(); rtmpClient = null; } + opened = false; } @Override diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/AssetDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/AssetDataSource.java index e529e28846..fa171094d9 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/AssetDataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/AssetDataSource.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.upstream; +import static com.google.android.exoplayer2.util.Assertions.checkState; import static com.google.android.exoplayer2.util.Util.castNonNull; import static java.lang.Math.min; @@ -57,6 +58,7 @@ public final class AssetDataSource extends BaseDataSource { @Override public long open(DataSpec dataSpec) throws AssetDataSourceException { + checkState(!opened); try { uri = dataSpec.uri; String path = Assertions.checkNotNull(uri.getPath()); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/ByteArrayDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/ByteArrayDataSource.java index 17e9073128..1d1d7cfea5 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/ByteArrayDataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/ByteArrayDataSource.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.upstream; +import static com.google.android.exoplayer2.util.Assertions.checkState; import static java.lang.Math.min; import android.net.Uri; @@ -45,6 +46,7 @@ public final class ByteArrayDataSource extends BaseDataSource { @Override public long open(DataSpec dataSpec) throws IOException { + checkState(!opened); uri = dataSpec.uri; transferInitializing(dataSpec); readPosition = (int) dataSpec.position; 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 b659c5ca98..a7bad13437 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 @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.upstream; +import static com.google.android.exoplayer2.util.Assertions.checkState; import static com.google.android.exoplayer2.util.Util.castNonNull; import static java.lang.Math.min; @@ -62,6 +63,8 @@ public final class ContentDataSource extends BaseDataSource { @Override public long open(DataSpec dataSpec) throws ContentDataSourceException { + checkState(!opened); + try { Uri uri = dataSpec.uri; this.uri = uri; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/DataSchemeDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/DataSchemeDataSource.java index 2c3670f52a..515f757183 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/DataSchemeDataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/DataSchemeDataSource.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.upstream; +import static com.google.android.exoplayer2.util.Assertions.checkState; import static com.google.android.exoplayer2.util.Util.castNonNull; import static java.lang.Math.min; @@ -44,6 +45,7 @@ public final class DataSchemeDataSource extends BaseDataSource { @Override public long open(DataSpec dataSpec) throws IOException { + checkState(this.dataSpec == null); transferInitializing(dataSpec); this.dataSpec = dataSpec; readPosition = (int) dataSpec.position; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/DefaultHttpDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/DefaultHttpDataSource.java index 15bee2c118..7a70d1a546 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/DefaultHttpDataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/DefaultHttpDataSource.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer2.upstream; import static com.google.android.exoplayer2.ExoPlayerLibraryInfo.DEFAULT_USER_AGENT; +import static com.google.android.exoplayer2.util.Assertions.checkState; import static java.lang.Math.max; import static java.lang.Math.min; @@ -342,6 +343,7 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou */ @Override public long open(DataSpec dataSpec) throws HttpDataSourceException { + checkState(!opened); this.dataSpec = dataSpec; this.bytesRead = 0; this.bytesSkipped = 0; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/FileDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/FileDataSource.java index d34e43eb46..f9ccf044c7 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/FileDataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/FileDataSource.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.upstream; +import static com.google.android.exoplayer2.util.Assertions.checkState; import static com.google.android.exoplayer2.util.Util.castNonNull; import static java.lang.Math.min; @@ -80,6 +81,7 @@ public final class FileDataSource extends BaseDataSource { @Override public long open(DataSpec dataSpec) throws FileDataSourceException { + checkState(!opened); try { Uri uri = dataSpec.uri; this.uri = uri; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/PriorityDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/PriorityDataSource.java index e52e1db376..2a73461bdc 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/PriorityDataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/PriorityDataSource.java @@ -15,6 +15,8 @@ */ package com.google.android.exoplayer2.upstream; +import static com.google.android.exoplayer2.util.Assertions.checkState; + import android.net.Uri; import androidx.annotation.Nullable; import com.google.android.exoplayer2.util.Assertions; @@ -40,6 +42,7 @@ public final class PriorityDataSource implements DataSource { private final DataSource upstream; private final PriorityTaskManager priorityTaskManager; private final int priority; + private boolean opened; /** * @param upstream The upstream {@link DataSource}. @@ -61,8 +64,11 @@ public final class PriorityDataSource implements DataSource { @Override public long open(DataSpec dataSpec) throws IOException { + checkState(!opened); priorityTaskManager.proceedOrThrow(priority); - return upstream.open(dataSpec); + long length = upstream.open(dataSpec); + opened = true; + return length; } @Override @@ -85,6 +91,7 @@ public final class PriorityDataSource implements DataSource { @Override public void close() throws IOException { upstream.close(); + opened = false; } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/RawResourceDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/RawResourceDataSource.java index 7538cc67a4..b154fa5c16 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/RawResourceDataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/RawResourceDataSource.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.upstream; +import static com.google.android.exoplayer2.util.Assertions.checkState; import static com.google.android.exoplayer2.util.Util.castNonNull; import static java.lang.Math.min; @@ -98,6 +99,7 @@ public final class RawResourceDataSource extends BaseDataSource { @Override public long open(DataSpec dataSpec) throws RawResourceDataSourceException { + checkState(!opened); Uri uri = dataSpec.uri; this.uri = uri; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/ResolvingDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/ResolvingDataSource.java index 958780cbc3..c60e6daf68 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/ResolvingDataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/ResolvingDataSource.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer2.upstream; import static com.google.android.exoplayer2.util.Assertions.checkNotNull; +import static com.google.android.exoplayer2.util.Assertions.checkState; import android.net.Uri; import androidx.annotation.Nullable; @@ -103,6 +104,7 @@ public final class ResolvingDataSource implements DataSource { @Override public long open(DataSpec dataSpec) throws IOException { + checkState(!upstreamOpened); DataSpec resolvedDataSpec = resolver.resolveDataSpec(dataSpec); upstreamOpened = true; return upstreamDataSource.open(resolvedDataSpec); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/StatsDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/StatsDataSource.java index 4340169f45..aabbb094e7 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/StatsDataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/StatsDataSource.java @@ -15,6 +15,8 @@ */ package com.google.android.exoplayer2.upstream; +import static com.google.android.exoplayer2.util.Assertions.checkState; + import android.net.Uri; import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; @@ -35,6 +37,7 @@ public final class StatsDataSource implements DataSource { private long bytesRead; private Uri lastOpenedUri; private Map> lastResponseHeaders; + private boolean opened; /** * Creates the stats data source. @@ -78,12 +81,14 @@ public final class StatsDataSource implements DataSource { @Override public long open(DataSpec dataSpec) throws IOException { + checkState(!opened); // Reassign defaults in case dataSource.open throws an exception. lastOpenedUri = dataSpec.uri; lastResponseHeaders = Collections.emptyMap(); long availableBytes = dataSource.open(dataSpec); lastOpenedUri = Assertions.checkNotNull(getUri()); lastResponseHeaders = getResponseHeaders(); + opened = true; return availableBytes; } @@ -110,5 +115,6 @@ public final class StatsDataSource implements DataSource { @Override public void close() throws IOException { dataSource.close(); + opened = false; } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/UdpDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/UdpDataSource.java index 2da837e788..947c5fb798 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/UdpDataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/UdpDataSource.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.upstream; +import static com.google.android.exoplayer2.util.Assertions.checkState; import static java.lang.Math.min; import android.net.Uri; @@ -89,6 +90,8 @@ public final class UdpDataSource extends BaseDataSource { @Override public long open(DataSpec dataSpec) throws UdpDataSourceException { + checkState(!opened); + uri = dataSpec.uri; String host = uri.getHost(); int port = uri.getPort(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSource.java index c2bbdbb893..fc1acb4d47 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSource.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer2.upstream.cache; import static com.google.android.exoplayer2.util.Assertions.checkNotNull; +import static com.google.android.exoplayer2.util.Assertions.checkState; import static com.google.android.exoplayer2.util.Util.castNonNull; import static java.lang.Math.min; @@ -33,7 +34,6 @@ import com.google.android.exoplayer2.upstream.PriorityDataSource; import com.google.android.exoplayer2.upstream.TeeDataSource; import com.google.android.exoplayer2.upstream.TransferListener; import com.google.android.exoplayer2.upstream.cache.Cache.CacheException; -import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.PriorityTaskManager; import java.io.IOException; import java.io.InterruptedIOException; @@ -397,6 +397,7 @@ public final class CacheDataSource implements DataSource { private boolean currentRequestIgnoresCache; private long totalCachedBytesRead; private long checkCachePosition; + private boolean opened; /** * Constructs an instance with default {@link DataSource} and {@link DataSink} instances for @@ -552,6 +553,7 @@ public final class CacheDataSource implements DataSource { @Override public long open(DataSpec dataSpec) throws IOException { + checkState(!opened); try { String key = cacheKeyFactory.buildCacheKey(dataSpec); DataSpec requestDataSpec = dataSpec.buildUpon().setKey(key).build(); @@ -577,6 +579,7 @@ public final class CacheDataSource implements DataSource { } } openNextSource(requestDataSpec, false); + opened = true; return bytesRemaining; } catch (Throwable e) { handleBeforeThrow(e); @@ -649,6 +652,7 @@ public final class CacheDataSource implements DataSource { notifyBytesRead(); try { closeCurrentSource(); + opened = false; } catch (Throwable e) { handleBeforeThrow(e); throw e; @@ -739,7 +743,7 @@ public final class CacheDataSource implements DataSource { ? readPosition + MIN_READ_BEFORE_CHECKING_CACHE : Long.MAX_VALUE; if (checkCache) { - Assertions.checkState(isBypassingCache()); + checkState(isBypassingCache()); if (nextDataSource == upstreamDataSource) { // Continue reading from upstream. return; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/crypto/AesCipherDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/crypto/AesCipherDataSource.java index 5abe42b937..13040377ad 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/crypto/AesCipherDataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/crypto/AesCipherDataSource.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer2.upstream.crypto; import static com.google.android.exoplayer2.util.Assertions.checkNotNull; +import static com.google.android.exoplayer2.util.Assertions.checkState; import static com.google.android.exoplayer2.util.Util.castNonNull; import android.net.Uri; @@ -36,6 +37,7 @@ public final class AesCipherDataSource implements DataSource { private final DataSource upstream; private final byte[] secretKey; + private boolean opened; @Nullable private AesFlushingCipher cipher; @@ -52,11 +54,13 @@ public final class AesCipherDataSource implements DataSource { @Override public long open(DataSpec dataSpec) throws IOException { + checkState(!opened); long dataLength = upstream.open(dataSpec); long nonce = CryptoUtil.getFNV64Hash(dataSpec.key); cipher = new AesFlushingCipher( Cipher.DECRYPT_MODE, secretKey, nonce, dataSpec.uriPositionOffset + dataSpec.position); + opened = true; return dataLength; } @@ -88,5 +92,6 @@ public final class AesCipherDataSource implements DataSource { public void close() throws IOException { cipher = null; upstream.close(); + opened = false; } } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/upstream/BaseDataSourceTest.java b/library/core/src/test/java/com/google/android/exoplayer2/upstream/BaseDataSourceTest.java index 1eb49188bf..09cc1522f0 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/upstream/BaseDataSourceTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/upstream/BaseDataSourceTest.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.upstream; +import static com.google.android.exoplayer2.util.Assertions.checkState; import static com.google.common.truth.Truth.assertThat; import android.net.Uri; @@ -89,14 +90,18 @@ public class BaseDataSourceTest { private static final class TestSource extends BaseDataSource { + private boolean opened; + public TestSource(boolean isNetwork) { super(isNetwork); } @Override public long open(DataSpec dataSpec) throws IOException { + checkState(!opened); transferInitializing(dataSpec); transferStarted(dataSpec); + opened = true; return C.LENGTH_UNSET; } @@ -115,6 +120,7 @@ public class BaseDataSourceTest { @Override public void close() throws IOException { transferEnded(); + opened = false; } } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/upstream/DataSchemeDataSourceTest.java b/library/core/src/test/java/com/google/android/exoplayer2/upstream/DataSchemeDataSourceTest.java index 7a99b97bd5..6a52be184e 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/upstream/DataSchemeDataSourceTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/upstream/DataSchemeDataSourceTest.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer2.upstream; import static com.google.android.exoplayer2.C.RESULT_END_OF_INPUT; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; import android.net.Uri; @@ -130,19 +131,20 @@ public final class DataSchemeDataSourceTest { } @Test - public void malformedData() { - try { - schemeDataDataSource.open(buildDataSpec("data:text/plain;base64,,This%20is%20Content")); - fail(); - } catch (IOException e) { - // Expected. - } - try { - schemeDataDataSource.open(buildDataSpec("data:text/plain;base64,IncorrectPadding==")); - fail(); - } catch (IOException e) { - // Expected. - } + public void malformedData_throwsIOException() { + assertThrows( + IOException.class, + () -> + schemeDataDataSource.open( + buildDataSpec("data:text/plain;base64,,This%20is%20Content"))); + } + + @Test + public void malformedData_incorrectPadding_throwsIOException() { + assertThrows( + IOException.class, + () -> + schemeDataDataSource.open(buildDataSpec("data:text/plain;base64,IncorrectPadding=="))); } @Test diff --git a/library/core/src/test/java/com/google/android/exoplayer2/upstream/cache/CacheDataSourceTest.java b/library/core/src/test/java/com/google/android/exoplayer2/upstream/cache/CacheDataSourceTest.java index 5ee8e423b7..f761afac55 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/upstream/cache/CacheDataSourceTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/upstream/cache/CacheDataSourceTest.java @@ -284,6 +284,7 @@ public final class CacheDataSourceTest { cacheDataSource.open( buildDataSpec(TEST_DATA.length - 2, C.LENGTH_UNSET, defaultCacheKey))) .isEqualTo(2); + cacheDataSource.close(); // An unbounded request with offset for not cached content. dataSpec = diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/Aes128DataSource.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/Aes128DataSource.java index 11d68b1c08..2f8786e11e 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/Aes128DataSource.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/Aes128DataSource.java @@ -15,6 +15,8 @@ */ package com.google.android.exoplayer2.source.hls; +import static com.google.android.exoplayer2.util.Assertions.checkState; + import android.net.Uri; import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; @@ -50,6 +52,7 @@ import javax.crypto.spec.SecretKeySpec; private final DataSource upstream; private final byte[] encryptionKey; private final byte[] encryptionIv; + private boolean opened; @Nullable private CipherInputStream cipherInputStream; @@ -72,6 +75,7 @@ import javax.crypto.spec.SecretKeySpec; @Override public final long open(DataSpec dataSpec) throws IOException { + checkState(!opened); Cipher cipher; try { cipher = getCipherInstance(); @@ -91,7 +95,7 @@ import javax.crypto.spec.SecretKeySpec; DataSourceInputStream inputStream = new DataSourceInputStream(upstream, dataSpec); cipherInputStream = new CipherInputStream(inputStream, cipher); inputStream.open(); - + opened = true; return C.LENGTH_UNSET; } @@ -121,6 +125,7 @@ import javax.crypto.spec.SecretKeySpec; if (cipherInputStream != null) { cipherInputStream = null; upstream.close(); + opened = false; } } diff --git a/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/Aes128DataSourceTest.java b/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/Aes128DataSourceTest.java index 3eef5c36d2..881697e4af 100644 --- a/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/Aes128DataSourceTest.java +++ b/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/Aes128DataSourceTest.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.source.hls; +import static com.google.android.exoplayer2.util.Assertions.checkState; import static com.google.common.truth.Truth.assertThat; import android.net.Uri; @@ -104,6 +105,7 @@ public class Aes128DataSourceTest { @Override public long open(DataSpec dataSpec) throws IOException { + checkState(!opened); opened = true; return C.LENGTH_UNSET; }