Remove the last deprecated ParserException constructor

PiperOrigin-RevId: 381221669
This commit is contained in:
aquilescanta 2021-06-24 11:53:51 +01:00 committed by Oliver Woodman
parent 1cb4fb290f
commit fc26d4eeb1
34 changed files with 234 additions and 135 deletions

View File

@ -327,7 +327,8 @@ public class SampleChooserActivity extends AppCompatActivity
reader.nextString(); // Ignore. reader.nextString(); // Ignore.
break; break;
default: default:
throw new ParserException("Unsupported name: " + name); throw ParserException.createForMalformedManifest(
"Unsupported name: " + name, /* cause= */ null);
} }
} }
reader.endObject(); reader.endObject();
@ -415,7 +416,8 @@ public class SampleChooserActivity extends AppCompatActivity
reader.endArray(); reader.endArray();
break; break;
default: default:
throw new ParserException("Unsupported attribute name: " + name); throw ParserException.createForMalformedManifest(
"Unsupported attribute name: " + name, /* cause= */ null);
} }
} }
reader.endObject(); reader.endObject();

View File

@ -148,7 +148,8 @@ import java.nio.ByteBuffer;
public FlacStreamMetadata decodeStreamMetadata() throws IOException { public FlacStreamMetadata decodeStreamMetadata() throws IOException {
FlacStreamMetadata streamMetadata = flacDecodeMetadata(nativeDecoderContext); FlacStreamMetadata streamMetadata = flacDecodeMetadata(nativeDecoderContext);
if (streamMetadata == null) { if (streamMetadata == null) {
throw new ParserException("Failed to decode stream metadata"); throw ParserException.createForMalformedContainer(
"Failed to decode stream metadata", /* cause= */ null);
} }
return streamMetadata; return streamMetadata;
} }

View File

@ -96,18 +96,6 @@ public class ParserException extends IOException {
/** The {@link DataType data type} of the parsed bitstream. */ /** The {@link DataType data type} of the parsed bitstream. */
public final int dataType; public final int dataType;
/**
* Creates a new instance.
*
* @param message The detail message for the exception.
* @deprecated Use a factory method which initializes {@link #contentIsMalformed}, and {@link
* #dataType} instead.
*/
@Deprecated
public ParserException(String message) {
this(message, /* cause= */ null, /* contentIsMalformed= */ true, C.DATA_TYPE_UNKNOWN);
}
protected ParserException( protected ParserException(
@Nullable String message, @Nullable String message,
@Nullable Throwable cause, @Nullable Throwable cause,

View File

@ -229,7 +229,8 @@ public final class AacUtil {
parseGaSpecificConfig(bitArray, audioObjectType, channelConfiguration); parseGaSpecificConfig(bitArray, audioObjectType, channelConfiguration);
break; break;
default: default:
throw new ParserException("Unsupported audio object type: " + audioObjectType); throw ParserException.createForUnsupportedContainerFeature(
"Unsupported audio object type: " + audioObjectType);
} }
switch (audioObjectType) { switch (audioObjectType) {
case 17: case 17:
@ -240,7 +241,8 @@ public final class AacUtil {
case 23: case 23:
int epConfig = bitArray.readBits(2); int epConfig = bitArray.readBits(2);
if (epConfig == 2 || epConfig == 3) { if (epConfig == 2 || epConfig == 3) {
throw new ParserException("Unsupported epConfig: " + epConfig); throw ParserException.createForUnsupportedContainerFeature(
"Unsupported epConfig: " + epConfig);
} }
break; break;
default: default:

View File

@ -1216,7 +1216,8 @@ public final class Util {
public static long parseXsDateTime(String value) throws ParserException { public static long parseXsDateTime(String value) throws ParserException {
Matcher matcher = XS_DATE_TIME_PATTERN.matcher(value); Matcher matcher = XS_DATE_TIME_PATTERN.matcher(value);
if (!matcher.matches()) { if (!matcher.matches()) {
throw new ParserException("Invalid date/time format: " + value); throw ParserException.createForMalformedContainer(
"Invalid date/time format: " + value, /* cause= */ null);
} }
int timezoneShift; int timezoneShift;

View File

@ -237,7 +237,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public void maybeThrowPrepareError() throws IOException { public void maybeThrowPrepareError() throws IOException {
maybeThrowError(); maybeThrowError();
if (loadingFinished && !prepared) { if (loadingFinished && !prepared) {
throw new ParserException("Loading finished before preparation is complete."); throw ParserException.createForMalformedContainer(
"Loading finished before preparation is complete.", /* cause= */ null);
} }
} }

View File

@ -40,7 +40,8 @@ public final class WebvttParserUtil {
int startPosition = input.getPosition(); int startPosition = input.getPosition();
if (!isWebvttHeaderLine(input)) { if (!isWebvttHeaderLine(input)) {
input.setPosition(startPosition); input.setPosition(startPosition);
throw new ParserException("Expected WEBVTT. Got " + input.readLine()); throw ParserException.createForMalformedContainer(
"Expected WEBVTT. Got " + input.readLine(), /* cause= */ null);
} }
} }

View File

@ -23,6 +23,7 @@ import android.util.Base64;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ParserException; import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import java.io.IOException; import java.io.IOException;
@ -48,12 +49,11 @@ public final class DataSchemeDataSource extends BaseDataSource {
this.dataSpec = dataSpec; this.dataSpec = dataSpec;
Uri uri = dataSpec.uri; Uri uri = dataSpec.uri;
String scheme = uri.getScheme(); String scheme = uri.getScheme();
if (!SCHEME_DATA.equals(scheme)) { Assertions.checkArgument(SCHEME_DATA.equals(scheme), "Unsupported scheme: " + scheme);
throw new ParserException("Unsupported scheme: " + scheme);
}
String[] uriParts = Util.split(uri.getSchemeSpecificPart(), ","); String[] uriParts = Util.split(uri.getSchemeSpecificPart(), ",");
if (uriParts.length != 2) { if (uriParts.length != 2) {
throw new ParserException("Unexpected URI format: " + uri); throw ParserException.createForMalformedDataOfUnknownType(
"Unexpected URI format: " + uri, /* cause= */ null);
} }
String dataString = uriParts[1]; String dataString = uriParts[1];
if (uriParts[0].contains(";base64")) { if (uriParts[0].contains(";base64")) {

View File

@ -108,11 +108,11 @@ public final class DataSchemeDataSourceTest {
} }
@Test @Test
public void incorrectScheme() { public void incorrectScheme() throws IOException {
try { try {
schemeDataDataSource.open(buildDataSpec("http://www.google.com")); schemeDataDataSource.open(buildDataSpec("http://www.google.com"));
fail(); fail();
} catch (IOException e) { } catch (IllegalArgumentException e) {
// Expected. // Expected.
} }
} }

View File

@ -1443,7 +1443,8 @@ public final class DashMediaSource extends BaseMediaSource {
try { try {
Matcher matcher = TIMESTAMP_WITH_TIMEZONE_PATTERN.matcher(firstLine); Matcher matcher = TIMESTAMP_WITH_TIMEZONE_PATTERN.matcher(firstLine);
if (!matcher.matches()) { if (!matcher.matches()) {
throw new ParserException("Couldn't parse timestamp: " + firstLine); throw ParserException.createForMalformedManifest(
"Couldn't parse timestamp: " + firstLine, /* cause= */ null);
} }
// Parse the timestamp. // Parse the timestamp.
String timestampWithoutTimezone = matcher.group(1); String timestampWithoutTimezone = matcher.group(1);

View File

@ -169,7 +169,8 @@ public class DashManifestParser extends DefaultHandler
// early access. // early access.
seenEarlyAccessPeriod = true; seenEarlyAccessPeriod = true;
} else { } else {
throw new ParserException("Unable to determine start of period " + periods.size()); throw ParserException.createForMalformedManifest(
"Unable to determine start of period " + periods.size(), /* cause= */ null);
} }
} else { } else {
long periodDurationMs = periodWithDurationMs.second; long periodDurationMs = periodWithDurationMs.second;
@ -187,12 +188,13 @@ public class DashManifestParser extends DefaultHandler
// If we know the end time of the final period, we can use it as the duration. // If we know the end time of the final period, we can use it as the duration.
durationMs = nextPeriodStartMs; durationMs = nextPeriodStartMs;
} else if (!dynamic) { } else if (!dynamic) {
throw new ParserException("Unable to determine duration of static manifest."); throw ParserException.createForMalformedManifest(
"Unable to determine duration of static manifest.", /* cause= */ null);
} }
} }
if (periods.isEmpty()) { if (periods.isEmpty()) {
throw new ParserException("No periods found."); throw ParserException.createForMalformedManifest("No periods found.", /* cause= */ null);
} }
return buildMediaPresentationDescription( return buildMediaPresentationDescription(

View File

@ -120,7 +120,8 @@ public final class FlacMetadataReader {
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.STREAM_MARKER_SIZE); ParsableByteArray scratch = new ParsableByteArray(FlacConstants.STREAM_MARKER_SIZE);
input.readFully(scratch.getData(), 0, FlacConstants.STREAM_MARKER_SIZE); input.readFully(scratch.getData(), 0, FlacConstants.STREAM_MARKER_SIZE);
if (scratch.readUnsignedInt() != STREAM_MARKER) { if (scratch.readUnsignedInt() != STREAM_MARKER) {
throw new ParserException("Failed to read FLAC stream marker."); throw ParserException.createForMalformedContainer(
"Failed to read FLAC stream marker.", /* cause= */ null);
} }
} }
@ -234,7 +235,8 @@ public final class FlacMetadataReader {
int syncCode = frameStartMarker >> 2; int syncCode = frameStartMarker >> 2;
if (syncCode != SYNC_CODE) { if (syncCode != SYNC_CODE) {
input.resetPeekPosition(); input.resetPeekPosition();
throw new ParserException("First frame does not start with sync code."); throw ParserException.createForMalformedContainer(
"First frame does not start with sync code.", /* cause= */ null);
} }
input.resetPeekPosition(); input.resetPeekPosition();

View File

@ -241,7 +241,8 @@ public final class VorbisUtil {
length += comments[i].length(); length += comments[i].length();
} }
if (hasFramingBit && (headerData.readUnsignedByte() & 0x01) == 0) { if (hasFramingBit && (headerData.readUnsignedByte() & 0x01) == 0) {
throw new ParserException("framing bit expected to be set"); throw ParserException.createForMalformedContainer(
"framing bit expected to be set", /* cause= */ null);
} }
length += 1; length += 1;
return new CommentHeader(vendor, comments, length); return new CommentHeader(vendor, comments, length);
@ -263,7 +264,8 @@ public final class VorbisUtil {
if (quiet) { if (quiet) {
return false; return false;
} else { } else {
throw new ParserException("too short header: " + header.bytesLeft()); throw ParserException.createForMalformedContainer(
"too short header: " + header.bytesLeft(), /* cause= */ null);
} }
} }
@ -271,7 +273,8 @@ public final class VorbisUtil {
if (quiet) { if (quiet) {
return false; return false;
} else { } else {
throw new ParserException("expected header type " + Integer.toHexString(headerType)); throw ParserException.createForMalformedContainer(
"expected header type " + Integer.toHexString(headerType), /* cause= */ null);
} }
} }
@ -284,7 +287,8 @@ public final class VorbisUtil {
if (quiet) { if (quiet) {
return false; return false;
} else { } else {
throw new ParserException("expected characters 'vorbis'"); throw ParserException.createForMalformedContainer(
"expected characters 'vorbis'", /* cause= */ null);
} }
} }
return true; return true;
@ -319,7 +323,8 @@ public final class VorbisUtil {
int timeCount = bitArray.readBits(6) + 1; int timeCount = bitArray.readBits(6) + 1;
for (int i = 0; i < timeCount; i++) { for (int i = 0; i < timeCount; i++) {
if (bitArray.readBits(16) != 0x00) { if (bitArray.readBits(16) != 0x00) {
throw new ParserException("placeholder of time domain transforms not zeroed out"); throw ParserException.createForMalformedContainer(
"placeholder of time domain transforms not zeroed out", /* cause= */ null);
} }
} }
readFloors(bitArray); readFloors(bitArray);
@ -328,7 +333,8 @@ public final class VorbisUtil {
Mode[] modes = readModes(bitArray); Mode[] modes = readModes(bitArray);
if (!bitArray.readBit()) { if (!bitArray.readBit()) {
throw new ParserException("framing bit after modes not set as expected"); throw ParserException.createForMalformedContainer(
"framing bit after modes not set as expected", /* cause= */ null);
} }
return modes; return modes;
} }
@ -371,7 +377,8 @@ public final class VorbisUtil {
couplingSteps = 0; couplingSteps = 0;
}*/ }*/
if (bitArray.readBits(2) != 0x00) { if (bitArray.readBits(2) != 0x00) {
throw new ParserException("to reserved bits must be zero after mapping coupling steps"); throw ParserException.createForMalformedContainer(
"to reserved bits must be zero after mapping coupling steps", /* cause= */ null);
} }
if (submaps > 1) { if (submaps > 1) {
for (int j = 0; j < channels; j++) { for (int j = 0; j < channels; j++) {
@ -391,7 +398,8 @@ public final class VorbisUtil {
for (int i = 0; i < residueCount; i++) { for (int i = 0; i < residueCount; i++) {
int residueType = bitArray.readBits(16); int residueType = bitArray.readBits(16);
if (residueType > 2) { if (residueType > 2) {
throw new ParserException("residueType greater than 2 is not decodable"); throw ParserException.createForMalformedContainer(
"residueType greater than 2 is not decodable", /* cause= */ null);
} else { } else {
bitArray.skipBits(24); // begin bitArray.skipBits(24); // begin
bitArray.skipBits(24); // end bitArray.skipBits(24); // end
@ -467,15 +475,17 @@ public final class VorbisUtil {
} }
break; break;
default: default:
throw new ParserException("floor type greater than 1 not decodable: " + floorType); throw ParserException.createForMalformedContainer(
"floor type greater than 1 not decodable: " + floorType, /* cause= */ null);
} }
} }
} }
private static CodeBook readBook(VorbisBitArray bitArray) throws ParserException { private static CodeBook readBook(VorbisBitArray bitArray) throws ParserException {
if (bitArray.readBits(24) != 0x564342) { if (bitArray.readBits(24) != 0x564342) {
throw new ParserException( throw ParserException.createForMalformedContainer(
"expected code book to start with [0x56, 0x43, 0x42] at " + bitArray.getPosition()); "expected code book to start with [0x56, 0x43, 0x42] at " + bitArray.getPosition(),
/* cause= */ null);
} }
int dimensions = bitArray.readBits(16); int dimensions = bitArray.readBits(16);
int entries = bitArray.readBits(24); int entries = bitArray.readBits(24);
@ -508,7 +518,8 @@ public final class VorbisUtil {
int lookupType = bitArray.readBits(4); int lookupType = bitArray.readBits(4);
if (lookupType > 2) { if (lookupType > 2) {
throw new ParserException("lookup type greater than 2 not decodable: " + lookupType); throw ParserException.createForMalformedContainer(
"lookup type greater than 2 not decodable: " + lookupType, /* cause= */ null);
} else if (lookupType == 1 || lookupType == 2) { } else if (lookupType == 1 || lookupType == 2) {
bitArray.skipBits(32); // minimumValue bitArray.skipBits(32); // minimumValue
bitArray.skipBits(32); // deltaValue bitArray.skipBits(32); // deltaValue

View File

@ -176,7 +176,8 @@ public final class AmrExtractor implements Extractor {
assertInitialized(); assertInitialized();
if (input.getPosition() == 0) { if (input.getPosition() == 0) {
if (!readAmrHeader(input)) { if (!readAmrHeader(input)) {
throw new ParserException("Could not find AMR header."); throw ParserException.createForMalformedContainer(
"Could not find AMR header.", /* cause= */ null);
} }
} }
maybeOutputFormat(); maybeOutputFormat();
@ -311,7 +312,8 @@ public final class AmrExtractor implements Extractor {
if ((frameHeader & 0x83) > 0) { if ((frameHeader & 0x83) > 0) {
// The padding bits are at bit-1 positions in the following pattern: 1000 0011 // The padding bits are at bit-1 positions in the following pattern: 1000 0011
// Padding bits must be 0. // Padding bits must be 0.
throw new ParserException("Invalid padding bits for frame header " + frameHeader); throw ParserException.createForMalformedContainer(
"Invalid padding bits for frame header " + frameHeader, /* cause= */ null);
} }
int frameType = (frameHeader >> 3) & 0x0f; int frameType = (frameHeader >> 3) & 0x0f;
@ -320,8 +322,9 @@ public final class AmrExtractor implements Extractor {
private int getFrameSizeInBytes(int frameType) throws ParserException { private int getFrameSizeInBytes(int frameType) throws ParserException {
if (!isValidFrameType(frameType)) { if (!isValidFrameType(frameType)) {
throw new ParserException( throw ParserException.createForMalformedContainer(
"Illegal AMR " + (isWideBand ? "WB" : "NB") + " frame type " + frameType); "Illegal AMR " + (isWideBand ? "WB" : "NB") + " frame type " + frameType,
/* cause= */ null);
} }
return isWideBand ? frameSizeBytesByTypeWb[frameType] : frameSizeBytesByTypeNb[frameType]; return isWideBand ? frameSizeBytesByTypeWb[frameType] : frameSizeBytesByTypeNb[frameType];

View File

@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.extractor.flv; package com.google.android.exoplayer2.extractor.flv;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ParserException; import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.extractor.TrackOutput; import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
@ -26,7 +27,7 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
public static final class UnsupportedFormatException extends ParserException { public static final class UnsupportedFormatException extends ParserException {
public UnsupportedFormatException(String msg) { public UnsupportedFormatException(String msg) {
super(msg); super(msg, /* cause= */ null, /* contentIsMalformed= */ false, C.DATA_TYPE_MEDIA);
} }
} }

View File

@ -85,7 +85,8 @@ import org.xmlpull.v1.XmlPullParserFactory;
xpp.setInput(new StringReader(xmpString)); xpp.setInput(new StringReader(xmpString));
xpp.next(); xpp.next();
if (!XmlPullParserUtil.isStartTag(xpp, "x:xmpmeta")) { if (!XmlPullParserUtil.isStartTag(xpp, "x:xmpmeta")) {
throw new ParserException("Couldn't find xmp metadata"); throw ParserException.createForMalformedContainer(
"Couldn't find xmp metadata", /* cause= */ null);
} }
long motionPhotoPresentationTimestampUs = C.TIME_UNSET; long motionPhotoPresentationTimestampUs = C.TIME_UNSET;
List<MotionPhotoDescription.ContainerItem> containerItems = ImmutableList.of(); List<MotionPhotoDescription.ContainerItem> containerItems = ImmutableList.of();

View File

@ -114,7 +114,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
return true; return true;
case EbmlProcessor.ELEMENT_TYPE_UNSIGNED_INT: case EbmlProcessor.ELEMENT_TYPE_UNSIGNED_INT:
if (elementContentSize > MAX_INTEGER_ELEMENT_SIZE_BYTES) { if (elementContentSize > MAX_INTEGER_ELEMENT_SIZE_BYTES) {
throw new ParserException("Invalid integer size: " + elementContentSize); throw ParserException.createForMalformedContainer(
"Invalid integer size: " + elementContentSize, /* cause= */ null);
} }
processor.integerElement(elementId, readInteger(input, (int) elementContentSize)); processor.integerElement(elementId, readInteger(input, (int) elementContentSize));
elementState = ELEMENT_STATE_READ_ID; elementState = ELEMENT_STATE_READ_ID;
@ -122,14 +123,16 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
case EbmlProcessor.ELEMENT_TYPE_FLOAT: case EbmlProcessor.ELEMENT_TYPE_FLOAT:
if (elementContentSize != VALID_FLOAT32_ELEMENT_SIZE_BYTES if (elementContentSize != VALID_FLOAT32_ELEMENT_SIZE_BYTES
&& elementContentSize != VALID_FLOAT64_ELEMENT_SIZE_BYTES) { && elementContentSize != VALID_FLOAT64_ELEMENT_SIZE_BYTES) {
throw new ParserException("Invalid float size: " + elementContentSize); throw ParserException.createForMalformedContainer(
"Invalid float size: " + elementContentSize, /* cause= */ null);
} }
processor.floatElement(elementId, readFloat(input, (int) elementContentSize)); processor.floatElement(elementId, readFloat(input, (int) elementContentSize));
elementState = ELEMENT_STATE_READ_ID; elementState = ELEMENT_STATE_READ_ID;
return true; return true;
case EbmlProcessor.ELEMENT_TYPE_STRING: case EbmlProcessor.ELEMENT_TYPE_STRING:
if (elementContentSize > Integer.MAX_VALUE) { if (elementContentSize > Integer.MAX_VALUE) {
throw new ParserException("String element size: " + elementContentSize); throw ParserException.createForMalformedContainer(
"String element size: " + elementContentSize, /* cause= */ null);
} }
processor.stringElement(elementId, readString(input, (int) elementContentSize)); processor.stringElement(elementId, readString(input, (int) elementContentSize));
elementState = ELEMENT_STATE_READ_ID; elementState = ELEMENT_STATE_READ_ID;
@ -143,7 +146,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
elementState = ELEMENT_STATE_READ_ID; elementState = ELEMENT_STATE_READ_ID;
break; break;
default: default:
throw new ParserException("Invalid element type " + type); throw ParserException.createForMalformedContainer(
"Invalid element type " + type, /* cause= */ null);
} }
} }
} }

View File

@ -626,7 +626,8 @@ public class MatroskaExtractor implements Extractor {
case ID_SEGMENT: case ID_SEGMENT:
if (segmentContentPosition != C.POSITION_UNSET if (segmentContentPosition != C.POSITION_UNSET
&& segmentContentPosition != contentPosition) { && segmentContentPosition != contentPosition) {
throw new ParserException("Multiple Segment elements not supported"); throw ParserException.createForMalformedContainer(
"Multiple Segment elements not supported", /* cause= */ null);
} }
segmentContentPosition = contentPosition; segmentContentPosition = contentPosition;
segmentContentSize = contentSize; segmentContentSize = contentSize;
@ -696,7 +697,8 @@ public class MatroskaExtractor implements Extractor {
break; break;
case ID_SEEK: case ID_SEEK:
if (seekEntryId == UNSET_ENTRY_ID || seekEntryPosition == C.POSITION_UNSET) { if (seekEntryId == UNSET_ENTRY_ID || seekEntryPosition == C.POSITION_UNSET) {
throw new ParserException("Mandatory element SeekID or SeekPosition not found"); throw ParserException.createForMalformedContainer(
"Mandatory element SeekID or SeekPosition not found", /* cause= */ null);
} }
if (seekEntryId == ID_CUES) { if (seekEntryId == ID_CUES) {
cuesContentPosition = seekEntryPosition; cuesContentPosition = seekEntryPosition;
@ -742,7 +744,8 @@ public class MatroskaExtractor implements Extractor {
assertInTrackEntry(id); assertInTrackEntry(id);
if (currentTrack.hasContentEncryption) { if (currentTrack.hasContentEncryption) {
if (currentTrack.cryptoData == null) { if (currentTrack.cryptoData == null) {
throw new ParserException("Encrypted Track found but ContentEncKeyID was not found"); throw ParserException.createForMalformedContainer(
"Encrypted Track found but ContentEncKeyID was not found", /* cause= */ null);
} }
currentTrack.drmInitData = currentTrack.drmInitData =
new DrmInitData( new DrmInitData(
@ -753,13 +756,15 @@ public class MatroskaExtractor implements Extractor {
case ID_CONTENT_ENCODINGS: case ID_CONTENT_ENCODINGS:
assertInTrackEntry(id); assertInTrackEntry(id);
if (currentTrack.hasContentEncryption && currentTrack.sampleStrippedBytes != null) { if (currentTrack.hasContentEncryption && currentTrack.sampleStrippedBytes != null) {
throw new ParserException("Combining encryption and compression is not supported"); throw ParserException.createForMalformedContainer(
"Combining encryption and compression is not supported", /* cause= */ null);
} }
break; break;
case ID_TRACK_ENTRY: case ID_TRACK_ENTRY:
Track currentTrack = checkStateNotNull(this.currentTrack); Track currentTrack = checkStateNotNull(this.currentTrack);
if (currentTrack.codecId == null) { if (currentTrack.codecId == null) {
throw new ParserException("CodecId is missing in TrackEntry element"); throw ParserException.createForMalformedContainer(
"CodecId is missing in TrackEntry element", /* cause= */ null);
} else { } else {
if (isCodecSupported(currentTrack.codecId)) { if (isCodecSupported(currentTrack.codecId)) {
currentTrack.initializeOutput(extractorOutput, currentTrack.number); currentTrack.initializeOutput(extractorOutput, currentTrack.number);
@ -770,7 +775,8 @@ public class MatroskaExtractor implements Extractor {
break; break;
case ID_TRACKS: case ID_TRACKS:
if (tracks.size() == 0) { if (tracks.size() == 0) {
throw new ParserException("No valid tracks were found"); throw ParserException.createForMalformedContainer(
"No valid tracks were found", /* cause= */ null);
} }
extractorOutput.endTracks(); extractorOutput.endTracks();
break; break;
@ -790,13 +796,15 @@ public class MatroskaExtractor implements Extractor {
case ID_EBML_READ_VERSION: case ID_EBML_READ_VERSION:
// Validate that EBMLReadVersion is supported. This extractor only supports v1. // Validate that EBMLReadVersion is supported. This extractor only supports v1.
if (value != 1) { if (value != 1) {
throw new ParserException("EBMLReadVersion " + value + " not supported"); throw ParserException.createForMalformedContainer(
"EBMLReadVersion " + value + " not supported", /* cause= */ null);
} }
break; break;
case ID_DOC_TYPE_READ_VERSION: case ID_DOC_TYPE_READ_VERSION:
// Validate that DocTypeReadVersion is supported. This extractor only supports up to v2. // Validate that DocTypeReadVersion is supported. This extractor only supports up to v2.
if (value < 1 || value > 2) { if (value < 1 || value > 2) {
throw new ParserException("DocTypeReadVersion " + value + " not supported"); throw ParserException.createForMalformedContainer(
"DocTypeReadVersion " + value + " not supported", /* cause= */ null);
} }
break; break;
case ID_SEEK_POSITION: case ID_SEEK_POSITION:
@ -861,31 +869,36 @@ public class MatroskaExtractor implements Extractor {
case ID_CONTENT_ENCODING_ORDER: case ID_CONTENT_ENCODING_ORDER:
// This extractor only supports one ContentEncoding element and hence the order has to be 0. // This extractor only supports one ContentEncoding element and hence the order has to be 0.
if (value != 0) { if (value != 0) {
throw new ParserException("ContentEncodingOrder " + value + " not supported"); throw ParserException.createForMalformedContainer(
"ContentEncodingOrder " + value + " not supported", /* cause= */ null);
} }
break; break;
case ID_CONTENT_ENCODING_SCOPE: case ID_CONTENT_ENCODING_SCOPE:
// This extractor only supports the scope of all frames. // This extractor only supports the scope of all frames.
if (value != 1) { if (value != 1) {
throw new ParserException("ContentEncodingScope " + value + " not supported"); throw ParserException.createForMalformedContainer(
"ContentEncodingScope " + value + " not supported", /* cause= */ null);
} }
break; break;
case ID_CONTENT_COMPRESSION_ALGORITHM: case ID_CONTENT_COMPRESSION_ALGORITHM:
// This extractor only supports header stripping. // This extractor only supports header stripping.
if (value != 3) { if (value != 3) {
throw new ParserException("ContentCompAlgo " + value + " not supported"); throw ParserException.createForMalformedContainer(
"ContentCompAlgo " + value + " not supported", /* cause= */ null);
} }
break; break;
case ID_CONTENT_ENCRYPTION_ALGORITHM: case ID_CONTENT_ENCRYPTION_ALGORITHM:
// Only the value 5 (AES) is allowed according to the WebM specification. // Only the value 5 (AES) is allowed according to the WebM specification.
if (value != 5) { if (value != 5) {
throw new ParserException("ContentEncAlgo " + value + " not supported"); throw ParserException.createForMalformedContainer(
"ContentEncAlgo " + value + " not supported", /* cause= */ null);
} }
break; break;
case ID_CONTENT_ENCRYPTION_AES_SETTINGS_CIPHER_MODE: case ID_CONTENT_ENCRYPTION_AES_SETTINGS_CIPHER_MODE:
// Only the value 1 is allowed according to the WebM specification. // Only the value 1 is allowed according to the WebM specification.
if (value != 1) { if (value != 1) {
throw new ParserException("AESSettingsCipherMode " + value + " not supported"); throw ParserException.createForMalformedContainer(
"AESSettingsCipherMode " + value + " not supported", /* cause= */ null);
} }
break; break;
case ID_CUE_TIME: case ID_CUE_TIME:
@ -1058,7 +1071,8 @@ public class MatroskaExtractor implements Extractor {
case ID_DOC_TYPE: case ID_DOC_TYPE:
// Validate that DocType is supported. // Validate that DocType is supported.
if (!DOC_TYPE_WEBM.equals(value) && !DOC_TYPE_MATROSKA.equals(value)) { if (!DOC_TYPE_WEBM.equals(value) && !DOC_TYPE_MATROSKA.equals(value)) {
throw new ParserException("DocType " + value + " not supported"); throw ParserException.createForMalformedContainer(
"DocType " + value + " not supported", /* cause= */ null);
} }
break; break;
case ID_NAME: case ID_NAME:
@ -1180,7 +1194,8 @@ public class MatroskaExtractor implements Extractor {
blockSampleSizes[sampleIndex] = 0; blockSampleSizes[sampleIndex] = 0;
readScratch(input, ++headerSize); readScratch(input, ++headerSize);
if (scratch.getData()[headerSize - 1] == 0) { if (scratch.getData()[headerSize - 1] == 0) {
throw new ParserException("No valid varint length mask found"); throw ParserException.createForMalformedContainer(
"No valid varint length mask found", /* cause= */ null);
} }
long readValue = 0; long readValue = 0;
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
@ -1202,7 +1217,8 @@ public class MatroskaExtractor implements Extractor {
} }
} }
if (readValue < Integer.MIN_VALUE || readValue > Integer.MAX_VALUE) { if (readValue < Integer.MIN_VALUE || readValue > Integer.MAX_VALUE) {
throw new ParserException("EBML lacing sample size out of range."); throw ParserException.createForMalformedContainer(
"EBML lacing sample size out of range.", /* cause= */ null);
} }
int intReadValue = (int) readValue; int intReadValue = (int) readValue;
blockSampleSizes[sampleIndex] = blockSampleSizes[sampleIndex] =
@ -1215,7 +1231,8 @@ public class MatroskaExtractor implements Extractor {
contentSize - blockTrackNumberLength - headerSize - totalSamplesSize; contentSize - blockTrackNumberLength - headerSize - totalSamplesSize;
} else { } else {
// Lacing is always in the range 0--3. // Lacing is always in the range 0--3.
throw new ParserException("Unexpected lacing value: " + lacing); throw ParserException.createForMalformedContainer(
"Unexpected lacing value: " + lacing, /* cause= */ null);
} }
} }
@ -1262,7 +1279,8 @@ public class MatroskaExtractor implements Extractor {
tracks.get(blockTrackNumber), blockAdditionalId, input, contentSize); tracks.get(blockTrackNumber), blockAdditionalId, input, contentSize);
break; break;
default: default:
throw new ParserException("Unexpected id: " + id); throw ParserException.createForMalformedContainer(
"Unexpected id: " + id, /* cause= */ null);
} }
} }
@ -1294,14 +1312,16 @@ public class MatroskaExtractor implements Extractor {
@EnsuresNonNull("currentTrack") @EnsuresNonNull("currentTrack")
private void assertInTrackEntry(int id) throws ParserException { private void assertInTrackEntry(int id) throws ParserException {
if (currentTrack == null) { if (currentTrack == null) {
throw new ParserException("Element " + id + " must be in a TrackEntry"); throw ParserException.createForMalformedContainer(
"Element " + id + " must be in a TrackEntry", /* cause= */ null);
} }
} }
@EnsuresNonNull({"cueTimesUs", "cueClusterPositions"}) @EnsuresNonNull({"cueTimesUs", "cueClusterPositions"})
private void assertInCues(int id) throws ParserException { private void assertInCues(int id) throws ParserException {
if (cueTimesUs == null || cueClusterPositions == null) { if (cueTimesUs == null || cueClusterPositions == null) {
throw new ParserException("Element " + id + " must be in a Cues"); throw ParserException.createForMalformedContainer(
"Element " + id + " must be in a Cues", /* cause= */ null);
} }
} }
@ -1401,7 +1421,8 @@ public class MatroskaExtractor implements Extractor {
input.readFully(scratch.getData(), 0, 1); input.readFully(scratch.getData(), 0, 1);
sampleBytesRead++; sampleBytesRead++;
if ((scratch.getData()[0] & 0x80) == 0x80) { if ((scratch.getData()[0] & 0x80) == 0x80) {
throw new ParserException("Extension bit is set in signal byte"); throw ParserException.createForMalformedContainer(
"Extension bit is set in signal byte", /* cause= */ null);
} }
sampleSignalByte = scratch.getData()[0]; sampleSignalByte = scratch.getData()[0];
sampleSignalByteRead = true; sampleSignalByteRead = true;
@ -1766,7 +1787,8 @@ public class MatroskaExtractor implements Extractor {
private long scaleTimecodeToUs(long unscaledTimecode) throws ParserException { private long scaleTimecodeToUs(long unscaledTimecode) throws ParserException {
if (timecodeScale == C.TIME_UNSET) { if (timecodeScale == C.TIME_UNSET) {
throw new ParserException("Can't scale timecode prior to timecodeScale being set."); throw ParserException.createForMalformedContainer(
"Can't scale timecode prior to timecodeScale being set.", /* cause= */ null);
} }
return Util.scaleLargeTimestamp(unscaledTimecode, timecodeScale, 1000); return Util.scaleLargeTimestamp(unscaledTimecode, timecodeScale, 1000);
} }
@ -2207,7 +2229,8 @@ public class MatroskaExtractor implements Extractor {
initializationData = ImmutableList.of(initializationDataBytes); initializationData = ImmutableList.of(initializationDataBytes);
break; break;
default: default:
throw new ParserException("Unrecognized codec identifier."); throw ParserException.createForMalformedContainer(
"Unrecognized codec identifier.", /* cause= */ null);
} }
if (dolbyVisionConfigBytes != null) { if (dolbyVisionConfigBytes != null) {
@ -2284,7 +2307,8 @@ public class MatroskaExtractor implements Extractor {
|| MimeTypes.APPLICATION_DVBSUBS.equals(mimeType)) { || MimeTypes.APPLICATION_DVBSUBS.equals(mimeType)) {
type = C.TRACK_TYPE_TEXT; type = C.TRACK_TYPE_TEXT;
} else { } else {
throw new ParserException("Unexpected MIME type."); throw ParserException.createForMalformedContainer(
"Unexpected MIME type.", /* cause= */ null);
} }
if (name != null && !TRACK_NAME_TO_ROTATION_DEGREES.containsKey(name)) { if (name != null && !TRACK_NAME_TO_ROTATION_DEGREES.containsKey(name)) {
@ -2389,10 +2413,12 @@ public class MatroskaExtractor implements Extractor {
return new Pair<>(MimeTypes.VIDEO_VC1, Collections.singletonList(initializationData)); return new Pair<>(MimeTypes.VIDEO_VC1, Collections.singletonList(initializationData));
} }
} }
throw new ParserException("Failed to find FourCC VC1 initialization data"); throw ParserException.createForMalformedContainer(
"Failed to find FourCC VC1 initialization data", /* cause= */ null);
} }
} catch (ArrayIndexOutOfBoundsException e) { } catch (ArrayIndexOutOfBoundsException e) {
throw new ParserException("Error parsing FourCC private data"); throw ParserException.createForMalformedContainer(
"Error parsing FourCC private data", /* cause= */ null);
} }
Log.w(TAG, "Unknown FourCC. Setting mimeType to " + MimeTypes.VIDEO_UNKNOWN); Log.w(TAG, "Unknown FourCC. Setting mimeType to " + MimeTypes.VIDEO_UNKNOWN);
@ -2409,7 +2435,8 @@ public class MatroskaExtractor implements Extractor {
throws ParserException { throws ParserException {
try { try {
if (codecPrivate[0] != 0x02) { if (codecPrivate[0] != 0x02) {
throw new ParserException("Error parsing vorbis codec private"); throw ParserException.createForMalformedContainer(
"Error parsing vorbis codec private", /* cause= */ null);
} }
int offset = 1; int offset = 1;
int vorbisInfoLength = 0; int vorbisInfoLength = 0;
@ -2427,17 +2454,20 @@ public class MatroskaExtractor implements Extractor {
vorbisSkipLength += codecPrivate[offset++] & 0xFF; vorbisSkipLength += codecPrivate[offset++] & 0xFF;
if (codecPrivate[offset] != 0x01) { if (codecPrivate[offset] != 0x01) {
throw new ParserException("Error parsing vorbis codec private"); throw ParserException.createForMalformedContainer(
"Error parsing vorbis codec private", /* cause= */ null);
} }
byte[] vorbisInfo = new byte[vorbisInfoLength]; byte[] vorbisInfo = new byte[vorbisInfoLength];
System.arraycopy(codecPrivate, offset, vorbisInfo, 0, vorbisInfoLength); System.arraycopy(codecPrivate, offset, vorbisInfo, 0, vorbisInfoLength);
offset += vorbisInfoLength; offset += vorbisInfoLength;
if (codecPrivate[offset] != 0x03) { if (codecPrivate[offset] != 0x03) {
throw new ParserException("Error parsing vorbis codec private"); throw ParserException.createForMalformedContainer(
"Error parsing vorbis codec private", /* cause= */ null);
} }
offset += vorbisSkipLength; offset += vorbisSkipLength;
if (codecPrivate[offset] != 0x05) { if (codecPrivate[offset] != 0x05) {
throw new ParserException("Error parsing vorbis codec private"); throw ParserException.createForMalformedContainer(
"Error parsing vorbis codec private", /* cause= */ null);
} }
byte[] vorbisBooks = new byte[codecPrivate.length - offset]; byte[] vorbisBooks = new byte[codecPrivate.length - offset];
System.arraycopy(codecPrivate, offset, vorbisBooks, 0, codecPrivate.length - offset); System.arraycopy(codecPrivate, offset, vorbisBooks, 0, codecPrivate.length - offset);
@ -2446,7 +2476,8 @@ public class MatroskaExtractor implements Extractor {
initializationData.add(vorbisBooks); initializationData.add(vorbisBooks);
return initializationData; return initializationData;
} catch (ArrayIndexOutOfBoundsException e) { } catch (ArrayIndexOutOfBoundsException e) {
throw new ParserException("Error parsing vorbis codec private"); throw ParserException.createForMalformedContainer(
"Error parsing vorbis codec private", /* cause= */ null);
} }
} }
@ -2469,7 +2500,8 @@ public class MatroskaExtractor implements Extractor {
return false; return false;
} }
} catch (ArrayIndexOutOfBoundsException e) { } catch (ArrayIndexOutOfBoundsException e) {
throw new ParserException("Error parsing MS/ACM codec private"); throw ParserException.createForMalformedContainer(
"Error parsing MS/ACM codec private", /* cause= */ null);
} }
} }
@ -2488,7 +2520,8 @@ public class MatroskaExtractor implements Extractor {
@EnsuresNonNull("codecPrivate") @EnsuresNonNull("codecPrivate")
private byte[] getCodecPrivate(String codecId) throws ParserException { private byte[] getCodecPrivate(String codecId) throws ParserException {
if (codecPrivate == null) { if (codecPrivate == null) {
throw new ParserException("Missing CodecPrivate for codec " + codecId); throw ParserException.createForMalformedContainer(
"Missing CodecPrivate for codec " + codecId, /* cause= */ null);
} }
return codecPrivate; return codecPrivate;
} }

View File

@ -357,7 +357,8 @@ public final class Mp3Extractor implements Extractor {
// The header doesn't match the candidate header or is invalid. Try the next byte offset. // The header doesn't match the candidate header or is invalid. Try the next byte offset.
if (searchedBytes++ == searchLimitBytes) { if (searchedBytes++ == searchLimitBytes) {
if (!sniffing) { if (!sniffing) {
throw new ParserException("Searched too many bytes."); throw ParserException.createForMalformedContainer(
"Searched too many bytes.", /* cause= */ null);
} }
return false; return false;
} }

View File

@ -379,7 +379,8 @@ public class FragmentedMp4Extractor implements Extractor {
} }
if (atomSize < atomHeaderBytesRead) { if (atomSize < atomHeaderBytesRead) {
throw new ParserException("Atom size less than header length (unsupported)."); throw ParserException.createForUnsupportedContainerFeature(
"Atom size less than header length (unsupported).");
} }
long atomPosition = input.getPosition() - atomHeaderBytesRead; long atomPosition = input.getPosition() - atomHeaderBytesRead;
@ -420,10 +421,12 @@ public class FragmentedMp4Extractor implements Extractor {
} }
} else if (shouldParseLeafAtom(atomType)) { } else if (shouldParseLeafAtom(atomType)) {
if (atomHeaderBytesRead != Atom.HEADER_SIZE) { if (atomHeaderBytesRead != Atom.HEADER_SIZE) {
throw new ParserException("Leaf atom defines extended atom size (unsupported)."); throw ParserException.createForUnsupportedContainerFeature(
"Leaf atom defines extended atom size (unsupported).");
} }
if (atomSize > Integer.MAX_VALUE) { if (atomSize > Integer.MAX_VALUE) {
throw new ParserException("Leaf atom with length > 2147483647 (unsupported)."); throw ParserException.createForUnsupportedContainerFeature(
"Leaf atom with length > 2147483647 (unsupported).");
} }
ParsableByteArray atomData = new ParsableByteArray((int) atomSize); ParsableByteArray atomData = new ParsableByteArray((int) atomSize);
System.arraycopy(atomHeader.getData(), 0, atomData.getData(), 0, Atom.HEADER_SIZE); System.arraycopy(atomHeader.getData(), 0, atomData.getData(), 0, Atom.HEADER_SIZE);
@ -431,7 +434,8 @@ public class FragmentedMp4Extractor implements Extractor {
parserState = STATE_READING_ATOM_PAYLOAD; parserState = STATE_READING_ATOM_PAYLOAD;
} else { } else {
if (atomSize > Integer.MAX_VALUE) { if (atomSize > Integer.MAX_VALUE) {
throw new ParserException("Skipping atom with length > 2147483647 (unsupported)."); throw ParserException.createForUnsupportedContainerFeature(
"Skipping atom with length > 2147483647 (unsupported).");
} }
atomData = null; atomData = null;
parserState = STATE_READING_ATOM_PAYLOAD; parserState = STATE_READING_ATOM_PAYLOAD;
@ -827,11 +831,12 @@ public class FragmentedMp4Extractor implements Extractor {
int sampleCount = saiz.readUnsignedIntToInt(); int sampleCount = saiz.readUnsignedIntToInt();
if (sampleCount > out.sampleCount) { if (sampleCount > out.sampleCount) {
throw new ParserException( throw ParserException.createForMalformedContainer(
"Saiz sample count " "Saiz sample count "
+ sampleCount + sampleCount
+ " is greater than fragment sample count" + " is greater than fragment sample count"
+ out.sampleCount); + out.sampleCount,
/* cause= */ null);
} }
int totalSize = 0; int totalSize = 0;
@ -870,7 +875,8 @@ public class FragmentedMp4Extractor implements Extractor {
int entryCount = saio.readUnsignedIntToInt(); int entryCount = saio.readUnsignedIntToInt();
if (entryCount != 1) { if (entryCount != 1) {
// We only support one trun element currently, so always expect one entry. // We only support one trun element currently, so always expect one entry.
throw new ParserException("Unexpected saio entry count: " + entryCount); throw ParserException.createForMalformedContainer(
"Unexpected saio entry count: " + entryCount, /* cause= */ null);
} }
int version = Atom.parseFullAtomVersion(fullAtom); int version = Atom.parseFullAtomVersion(fullAtom);
@ -1055,7 +1061,8 @@ public class FragmentedMp4Extractor implements Extractor {
private static int checkNonNegative(int value) throws ParserException { private static int checkNonNegative(int value) throws ParserException {
if (value < 0) { if (value < 0) {
throw new ParserException("Unexpected negative value: " + value); throw ParserException.createForMalformedContainer(
"Unexpected negative value: " + value, /* cause= */ null);
} }
return value; return value;
} }
@ -1089,7 +1096,8 @@ public class FragmentedMp4Extractor implements Extractor {
if ((flags & 0x01 /* override_track_encryption_box_parameters */) != 0) { if ((flags & 0x01 /* override_track_encryption_box_parameters */) != 0) {
// TODO: Implement this. // TODO: Implement this.
throw new ParserException("Overriding TrackEncryptionBox parameters is unsupported."); throw ParserException.createForUnsupportedContainerFeature(
"Overriding TrackEncryptionBox parameters is unsupported.");
} }
boolean subsampleEncryption = (flags & 0x02 /* use_subsample_encryption */) != 0; boolean subsampleEncryption = (flags & 0x02 /* use_subsample_encryption */) != 0;
@ -1099,11 +1107,12 @@ public class FragmentedMp4Extractor implements Extractor {
Arrays.fill(out.sampleHasSubsampleEncryptionTable, 0, out.sampleCount, false); Arrays.fill(out.sampleHasSubsampleEncryptionTable, 0, out.sampleCount, false);
return; return;
} else if (sampleCount != out.sampleCount) { } else if (sampleCount != out.sampleCount) {
throw new ParserException( throw ParserException.createForMalformedContainer(
"Senc sample count " "Senc sample count "
+ sampleCount + sampleCount
+ " is different from fragment sample count" + " is different from fragment sample count"
+ out.sampleCount); + out.sampleCount,
/* cause= */ null);
} }
Arrays.fill(out.sampleHasSubsampleEncryptionTable, 0, sampleCount, subsampleEncryption); Arrays.fill(out.sampleHasSubsampleEncryptionTable, 0, sampleCount, subsampleEncryption);
@ -1142,7 +1151,8 @@ public class FragmentedMp4Extractor implements Extractor {
sbgp.skipBytes(4); // grouping_type_parameter. sbgp.skipBytes(4); // grouping_type_parameter.
} }
if (sbgp.readInt() != 1) { // entry_count. if (sbgp.readInt() != 1) { // entry_count.
throw new ParserException("Entry count in sbgp != 1 (unsupported)."); throw ParserException.createForUnsupportedContainerFeature(
"Entry count in sbgp != 1 (unsupported).");
} }
sgpd.setPosition(Atom.HEADER_SIZE); sgpd.setPosition(Atom.HEADER_SIZE);
@ -1150,13 +1160,15 @@ public class FragmentedMp4Extractor implements Extractor {
sgpd.skipBytes(4); // grouping_type == seig. sgpd.skipBytes(4); // grouping_type == seig.
if (sgpdVersion == 1) { if (sgpdVersion == 1) {
if (sgpd.readUnsignedInt() == 0) { if (sgpd.readUnsignedInt() == 0) {
throw new ParserException("Variable length description in sgpd found (unsupported)"); throw ParserException.createForUnsupportedContainerFeature(
"Variable length description in sgpd found (unsupported)");
} }
} else if (sgpdVersion >= 2) { } else if (sgpdVersion >= 2) {
sgpd.skipBytes(4); // default_sample_description_index. sgpd.skipBytes(4); // default_sample_description_index.
} }
if (sgpd.readUnsignedInt() != 1) { // entry_count. if (sgpd.readUnsignedInt() != 1) { // entry_count.
throw new ParserException("Entry count in sgpd != 1 (unsupported)."); throw ParserException.createForUnsupportedContainerFeature(
"Entry count in sgpd != 1 (unsupported).");
} }
// CencSampleEncryptionInformationGroupEntry // CencSampleEncryptionInformationGroupEntry
@ -1232,7 +1244,8 @@ public class FragmentedMp4Extractor implements Extractor {
int type = 0x80000000 & firstInt; int type = 0x80000000 & firstInt;
if (type != 0) { if (type != 0) {
throw new ParserException("Unhandled indirect reference"); throw ParserException.createForMalformedContainer(
"Unhandled indirect reference", /* cause= */ null);
} }
long referenceDuration = atom.readUnsignedInt(); long referenceDuration = atom.readUnsignedInt();
@ -1272,7 +1285,8 @@ public class FragmentedMp4Extractor implements Extractor {
} }
int bytesToSkip = (int) (nextDataOffset - input.getPosition()); int bytesToSkip = (int) (nextDataOffset - input.getPosition());
if (bytesToSkip < 0) { if (bytesToSkip < 0) {
throw new ParserException("Offset to encryption data was negative."); throw ParserException.createForMalformedContainer(
"Offset to encryption data was negative.", /* cause= */ null);
} }
input.skipFully(bytesToSkip); input.skipFully(bytesToSkip);
nextTrackBundle.fragment.fillEncryptionData(input); nextTrackBundle.fragment.fillEncryptionData(input);
@ -1302,7 +1316,8 @@ public class FragmentedMp4Extractor implements Extractor {
// read the header of the next atom. // read the header of the next atom.
int bytesToSkip = (int) (endOfMdatPosition - input.getPosition()); int bytesToSkip = (int) (endOfMdatPosition - input.getPosition());
if (bytesToSkip < 0) { if (bytesToSkip < 0) {
throw new ParserException("Offset to end of mdat was negative."); throw ParserException.createForMalformedContainer(
"Offset to end of mdat was negative.", /* cause= */ null);
} }
input.skipFully(bytesToSkip); input.skipFully(bytesToSkip);
enterReadingAtomHeaderState(); enterReadingAtomHeaderState();
@ -1380,7 +1395,8 @@ public class FragmentedMp4Extractor implements Extractor {
nalPrefix.setPosition(0); nalPrefix.setPosition(0);
int nalLengthInt = nalPrefix.readInt(); int nalLengthInt = nalPrefix.readInt();
if (nalLengthInt < 1) { if (nalLengthInt < 1) {
throw new ParserException("Invalid NAL length"); throw ParserException.createForMalformedContainer(
"Invalid NAL length", /* cause= */ null);
} }
sampleCurrentNalBytesRemaining = nalLengthInt - 1; sampleCurrentNalBytesRemaining = nalLengthInt - 1;
// Write a start code for the current NAL unit. // Write a start code for the current NAL unit.

View File

@ -360,7 +360,8 @@ public final class Mp4Extractor implements Extractor, SeekMap {
} }
if (atomSize < atomHeaderBytesRead) { if (atomSize < atomHeaderBytesRead) {
throw new ParserException("Atom size less than header length (unsupported)."); throw ParserException.createForUnsupportedContainerFeature(
"Atom size less than header length (unsupported).");
} }
if (shouldParseContainerAtom(atomType)) { if (shouldParseContainerAtom(atomType)) {
@ -598,7 +599,8 @@ public final class Mp4Extractor implements Extractor, SeekMap {
nalLength.setPosition(0); nalLength.setPosition(0);
int nalLengthInt = nalLength.readInt(); int nalLengthInt = nalLength.readInt();
if (nalLengthInt < 0) { if (nalLengthInt < 0) {
throw new ParserException("Invalid NAL length"); throw ParserException.createForMalformedContainer(
"Invalid NAL length", /* cause= */ null);
} }
sampleCurrentNalBytesRemaining = nalLengthInt; sampleCurrentNalBytesRemaining = nalLengthInt;
// Write a start code for the current NAL unit. // Write a start code for the current NAL unit.

View File

@ -260,7 +260,7 @@ import java.util.List;
case "Super_SlowMotion_Deflickering_On": case "Super_SlowMotion_Deflickering_On":
return TYPE_SUPER_SLOW_DEFLICKERING_ON; return TYPE_SUPER_SLOW_DEFLICKERING_ON;
default: default:
throw new ParserException("Invalid SEF name"); throw ParserException.createForMalformedContainer("Invalid SEF name", /* cause= */ null);
} }
} }

View File

@ -74,7 +74,8 @@ public class OggExtractor implements Extractor {
checkStateNotNull(output); // Check that init has been called. checkStateNotNull(output); // Check that init has been called.
if (streamReader == null) { if (streamReader == null) {
if (!sniffInternal(input)) { if (!sniffInternal(input)) {
throw new ParserException("Failed to determine bitstream type"); throw ParserException.createForMalformedContainer(
"Failed to determine bitstream type", /* cause= */ null);
} }
input.resetPeekPosition(); input.resetPeekPosition();
} }

View File

@ -140,7 +140,8 @@ import java.io.IOException;
if (quiet) { if (quiet) {
return false; return false;
} else { } else {
throw new ParserException("unsupported bit stream revision"); throw ParserException.createForUnsupportedContainerFeature(
"unsupported bit stream revision");
} }
} }
type = scratch.readUnsignedByte(); type = scratch.readUnsignedByte();

View File

@ -144,7 +144,8 @@ public final class RawCcExtractor implements Extractor {
} }
timestampUs = dataScratch.readLong(); timestampUs = dataScratch.readLong();
} else { } else {
throw new ParserException("Unsupported version number: " + version); throw ParserException.createForMalformedContainer(
"Unsupported version number: " + version, /* cause= */ null);
} }
remainingSampleCount = dataScratch.readUnsignedByte(); remainingSampleCount = dataScratch.readUnsignedByte();

View File

@ -287,7 +287,8 @@ public final class AdtsExtractor implements Extractor {
// Either the stream is malformed OR we're not parsing an ADTS stream. // Either the stream is malformed OR we're not parsing an ADTS stream.
if (currentFrameSize <= 6) { if (currentFrameSize <= 6) {
hasCalculatedAverageFrameSize = true; hasCalculatedAverageFrameSize = true;
throw new ParserException("Malformed ADTS stream"); throw ParserException.createForMalformedContainer(
"Malformed ADTS stream", /* cause= */ null);
} }
totalValidFramesSize += currentFrameSize; totalValidFramesSize += currentFrameSize;
if (++numValidFrames == NUM_FRAMES_FOR_AVERAGE_FRAME_SIZE) { if (++numValidFrames == NUM_FRAMES_FOR_AVERAGE_FRAME_SIZE) {

View File

@ -443,7 +443,8 @@ public final class TsExtractor implements Extractor {
if (endOfPacket > limit) { if (endOfPacket > limit) {
bytesSinceLastSync += syncBytePosition - searchStart; bytesSinceLastSync += syncBytePosition - searchStart;
if (mode == MODE_HLS && bytesSinceLastSync > TS_PACKET_SIZE * 2) { if (mode == MODE_HLS && bytesSinceLastSync > TS_PACKET_SIZE * 2) {
throw new ParserException("Cannot find sync byte. Most likely not a Transport Stream."); throw ParserException.createForMalformedContainer(
"Cannot find sync byte. Most likely not a Transport Stream.", /* cause= */ null);
} }
} else { } else {
// We have found a packet within the buffer. // We have found a packet within the buffer.

View File

@ -92,7 +92,8 @@ public final class WavExtractor implements Extractor {
WavHeader header = WavHeaderReader.peek(input); WavHeader header = WavHeaderReader.peek(input);
if (header == null) { if (header == null) {
// Should only happen if the media wasn't sniffed. // Should only happen if the media wasn't sniffed.
throw new ParserException("Unsupported or unrecognized wav header."); throw ParserException.createForMalformedContainer(
"Unsupported or unrecognized wav header.", /* cause= */ null);
} }
if (header.formatType == WavUtil.TYPE_IMA_ADPCM) { if (header.formatType == WavUtil.TYPE_IMA_ADPCM) {
@ -117,7 +118,8 @@ public final class WavExtractor implements Extractor {
@C.PcmEncoding @C.PcmEncoding
int pcmEncoding = WavUtil.getPcmEncodingForType(header.formatType, header.bitsPerSample); int pcmEncoding = WavUtil.getPcmEncodingForType(header.formatType, header.bitsPerSample);
if (pcmEncoding == C.ENCODING_INVALID) { if (pcmEncoding == C.ENCODING_INVALID) {
throw new ParserException("Unsupported WAV format type: " + header.formatType); throw ParserException.createForUnsupportedContainerFeature(
"Unsupported WAV format type: " + header.formatType);
} }
outputWriter = outputWriter =
new PassthroughOutputWriter( new PassthroughOutputWriter(
@ -217,8 +219,9 @@ public final class WavExtractor implements Extractor {
int bytesPerFrame = header.numChannels * header.bitsPerSample / 8; int bytesPerFrame = header.numChannels * header.bitsPerSample / 8;
// Validate the header. Blocks are expected to correspond to single frames. // Validate the header. Blocks are expected to correspond to single frames.
if (header.blockSize != bytesPerFrame) { if (header.blockSize != bytesPerFrame) {
throw new ParserException( throw ParserException.createForMalformedContainer(
"Expected block size: " + bytesPerFrame + "; got: " + header.blockSize); "Expected block size: " + bytesPerFrame + "; got: " + header.blockSize,
/* cause= */ null);
} }
int constantBitrate = header.frameRateHz * bytesPerFrame * 8; int constantBitrate = header.frameRateHz * bytesPerFrame * 8;
@ -351,8 +354,9 @@ public final class WavExtractor implements Extractor {
int expectedFramesPerBlock = int expectedFramesPerBlock =
(((header.blockSize - (4 * numChannels)) * 8) / (header.bitsPerSample * numChannels)) + 1; (((header.blockSize - (4 * numChannels)) * 8) / (header.bitsPerSample * numChannels)) + 1;
if (framesPerBlock != expectedFramesPerBlock) { if (framesPerBlock != expectedFramesPerBlock) {
throw new ParserException( throw ParserException.createForMalformedContainer(
"Expected frames per block: " + expectedFramesPerBlock + "; got: " + framesPerBlock); "Expected frames per block: " + expectedFramesPerBlock + "; got: " + framesPerBlock,
/* cause= */ null);
} }
// Calculate the number of blocks we'll need to decode to obtain an output sample of the // Calculate the number of blocks we'll need to decode to obtain an output sample of the

View File

@ -127,7 +127,8 @@ import java.io.IOException;
bytesToSkip = ChunkHeader.SIZE_IN_BYTES + 4; bytesToSkip = ChunkHeader.SIZE_IN_BYTES + 4;
} }
if (bytesToSkip > Integer.MAX_VALUE) { if (bytesToSkip > Integer.MAX_VALUE) {
throw new ParserException("Chunk is too large (~2GB+) to skip; id: " + chunkHeader.id); throw ParserException.createForUnsupportedContainerFeature(
"Chunk is too large (~2GB+) to skip; id: " + chunkHeader.id);
} }
input.skipFully((int) bytesToSkip); input.skipFully((int) bytesToSkip);
chunkHeader = ChunkHeader.peek(input, scratch); chunkHeader = ChunkHeader.peek(input, scratch);

View File

@ -278,7 +278,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
public void maybeThrowPrepareError() throws IOException { public void maybeThrowPrepareError() throws IOException {
maybeThrowError(); maybeThrowError();
if (loadingFinished && !prepared) { if (loadingFinished && !prepared) {
throw new ParserException("Loading finished before preparation is complete."); throw ParserException.createForMalformedContainer(
"Loading finished before preparation is complete.", /* cause= */ null);
} }
} }

View File

@ -153,11 +153,13 @@ public final class WebvttExtractor implements Extractor {
if (line.startsWith("X-TIMESTAMP-MAP")) { if (line.startsWith("X-TIMESTAMP-MAP")) {
Matcher localTimestampMatcher = LOCAL_TIMESTAMP.matcher(line); Matcher localTimestampMatcher = LOCAL_TIMESTAMP.matcher(line);
if (!localTimestampMatcher.find()) { if (!localTimestampMatcher.find()) {
throw new ParserException("X-TIMESTAMP-MAP doesn't contain local timestamp: " + line); throw ParserException.createForMalformedContainer(
"X-TIMESTAMP-MAP doesn't contain local timestamp: " + line, /* cause= */ null);
} }
Matcher mediaTimestampMatcher = MEDIA_TIMESTAMP.matcher(line); Matcher mediaTimestampMatcher = MEDIA_TIMESTAMP.matcher(line);
if (!mediaTimestampMatcher.find()) { if (!mediaTimestampMatcher.find()) {
throw new ParserException("X-TIMESTAMP-MAP doesn't contain media timestamp: " + line); throw ParserException.createForMalformedContainer(
"X-TIMESTAMP-MAP doesn't contain media timestamp: " + line, /* cause= */ null);
} }
vttTimestampUs = vttTimestampUs =
WebvttParserUtil.parseTimestampUs( WebvttParserUtil.parseTimestampUs(

View File

@ -567,7 +567,9 @@ public final class DefaultHlsPlaylistTracker
processLoadedPlaylist((HlsMediaPlaylist) result, loadEventInfo); processLoadedPlaylist((HlsMediaPlaylist) result, loadEventInfo);
eventDispatcher.loadCompleted(loadEventInfo, C.DATA_TYPE_MANIFEST); eventDispatcher.loadCompleted(loadEventInfo, C.DATA_TYPE_MANIFEST);
} else { } else {
playlistError = new ParserException("Loaded playlist has unexpected type."); playlistError =
ParserException.createForMalformedManifest(
"Loaded playlist has unexpected type.", /* cause= */ null);
eventDispatcher.loadError( eventDispatcher.loadError(
loadEventInfo, C.DATA_TYPE_MANIFEST, playlistError, /* wasCanceled= */ true); loadEventInfo, C.DATA_TYPE_MANIFEST, playlistError, /* wasCanceled= */ true);
} }

View File

@ -286,7 +286,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
} finally { } finally {
Util.closeQuietly(reader); Util.closeQuietly(reader);
} }
throw new ParserException("Failed to parse the playlist, could not identify any tags."); throw ParserException.createForMalformedManifest(
"Failed to parse the playlist, could not identify any tags.", /* cause= */ null);
} }
private static boolean checkPlaylistHeader(BufferedReader reader) throws IOException { private static boolean checkPlaylistHeader(BufferedReader reader) throws IOException {
@ -404,7 +405,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
uri = uri =
UriUtil.resolveToUri(baseUri, parseStringAttr(line, REGEX_URI, variableDefinitions)); UriUtil.resolveToUri(baseUri, parseStringAttr(line, REGEX_URI, variableDefinitions));
} else if (!iterator.hasNext()) { } else if (!iterator.hasNext()) {
throw new ParserException("#EXT-X-STREAM-INF must be followed by another line"); throw ParserException.createForMalformedManifest(
"#EXT-X-STREAM-INF must be followed by another line", /* cause= */ null);
} else { } else {
// The following line contains #EXT-X-STREAM-INF's URI. // The following line contains #EXT-X-STREAM-INF's URI.
line = replaceVariableReferences(iterator.next(), variableDefinitions); line = replaceVariableReferences(iterator.next(), variableDefinitions);
@ -720,9 +722,10 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
} }
if (fullSegmentEncryptionKeyUri != null && fullSegmentEncryptionIV == null) { if (fullSegmentEncryptionKeyUri != null && fullSegmentEncryptionIV == null) {
// See RFC 8216, Section 4.3.2.5. // See RFC 8216, Section 4.3.2.5.
throw new ParserException( throw ParserException.createForMalformedManifest(
"The encryption IV attribute must be present when an initialization segment is" "The encryption IV attribute must be present when an initialization segment is"
+ "encrypted with METHOD=AES-128."); + " encrypted with METHOD=AES-128.",
/* cause= */ null);
} }
initializationSegment = initializationSegment =
new Segment( new Segment(
@ -1199,7 +1202,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
if (value != null) { if (value != null) {
return value; return value;
} else { } else {
throw new ParserException("Couldn't match " + pattern.pattern() + " in " + line); throw ParserException.createForMalformedManifest(
"Couldn't match " + pattern.pattern() + " in " + line, /* cause= */ null);
} }
} }

View File

@ -82,7 +82,11 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
public static class MissingFieldException extends ParserException { public static class MissingFieldException extends ParserException {
public MissingFieldException(String fieldName) { public MissingFieldException(String fieldName) {
super("Missing required field: " + fieldName); super(
"Missing required field: " + fieldName,
/* cause= */ null,
/* contentIsMalformed= */ true,
C.DATA_TYPE_MANIFEST);
} }
} }
@ -562,7 +566,8 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
startTime = startTimes.get(chunkIndex - 1) + lastChunkDuration; startTime = startTimes.get(chunkIndex - 1) + lastChunkDuration;
} else { } else {
// We don't have the start time, and we're unable to infer it. // We don't have the start time, and we're unable to infer it.
throw new ParserException("Unable to infer start time"); throw ParserException.createForMalformedManifest(
"Unable to infer start time", /* cause= */ null);
} }
} }
chunkIndex++; chunkIndex++;
@ -571,7 +576,8 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
// Handle repeated chunks. // Handle repeated chunks.
long repeatCount = parseLong(parser, KEY_FRAGMENT_REPEAT_COUNT, 1L); long repeatCount = parseLong(parser, KEY_FRAGMENT_REPEAT_COUNT, 1L);
if (repeatCount > 1 && lastChunkDuration == C.TIME_UNSET) { if (repeatCount > 1 && lastChunkDuration == C.TIME_UNSET) {
throw new ParserException("Repeated chunk with unspecified duration"); throw ParserException.createForMalformedManifest(
"Repeated chunk with unspecified duration", /* cause= */ null);
} }
for (int i = 1; i < repeatCount; i++) { for (int i = 1; i < repeatCount; i++) {
chunkIndex++; chunkIndex++;
@ -613,7 +619,8 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
} else if (KEY_TYPE_TEXT.equalsIgnoreCase(value)) { } else if (KEY_TYPE_TEXT.equalsIgnoreCase(value)) {
return C.TRACK_TYPE_TEXT; return C.TRACK_TYPE_TEXT;
} else { } else {
throw new ParserException("Invalid key value[" + value + "]"); throw ParserException.createForMalformedManifest(
"Invalid key value[" + value + "]", /* cause= */ null);
} }
} }
throw new MissingFieldException(KEY_TYPE); throw new MissingFieldException(KEY_TYPE);