From f7b8d07cd2faac1dbe97a6c294548ca782ec6dd4 Mon Sep 17 00:00:00 2001 From: ibaker Date: Wed, 2 Oct 2019 11:53:03 +0100 Subject: [PATCH] Add specific error message if file-not-found for path with fragment or query This doesn't change the current behaviour, just adds a clear error message to the developer with instructions on how to avoid it. Issue:#6470 PiperOrigin-RevId: 272405556 --- RELEASENOTES.md | 2 ++ .../exoplayer2/upstream/FileDataSource.java | 26 +++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 50418ded28..83997fe3c7 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -89,6 +89,8 @@ [#5973](https://github.com/google/ExoPlayer/issues/5973)). * Expose the raw ICY metadata through `IcyInfo` ([#6476](https://github.com/google/ExoPlayer/issues/6476)). +* Fail more explicitly when local-file Uris contain invalid parts (e.g. + fragment) ([#6470](https://github.com/google/ExoPlayer/issues/6470)). ### 2.10.5 (2019-09-20) ### 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 e329dc722e..38b4a1da03 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 @@ -18,10 +18,12 @@ package com.google.android.exoplayer2.upstream; import static com.google.android.exoplayer2.util.Util.castNonNull; import android.net.Uri; +import android.text.TextUtils; import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.util.Assertions; import java.io.EOFException; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; @@ -37,6 +39,9 @@ public final class FileDataSource extends BaseDataSource { super(cause); } + public FileDataSourceException(String message, IOException cause) { + super(message, cause); + } } @Nullable private RandomAccessFile file; @@ -55,8 +60,8 @@ public final class FileDataSource extends BaseDataSource { this.uri = uri; transferInitializing(dataSpec); - RandomAccessFile file = new RandomAccessFile(Assertions.checkNotNull(uri.getPath()), "r"); - this.file = file; + + this.file = openLocalFile(uri); file.seek(dataSpec.position); bytesRemaining = dataSpec.length == C.LENGTH_UNSET ? file.length() - dataSpec.position @@ -74,6 +79,23 @@ public final class FileDataSource extends BaseDataSource { return bytesRemaining; } + private static RandomAccessFile openLocalFile(Uri uri) throws FileDataSourceException { + try { + return new RandomAccessFile(Assertions.checkNotNull(uri.getPath()), "r"); + } catch (FileNotFoundException e) { + if (!TextUtils.isEmpty(uri.getQuery()) || !TextUtils.isEmpty(uri.getFragment())) { + throw new FileDataSourceException( + String.format( + "uri has query and/or fragment, which are not supported. Did you call Uri.parse()" + + " on a string containing '?' or '#'? Use Uri.fromFile(new File(path)) to" + + " avoid this. path=%s,query=%s,fragment=%s", + uri.getPath(), uri.getQuery(), uri.getFragment()), + e); + } + throw new FileDataSourceException(e); + } + } + @Override public int read(byte[] buffer, int offset, int readLength) throws FileDataSourceException { if (readLength == 0) {