Skip to content

Commit

Permalink
Handle size==0 in MP4 atoms
Browse files Browse the repository at this point in the history
Issue: #3191

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=165925148
  • Loading branch information
ojw28 authored and Oliver Woodman committed Sep 8, 2017
1 parent 85bc8a0 commit cc5cfd4
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 13 deletions.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package com.google.android.exoplayer2.extractor.mp4;

import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import com.google.android.exoplayer2.testutil.ExtractorAsserts.ExtractorFactory;
Expand All @@ -38,11 +37,6 @@ public void testSampleWithSeiPayloadParsing() throws Exception {
"mp4/sample_fragmented_sei.mp4", getInstrumentation());
}

public void testAtomWithZeroSize() throws Exception {
ExtractorAsserts.assertThrows(getExtractorFactory(), "mp4/sample_fragmented_zero_size_atom.mp4",
getInstrumentation(), ParserException.class);
}

private static ExtractorFactory getExtractorFactory() {
return getExtractorFactory(0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,14 @@
public static final int LONG_HEADER_SIZE = 16;

/**
* Value for the first 32 bits of atomSize when the atom size is actually a long value.
* Value for the size field in an atom that defines its size in the largesize field.
*/
public static final int LONG_SIZE_PREFIX = 1;
public static final int DEFINES_LARGE_SIZE = 1;

/**
* Value for the size field in an atom that extends to the end of the file.
*/
public static final int EXTENDS_TO_END_SIZE = 0;

public static final int TYPE_ftyp = Util.getIntegerCodeForString("ftyp");
public static final int TYPE_avc1 = Util.getIntegerCodeForString("avc1");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,12 +283,22 @@ private boolean readAtomHeader(ExtractorInput input) throws IOException, Interru
atomType = atomHeader.readInt();
}

if (atomSize == Atom.LONG_SIZE_PREFIX) {
// Read the extended atom size.
if (atomSize == Atom.DEFINES_LARGE_SIZE) {
// Read the large size.
int headerBytesRemaining = Atom.LONG_HEADER_SIZE - Atom.HEADER_SIZE;
input.readFully(atomHeader.data, Atom.HEADER_SIZE, headerBytesRemaining);
atomHeaderBytesRead += headerBytesRemaining;
atomSize = atomHeader.readUnsignedLongToLong();
} else if (atomSize == Atom.EXTENDS_TO_END_SIZE) {
// The atom extends to the end of the file. Note that if the atom is within a container we can
// work out its size even if the input length is unknown.
long endPosition = input.getLength();
if (endPosition == C.LENGTH_UNSET && !containerAtoms.isEmpty()) {
endPosition = containerAtoms.peek().endPosition;
}
if (endPosition != C.LENGTH_UNSET) {
atomSize = endPosition - input.getPosition() + atomHeaderBytesRead;
}
}

if (atomSize < atomHeaderBytesRead) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,26 @@ private boolean readAtomHeader(ExtractorInput input) throws IOException, Interru
atomType = atomHeader.readInt();
}

if (atomSize == Atom.LONG_SIZE_PREFIX) {
// Read the extended atom size.
if (atomSize == Atom.DEFINES_LARGE_SIZE) {
// Read the large size.
int headerBytesRemaining = Atom.LONG_HEADER_SIZE - Atom.HEADER_SIZE;
input.readFully(atomHeader.data, Atom.HEADER_SIZE, headerBytesRemaining);
atomHeaderBytesRead += headerBytesRemaining;
atomSize = atomHeader.readUnsignedLongToLong();
} else if (atomSize == Atom.EXTENDS_TO_END_SIZE) {
// The atom extends to the end of the file. Note that if the atom is within a container we can
// work out its size even if the input length is unknown.
long endPosition = input.getLength();
if (endPosition == C.LENGTH_UNSET && !containerAtoms.isEmpty()) {
endPosition = containerAtoms.peek().endPosition;
}
if (endPosition != C.LENGTH_UNSET) {
atomSize = endPosition - input.getPosition() + atomHeaderBytesRead;
}
}

if (atomSize < atomHeaderBytesRead) {
throw new ParserException("Atom size less than header length (unsupported).");
}

if (shouldParseContainerAtom(atomType)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,18 @@ private static boolean sniffInternal(ExtractorInput input, boolean fragmented)
input.peekFully(buffer.data, 0, headerSize);
long atomSize = buffer.readUnsignedInt();
int atomType = buffer.readInt();
if (atomSize == Atom.LONG_SIZE_PREFIX) {
if (atomSize == Atom.DEFINES_LARGE_SIZE) {
// Read the large atom size.
headerSize = Atom.LONG_HEADER_SIZE;
input.peekFully(buffer.data, Atom.HEADER_SIZE, Atom.LONG_HEADER_SIZE - Atom.HEADER_SIZE);
buffer.setLimit(Atom.LONG_HEADER_SIZE);
atomSize = buffer.readUnsignedLongToLong();
} else if (atomSize == Atom.EXTENDS_TO_END_SIZE) {
// The atom extends to the end of the file.
long endPosition = input.getLength();
if (endPosition != C.LENGTH_UNSET) {
atomSize = endPosition - input.getPosition() + headerSize;
}
}

if (atomSize < headerSize) {
Expand Down

0 comments on commit cc5cfd4

Please sign in to comment.