ID3: Fix end-of-string detection for UTF-16
The current detection logic checks that the two byte terminator starts at an even position in the ID3 data, where-as it should check that it starts at an even position relative to the start of the string. Issue: #9087 PiperOrigin-RevId: 395274934
This commit is contained in:
parent
a1d376fae1
commit
1bd96fbaf7
@ -12,6 +12,8 @@
|
||||
* Extractors:
|
||||
* Support TS packets without PTS flag
|
||||
([#9294](https://github.com/google/ExoPlayer/issues/9294)).
|
||||
* ID3: Fix issue decoding ID3 tags containing UTF-16 encoded strings
|
||||
([#9087](https://github.com/google/ExoPlayer/issues/9087)).
|
||||
* Video:
|
||||
* Request smaller decoder input buffers for Dolby Vision. This fixes an
|
||||
issue that could cause UHD Dolby Vision playbacks to fail on some
|
||||
|
@ -806,9 +806,9 @@ public final class Id3Decoder extends SimpleMetadataDecoder {
|
||||
return terminationPos;
|
||||
}
|
||||
|
||||
// Otherwise ensure an even index and look for a second zero byte.
|
||||
// Otherwise ensure an even offset from the start, and look for a second zero byte.
|
||||
while (terminationPos < data.length - 1) {
|
||||
if (terminationPos % 2 == 0 && data[terminationPos + 1] == (byte) 0) {
|
||||
if ((terminationPos - fromIndex) % 2 == 0 && data[terminationPos + 1] == (byte) 0) {
|
||||
return terminationPos;
|
||||
}
|
||||
terminationPos = indexOfZeroByte(data, terminationPos + 1);
|
||||
|
@ -38,6 +38,7 @@ public final class Id3DecoderTest {
|
||||
|
||||
@Test
|
||||
public void decodeTxxxFrame() {
|
||||
// Test UTF-8.
|
||||
byte[] rawId3 =
|
||||
buildSingleFrameTag(
|
||||
"TXXX",
|
||||
@ -53,6 +54,21 @@ public final class Id3DecoderTest {
|
||||
assertThat(textInformationFrame.description).isEmpty();
|
||||
assertThat(textInformationFrame.value).isEqualTo("mdialog_VINDICO1527664_start");
|
||||
|
||||
// Test UTF-16.
|
||||
rawId3 =
|
||||
buildSingleFrameTag(
|
||||
"TXXX",
|
||||
new byte[] {
|
||||
1, 0, 72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 32, 0, 87, 0, 111, 0, 114, 0, 108, 0,
|
||||
100, 0, 0
|
||||
});
|
||||
metadata = decoder.decode(rawId3, rawId3.length);
|
||||
assertThat(metadata.length()).isEqualTo(1);
|
||||
textInformationFrame = (TextInformationFrame) metadata.get(0);
|
||||
assertThat(textInformationFrame.id).isEqualTo("TXXX");
|
||||
assertThat(textInformationFrame.description).isEqualTo("Hello World");
|
||||
assertThat(textInformationFrame.value).isEmpty();
|
||||
|
||||
// Test empty.
|
||||
rawId3 = buildSingleFrameTag("TXXX", new byte[0]);
|
||||
metadata = decoder.decode(rawId3, rawId3.length);
|
||||
@ -220,6 +236,43 @@ public final class Id3DecoderTest {
|
||||
assertThat(apicFrame.description).isEqualTo("Hello World");
|
||||
assertThat(apicFrame.pictureData).hasLength(10);
|
||||
assertThat(apicFrame.pictureData).isEqualTo(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0});
|
||||
|
||||
// Test with UTF-16 description at even offset.
|
||||
rawId3 =
|
||||
buildSingleFrameTag(
|
||||
"APIC",
|
||||
new byte[] {
|
||||
1, 105, 109, 97, 103, 101, 47, 106, 112, 101, 103, 0, 16, 0, 72, 0, 101, 0, 108, 0,
|
||||
108, 0, 111, 0, 32, 0, 87, 0, 111, 0, 114, 0, 108, 0, 100, 0, 0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 0
|
||||
});
|
||||
decoder = new Id3Decoder();
|
||||
metadata = decoder.decode(rawId3, rawId3.length);
|
||||
assertThat(metadata.length()).isEqualTo(1);
|
||||
apicFrame = (ApicFrame) metadata.get(0);
|
||||
assertThat(apicFrame.mimeType).isEqualTo("image/jpeg");
|
||||
assertThat(apicFrame.pictureType).isEqualTo(16);
|
||||
assertThat(apicFrame.description).isEqualTo("Hello World");
|
||||
assertThat(apicFrame.pictureData).hasLength(10);
|
||||
assertThat(apicFrame.pictureData).isEqualTo(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0});
|
||||
|
||||
// Test with UTF-16 description at odd offset.
|
||||
rawId3 =
|
||||
buildSingleFrameTag(
|
||||
"APIC",
|
||||
new byte[] {
|
||||
1, 105, 109, 97, 103, 101, 47, 112, 110, 103, 0, 16, 0, 72, 0, 101, 0, 108, 0, 108, 0,
|
||||
111, 0, 32, 0, 87, 0, 111, 0, 114, 0, 108, 0, 100, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0
|
||||
});
|
||||
decoder = new Id3Decoder();
|
||||
metadata = decoder.decode(rawId3, rawId3.length);
|
||||
assertThat(metadata.length()).isEqualTo(1);
|
||||
apicFrame = (ApicFrame) metadata.get(0);
|
||||
assertThat(apicFrame.mimeType).isEqualTo("image/png");
|
||||
assertThat(apicFrame.pictureType).isEqualTo(16);
|
||||
assertThat(apicFrame.description).isEqualTo("Hello World");
|
||||
assertThat(apicFrame.pictureData).hasLength(10);
|
||||
assertThat(apicFrame.pictureData).isEqualTo(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0});
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
x
Reference in New Issue
Block a user