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);