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 * 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 resources when the playback thread has quit by the time the loading task has
completed. completed.
* ID3: Better handle malformed ID3 data
([#3792](https://github.com/google/ExoPlayer/issues/3792).
### 2.6.1 ### ### 2.6.1 ###

View File

@ -405,14 +405,9 @@ public final class Id3Decoder implements MetadataDecoder {
int descriptionEndIndex = indexOfEos(data, 0, encoding); int descriptionEndIndex = indexOfEos(data, 0, encoding);
String description = new String(data, 0, descriptionEndIndex, charset); String description = new String(data, 0, descriptionEndIndex, charset);
String value;
int valueStartIndex = descriptionEndIndex + delimiterLength(encoding); int valueStartIndex = descriptionEndIndex + delimiterLength(encoding);
if (valueStartIndex < data.length) {
int valueEndIndex = indexOfEos(data, valueStartIndex, encoding); int valueEndIndex = indexOfEos(data, valueStartIndex, encoding);
value = new String(data, valueStartIndex, valueEndIndex - valueStartIndex, charset); String value = decodeStringIfValid(data, valueStartIndex, valueEndIndex, charset);
} else {
value = "";
}
return new TextInformationFrame("TXXX", description, value); return new TextInformationFrame("TXXX", description, value);
} }
@ -452,14 +447,9 @@ public final class Id3Decoder implements MetadataDecoder {
int descriptionEndIndex = indexOfEos(data, 0, encoding); int descriptionEndIndex = indexOfEos(data, 0, encoding);
String description = new String(data, 0, descriptionEndIndex, charset); String description = new String(data, 0, descriptionEndIndex, charset);
String url;
int urlStartIndex = descriptionEndIndex + delimiterLength(encoding); int urlStartIndex = descriptionEndIndex + delimiterLength(encoding);
if (urlStartIndex < data.length) {
int urlEndIndex = indexOfZeroByte(data, urlStartIndex); int urlEndIndex = indexOfZeroByte(data, urlStartIndex);
url = new String(data, urlStartIndex, urlEndIndex - urlStartIndex, "ISO-8859-1"); String url = decodeStringIfValid(data, urlStartIndex, urlEndIndex, "ISO-8859-1");
} else {
url = "";
}
return new UrlLinkFrame("WXXX", description, url); return new UrlLinkFrame("WXXX", description, url);
} }
@ -502,13 +492,12 @@ public final class Id3Decoder implements MetadataDecoder {
int filenameStartIndex = mimeTypeEndIndex + 1; int filenameStartIndex = mimeTypeEndIndex + 1;
int filenameEndIndex = indexOfEos(data, filenameStartIndex, encoding); int filenameEndIndex = indexOfEos(data, filenameStartIndex, encoding);
String filename = new String(data, filenameStartIndex, filenameEndIndex - filenameStartIndex, String filename = decodeStringIfValid(data, filenameStartIndex, filenameEndIndex, charset);
charset);
int descriptionStartIndex = filenameEndIndex + delimiterLength(encoding); int descriptionStartIndex = filenameEndIndex + delimiterLength(encoding);
int descriptionEndIndex = indexOfEos(data, descriptionStartIndex, encoding); int descriptionEndIndex = indexOfEos(data, descriptionStartIndex, encoding);
String description = new String(data, descriptionStartIndex, String description =
descriptionEndIndex - descriptionStartIndex, charset); decodeStringIfValid(data, descriptionStartIndex, descriptionEndIndex, charset);
int objectDataStartIndex = descriptionEndIndex + delimiterLength(encoding); int objectDataStartIndex = descriptionEndIndex + delimiterLength(encoding);
byte[] objectData = copyOfRangeIfValid(data, objectDataStartIndex, data.length); byte[] objectData = copyOfRangeIfValid(data, objectDataStartIndex, data.length);
@ -573,14 +562,9 @@ public final class Id3Decoder implements MetadataDecoder {
int descriptionEndIndex = indexOfEos(data, 0, encoding); int descriptionEndIndex = indexOfEos(data, 0, encoding);
String description = new String(data, 0, descriptionEndIndex, charset); String description = new String(data, 0, descriptionEndIndex, charset);
String text;
int textStartIndex = descriptionEndIndex + delimiterLength(encoding); int textStartIndex = descriptionEndIndex + delimiterLength(encoding);
if (textStartIndex < data.length) {
int textEndIndex = indexOfEos(data, textStartIndex, encoding); int textEndIndex = indexOfEos(data, textStartIndex, encoding);
text = new String(data, textStartIndex, textEndIndex - textStartIndex, charset); String text = decodeStringIfValid(data, textStartIndex, textEndIndex, charset);
} else {
text = "";
}
return new CommentFrame(language, description, text); return new CommentFrame(language, description, text);
} }
@ -760,6 +744,25 @@ public final class Id3Decoder implements MetadataDecoder {
return Arrays.copyOfRange(data, from, to); 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 static final class Id3Header {
private final int majorVersion; private final int majorVersion;