Bug 1079747 - Follow WhatWG's MIMESniff spec for MP4 more closely. r=cpearce
--- a/toolkit/components/mediasniffer/nsMediaSniffer.cpp
+++ b/toolkit/components/mediasniffer/nsMediaSniffer.cpp
@@ -33,16 +33,36 @@ nsMediaSniffer::nsMediaSnifferEntry nsMe
// The string OggS, followed by the null byte.
PATTERN_ENTRY("\xFF\xFF\xFF\xFF\xFF", "OggS", APPLICATION_OGG),
// The string RIFF, followed by four bytes, followed by the string WAVE
PATTERN_ENTRY("\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF", "RIFF\x00\x00\x00\x00WAVE", AUDIO_WAV),
// mp3 with ID3 tags, the string "ID3".
PATTERN_ENTRY("\xFF\xFF\xFF", "ID3", AUDIO_MP3)
};
+static bool MatchesMP4orISOBrand(const uint8_t aData[4])
+{
+ // Return true if aData contains the string "mp4" (last byte ignored).
+ if (aData[0] == 0x6D &&
+ aData[1] == 0x70 &&
+ aData[2] == 0x34) {
+ return true;
+ }
+
+ // Return true if aData contains the string "isom", or "iso2".
+ if (aData[0] == 0x69 &&
+ aData[1] == 0x73 &&
+ aData[2] == 0x6F &&
+ (aData[3] == 0x6D || aData[3] == 0x32)) {
+ return true;
+ }
+
+ return false;
+}
+
// This function implements mp4 sniffing algorithm, described at
// http://mimesniff.spec.whatwg.org/#signature-for-mp4
static bool MatchesMP4(const uint8_t* aData, const uint32_t aLength)
{
if (aLength <= MP4_MIN_BYTES_COUNT) {
return false;
}
// Conversion from big endian to host byte order.
@@ -54,34 +74,28 @@ static bool MatchesMP4(const uint8_t* aD
}
// The string "ftyp".
if (aData[4] != 0x66 ||
aData[5] != 0x74 ||
aData[6] != 0x79 ||
aData[7] != 0x70) {
return false;
}
- for (uint32_t i = 2; i <= boxSize / 4 - 1 ; i++) {
- if (i == 3) {
- continue;
- }
- // The string "mp42" or "mp41".
- if (aData[4*i] == 0x6D &&
- aData[4*i+1] == 0x70 &&
- aData[4*i+2] == 0x34) {
+ if (MatchesMP4orISOBrand(&aData[8])) {
+ return true;
+ }
+ // Skip minor_version (bytes 12-15).
+ uint32_t bytesRead = 16;
+ while (bytesRead < boxSize) {
+ if (MatchesMP4orISOBrand(&aData[bytesRead])) {
return true;
}
- // The string "isom" or "iso2".
- if (aData[4*i] == 0x69 &&
- aData[4*i+1] == 0x73 &&
- aData[4*i+2] == 0x6F &&
- (aData[4*i+3] == 0x6D || aData[4*i+3] == 0x32)) {
- return true;
- }
+ bytesRead += 4;
}
+
return false;
}
static bool MatchesWebM(const uint8_t* aData, const uint32_t aLength)
{
#ifdef MOZ_WEBM
return nestegg_sniff((uint8_t*)aData, aLength) ? true : false;
#else
new file mode 100644
index 0000000000000000000000000000000000000000..f00731d7e2719eef6ba82f4f88f946d73f3a2289
GIT binary patch
literal 512
zc${NkU|>iqsVqoIEC#X|GK=%g63dbea|=uiRj(viS6(^)cm{vky`DAePB1VW$@Xyb
z)oJb6$<UIUpI-)4pOagbkpj|qCZXI3gc%s)CxG}2j9`QSC>%__0|Q>b1jHJ-WvLZF
zTA`!}Ov6k;Gl}s<Nl{`pkP*Yc0CpQQ+-+dBtlM5KG3#49?^zcPyNGZp<0>HW0W8^)
zo06Fba#d~$_K*lY0@kLRk&;scGovgsB^BAsFd#qQBQY-}Cl#cIQ9m~`FAd00NrBKZ
sDMhJiNY3FYEy_`Vvfme%B;^3<$;BnbDM)IXLGg&gOCS$?VDJDk0Nof;J^%m!
--- a/toolkit/components/mediasniffer/test/unit/test_mediasniffer_ext.js
+++ b/toolkit/components/mediasniffer/test/unit/test_mediasniffer_ext.js
@@ -34,16 +34,18 @@ const tests = [
// Garbage before header: sniffing should fail.
{ path: "data/notags-scan.mp3", expected: "application/octet-stream" },
// VBR from the layer III test patterns. We can't sniff this.
{ path: "data/he_free.mp3", expected: "application/octet-stream" },
// Make sure we reject mp2, which has a similar header.
{ path: "data/fl10.mp2", expected: "application/octet-stream" },
// Truncated ff installer regression test for bug 875769.
{ path: "data/ff-inst.exe", expected: "application/octet-stream" },
+ // MP4 with invalid box size (0) for "ftyp".
+ { path: "data/bug1079747.mp4", expected: "application/octet-stream" },
];
// A basic listener that reads checks the if we sniffed properly.
var listener = {
onStartRequest: function(request, context) {
do_print("Sniffing " + tests[testRan].path);
do_check_eq(request.QueryInterface(Ci.nsIChannel).contentType, tests[testRan].expected);
},
--- a/toolkit/components/mediasniffer/test/unit/xpcshell.ini
+++ b/toolkit/components/mediasniffer/test/unit/xpcshell.ini
@@ -1,13 +1,14 @@
[DEFAULT]
head =
tail =
skip-if = toolkit == 'android' || toolkit == 'gonk'
support-files =
+ data/bug1079747.mp4
data/detodos.mp3
data/ff-inst.exe
data/file.mkv
data/file.webm
data/fl10.mp2
data/he_free.mp3
data/id3tags.mp3
data/notags-bad.mp3