Chromium Code Reviews| Index: net/base/mime_sniffer.cc |
| diff --git a/net/base/mime_sniffer.cc b/net/base/mime_sniffer.cc |
| index d53b567ffec075a6f4b871ffafbe388f00fb2b63..180d4a14abfcabb3a61403585ddf247d15d06167 100644 |
| --- a/net/base/mime_sniffer.cc |
| +++ b/net/base/mime_sniffer.cc |
| @@ -114,14 +114,18 @@ struct MagicNumber { |
| const char* magic; |
| size_t magic_len; |
| bool is_string; |
| + const char* mask; // must have same length as |magic| |
|
vandebo (ex-Chrome)
2013/05/02 21:58:24
nit: If not NULL, must have same length as |magic|
Kevin Bailey
2013/05/03 16:52:55
Not nit, good point.
|
| }; |
| #define MAGIC_NUMBER(mime_type, magic) \ |
| - { (mime_type), (magic), sizeof(magic)-1, false }, |
| + { (mime_type), (magic), sizeof(magic)-1, false, NULL }, |
| + |
| +#define MAGIC_MASK(mime_type, magic, mask) \ |
| + { (mime_type), (magic), sizeof(magic)-1, false, (mask) }, |
| // Magic strings are case insensitive and must not include '\0' characters |
| #define MAGIC_STRING(mime_type, magic) \ |
| - { (mime_type), (magic), sizeof(magic)-1, true }, |
| + { (mime_type), (magic), sizeof(magic)-1, true, NULL }, |
| static const MagicNumber kMagicNumbers[] = { |
| // Source: HTML 5 specification |
| @@ -176,6 +180,24 @@ static const MagicNumber kMagicNumbers[] = { |
| // On balance, we do not include these patterns. |
| }; |
| +static const MagicNumber kExtraMagicNumbers[] = { |
| + MAGIC_NUMBER("image/x-xbitmap", "#define") |
| + MAGIC_NUMBER("image/x-icon", "\x00\x00\x01\x00") |
| + MAGIC_NUMBER("image/svg+xml", "<?xml_version=") |
| + MAGIC_NUMBER("audio/wav", "RIFF....WAVEfmt ") |
| + MAGIC_NUMBER("video/avi", "RIFF....AVI LIST") |
| + MAGIC_NUMBER("audio/ogg", "OggS") |
| + MAGIC_MASK("video/mpeg", "\x00\x00\x01\xB0", "\xFF\xFF\xFF\xF0") |
| + MAGIC_MASK("audio/mpeg", "\xFF\xE0", "\xFF\xE0") |
| + MAGIC_NUMBER("video/3gpp", "....ftyp3g") |
| + MAGIC_NUMBER("video/3gpp", "....ftypavcl") |
| + MAGIC_NUMBER("video/mp4", "....ftyp") |
| + MAGIC_NUMBER("video/quicktime", "MOVI") |
| + MAGIC_NUMBER("application/x-shockwave-flash", "CWS") |
| + MAGIC_NUMBER("application/x-shockwave-flash", "FWS") |
| + MAGIC_NUMBER("video/x-flv", "FLV") |
| +}; |
| + |
| // Our HTML sniffer differs slightly from Mozilla. For example, Mozilla will |
| // decide that a document that begins "<!DOCTYPE SOAP-ENV:Envelope PUBLIC " is |
| // HTML, but we will not. |
| @@ -230,6 +252,21 @@ static bool MagicCmp(const char* magic_entry, const char* content, size_t len) { |
| return true; |
| } |
| +// Like MagicCmp() except that it ANDs each byte with a mask before |
| +// the comparison, because there are some bits we don't care about. |
| +static bool MagicMaskCmp(const char* magic_entry, const char* content, |
| + size_t len, const char* mask) { |
| + while (len) { |
| + if ((*magic_entry != '.') && (*magic_entry != (*mask & *content))) |
| + return false; |
| + ++magic_entry; |
| + ++content; |
| + ++mask; |
| + --len; |
| + } |
| + return true; |
| +} |
| + |
| static bool MatchMagicNumber(const char* content, size_t size, |
| const MagicNumber* magic_entry, |
| std::string* result) { |
| @@ -253,8 +290,14 @@ static bool MatchMagicNumber(const char* content, size_t size, |
| match = (base::strncasecmp(magic_entry->magic, content, len) == 0); |
| } |
| } else { |
| - if (size >= len) |
| - match = MagicCmp(magic_entry->magic, content, len); |
| + if (size >= len) { |
| + if (!magic_entry->mask) { |
| + match = MagicCmp(magic_entry->magic, content, len); |
| + } else { |
| + match = MagicMaskCmp(magic_entry->magic, content, len, |
| + magic_entry->mask); |
| + } |
| + } |
| } |
| if (match) { |
| @@ -686,4 +729,17 @@ bool SniffMimeType(const char* content, size_t content_size, |
| return have_enough_content; |
| } |
| +bool IdentifyExtraMimeType(const char* content, size_t size, |
| + std::string* result) { |
| + // First check the extra table. |
| + if (CheckForMagicNumbers(content, size, kExtraMagicNumbers, |
| + sizeof(kExtraMagicNumbers) / sizeof(MagicNumber), |
| + NULL, result)) |
| + return true; |
| + // Finally check the original table. |
| + return CheckForMagicNumbers(content, size, kMagicNumbers, |
| + sizeof(kMagicNumbers) / sizeof(MagicNumber), |
| + NULL, result); |
| +} |
| + |
| } // namespace net |