From 36efdc74922fb8dc4c016e1f0337316ad44b7ed8 Mon Sep 17 00:00:00 2001 From: olly Date: Thu, 6 Aug 2020 12:41:02 +0100 Subject: [PATCH] Fix MP4 sniffing for very short files The sniffer sniffs boxes at the start of the file to try and determine whether the file is fragmented. However, if the file is extremely short then it's possible that sniffing will try and read beyond the end of the file, resulting i EOFException being thrown. In general it's OK for sniffing to throw EOFException if the file is not of the correct type. The problem in this case is that EOFException can be thrown for an actual MP4 file, due to the sniffer continuing up sniff atoms up to bytesToSearch in case the file is fragmented. PiperOrigin-RevId: 325205389 --- RELEASENOTES.md | 6 ++++-- .../google/android/exoplayer2/extractor/mp4/Sniffer.java | 7 ++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index dcae95e28f..5b3228c0d6 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -4,8 +4,10 @@ * Fix distorted playback of floating point audio when samples exceed the `[-1, 1]` nominal range. -* MP4: Add support for `piff` and `isml` brands - ([#7584](https://github.com/google/ExoPlayer/issues/7584)). +* MP4: + * Add support for `piff` and `isml` brands + ([#7584](https://github.com/google/ExoPlayer/issues/7584)). + * Fix playback of very short MP4 files. * FMP4: Fix `saiz` and `senc` sample count checks, resolving a "length mismatch" `ParserException` when playing certain protected FMP4 streams ([#7592](https://github.com/google/ExoPlayer/issues/7592)). diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/Sniffer.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/Sniffer.java index 40e516aefd..1e1c5450be 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/Sniffer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/Sniffer.java @@ -103,7 +103,12 @@ import java.io.IOException; // Read an atom header. int headerSize = Atom.HEADER_SIZE; buffer.reset(headerSize); - input.peekFully(buffer.data, 0, headerSize); + boolean success = + input.peekFully(buffer.data, 0, headerSize, /* allowEndOfInput= */ true); + if (!success) { + // We've reached the end of the file. + break; + } long atomSize = buffer.readUnsignedInt(); int atomType = buffer.readInt(); if (atomSize == Atom.DEFINES_LARGE_SIZE) {