Make ID3 GEOB frames parsing more robust

Issue:#3792

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=185668919
This commit is contained in:
aquilescanta 2018-02-14 04:25:44 -08:00 committed by Oliver Woodman
parent 43cfb08207
commit 4d26b316cc
2 changed files with 30 additions and 25 deletions

View File

@ -109,6 +109,8 @@
* Release `Extractor`s on the loading thread to avoid potentially leaking
resources when the playback thread has quit by the time the loading task has
completed.
* ID3: Better handle malformed ID3 data
([#3792](https://github.com/google/ExoPlayer/issues/3792).
### 2.6.1 ###

View File

@ -405,14 +405,9 @@ public final class Id3Decoder implements MetadataDecoder {
int descriptionEndIndex = indexOfEos(data, 0, encoding);
String description = new String(data, 0, descriptionEndIndex, charset);
String value;
int valueStartIndex = descriptionEndIndex + delimiterLength(encoding);
if (valueStartIndex < data.length) {
int valueEndIndex = indexOfEos(data, valueStartIndex, encoding);
value = new String(data, valueStartIndex, valueEndIndex - valueStartIndex, charset);
} else {
value = "";
}
int valueEndIndex = indexOfEos(data, valueStartIndex, encoding);
String value = decodeStringIfValid(data, valueStartIndex, valueEndIndex, charset);
return new TextInformationFrame("TXXX", description, value);
}
@ -452,14 +447,9 @@ public final class Id3Decoder implements MetadataDecoder {
int descriptionEndIndex = indexOfEos(data, 0, encoding);
String description = new String(data, 0, descriptionEndIndex, charset);
String url;
int urlStartIndex = descriptionEndIndex + delimiterLength(encoding);
if (urlStartIndex < data.length) {
int urlEndIndex = indexOfZeroByte(data, urlStartIndex);
url = new String(data, urlStartIndex, urlEndIndex - urlStartIndex, "ISO-8859-1");
} else {
url = "";
}
int urlEndIndex = indexOfZeroByte(data, urlStartIndex);
String url = decodeStringIfValid(data, urlStartIndex, urlEndIndex, "ISO-8859-1");
return new UrlLinkFrame("WXXX", description, url);
}
@ -502,13 +492,12 @@ public final class Id3Decoder implements MetadataDecoder {
int filenameStartIndex = mimeTypeEndIndex + 1;
int filenameEndIndex = indexOfEos(data, filenameStartIndex, encoding);
String filename = new String(data, filenameStartIndex, filenameEndIndex - filenameStartIndex,
charset);
String filename = decodeStringIfValid(data, filenameStartIndex, filenameEndIndex, charset);
int descriptionStartIndex = filenameEndIndex + delimiterLength(encoding);
int descriptionEndIndex = indexOfEos(data, descriptionStartIndex, encoding);
String description = new String(data, descriptionStartIndex,
descriptionEndIndex - descriptionStartIndex, charset);
String description =
decodeStringIfValid(data, descriptionStartIndex, descriptionEndIndex, charset);
int objectDataStartIndex = descriptionEndIndex + delimiterLength(encoding);
byte[] objectData = copyOfRangeIfValid(data, objectDataStartIndex, data.length);
@ -573,14 +562,9 @@ public final class Id3Decoder implements MetadataDecoder {
int descriptionEndIndex = indexOfEos(data, 0, encoding);
String description = new String(data, 0, descriptionEndIndex, charset);
String text;
int textStartIndex = descriptionEndIndex + delimiterLength(encoding);
if (textStartIndex < data.length) {
int textEndIndex = indexOfEos(data, textStartIndex, encoding);
text = new String(data, textStartIndex, textEndIndex - textStartIndex, charset);
} else {
text = "";
}
int textEndIndex = indexOfEos(data, textStartIndex, encoding);
String text = decodeStringIfValid(data, textStartIndex, textEndIndex, charset);
return new CommentFrame(language, description, text);
}
@ -760,6 +744,25 @@ public final class Id3Decoder implements MetadataDecoder {
return Arrays.copyOfRange(data, from, to);
}
/**
* Returns a string obtained by decoding the specified range of {@code data} using the specified
* {@code charsetName}. An empty string is returned if the range is invalid.
*
* @param data The array from which to decode the string.
* @param from The start of the range.
* @param to The end of the range (exclusive).
* @param charsetName The name of the Charset to use.
* @return The decoded string, or an empty string if the range is invalid.
* @throws UnsupportedEncodingException If the Charset is not supported.
*/
private static String decodeStringIfValid(byte[] data, int from, int to, String charsetName)
throws UnsupportedEncodingException {
if (to <= from || to > data.length) {
return "";
}
return new String(data, from, to - from, charsetName);
}
private static final class Id3Header {
private final int majorVersion;