OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Detecting mime types is a tricky business because we need to balance | 5 // Detecting mime types is a tricky business because we need to balance |
6 // compatibility concerns with security issues. Here is a survey of how other | 6 // compatibility concerns with security issues. Here is a survey of how other |
7 // browsers behave and then a description of how we intend to behave. | 7 // browsers behave and then a description of how we intend to behave. |
8 // | 8 // |
9 // HTML payload, no Content-Type header: | 9 // HTML payload, no Content-Type header: |
10 // * IE 7: Render as HTML | 10 // * IE 7: Render as HTML |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 // To compare with magic strings, we need to compute strlen(content), but | 337 // To compare with magic strings, we need to compute strlen(content), but |
338 // content might not actually have a null terminator. In that case, we | 338 // content might not actually have a null terminator. In that case, we |
339 // pretend the length is content_size. | 339 // pretend the length is content_size. |
340 const char* end = static_cast<const char*>(memchr(content, '\0', size)); | 340 const char* end = static_cast<const char*>(memchr(content, '\0', size)); |
341 const size_t content_strlen = | 341 const size_t content_strlen = |
342 (end != NULL) ? static_cast<size_t>(end - content) : size; | 342 (end != NULL) ? static_cast<size_t>(end - content) : size; |
343 | 343 |
344 bool match = false; | 344 bool match = false; |
345 if (magic_entry.is_string) { | 345 if (magic_entry.is_string) { |
346 if (content_strlen >= len) { | 346 if (content_strlen >= len) { |
347 // String comparisons are case-insensitive | 347 // Do a case-insensitive prefix comparison. |
348 match = (base::strncasecmp(magic_entry.magic, content, len) == 0); | 348 DCHECK_EQ(strlen(magic_entry.magic), len); |
| 349 match = base::EqualsCaseInsensitiveASCII(magic_entry.magic, |
| 350 base::StringPiece(content, len)); |
349 } | 351 } |
350 } else { | 352 } else { |
351 if (size >= len) { | 353 if (size >= len) { |
352 if (!magic_entry.mask) { | 354 if (!magic_entry.mask) { |
353 match = MagicCmp(magic_entry.magic, content, len); | 355 match = MagicCmp(magic_entry.magic, content, len); |
354 } else { | 356 } else { |
355 match = MagicMaskCmp(magic_entry.magic, content, len, magic_entry.mask); | 357 match = MagicMaskCmp(magic_entry.magic, content, len, magic_entry.mask); |
356 } | 358 } |
357 } | 359 } |
358 } | 360 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 NULL, &office_version)) | 457 NULL, &office_version)) |
456 return false; | 458 return false; |
457 | 459 |
458 OfficeDocType type = DOC_TYPE_NONE; | 460 OfficeDocType type = DOC_TYPE_NONE; |
459 for (size_t i = 0; i < arraysize(kOfficeExtensionTypes); ++i) { | 461 for (size_t i = 0; i < arraysize(kOfficeExtensionTypes); ++i) { |
460 std::string url_path = url.path(); | 462 std::string url_path = url.path(); |
461 | 463 |
462 if (url_path.length() < kOfficeExtensionTypes[i].extension_len) | 464 if (url_path.length() < kOfficeExtensionTypes[i].extension_len) |
463 continue; | 465 continue; |
464 | 466 |
465 const char* extension = | 467 base::StringPiece extension = base::StringPiece(url_path).substr( |
466 &url_path[url_path.length() - kOfficeExtensionTypes[i].extension_len]; | 468 url_path.length() - kOfficeExtensionTypes[i].extension_len); |
467 | 469 if (base::EqualsCaseInsensitiveASCII( |
468 if (0 == base::strncasecmp(extension, kOfficeExtensionTypes[i].extension, | 470 extension, |
469 kOfficeExtensionTypes[i].extension_len)) { | 471 base::StringPiece(kOfficeExtensionTypes[i].extension, |
| 472 kOfficeExtensionTypes[i].extension_len))) { |
470 type = kOfficeExtensionTypes[i].doc_type; | 473 type = kOfficeExtensionTypes[i].doc_type; |
471 break; | 474 break; |
472 } | 475 } |
473 } | 476 } |
474 | 477 |
475 if (type == DOC_TYPE_NONE) | 478 if (type == DOC_TYPE_NONE) |
476 return false; | 479 return false; |
477 | 480 |
478 if (office_version == "CFB") { | 481 if (office_version == "CFB") { |
479 switch (type) { | 482 switch (type) { |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 if (!counter) { | 604 if (!counter) { |
602 counter = UMASnifferHistogramGet("mime_sniffer.kMagicXML2", | 605 counter = UMASnifferHistogramGet("mime_sniffer.kMagicXML2", |
603 arraysize(kMagicXML)); | 606 arraysize(kMagicXML)); |
604 } | 607 } |
605 const int kMaxTagIterations = 5; | 608 const int kMaxTagIterations = 5; |
606 for (int i = 0; i < kMaxTagIterations && pos < end; ++i) { | 609 for (int i = 0; i < kMaxTagIterations && pos < end; ++i) { |
607 pos = reinterpret_cast<const char*>(memchr(pos, '<', end - pos)); | 610 pos = reinterpret_cast<const char*>(memchr(pos, '<', end - pos)); |
608 if (!pos) | 611 if (!pos) |
609 return false; | 612 return false; |
610 | 613 |
611 if ((pos + sizeof("<?xml") - 1 <= end) && | 614 static const char kXmlPrefix[] = "<?xml"; |
612 (base::strncasecmp(pos, "<?xml", sizeof("<?xml") - 1) == 0)) { | 615 static const size_t kXmlPrefixLength = arraysize(kXmlPrefix) - 1; |
| 616 static const char kDocTypePrefix[] = "<!DOCTYPE"; |
| 617 static const size_t kDocTypePrefixLength = arraysize(kDocTypePrefix) - 1; |
| 618 |
| 619 if ((pos + kXmlPrefixLength <= end) && |
| 620 base::EqualsCaseInsensitiveASCII( |
| 621 base::StringPiece(pos, kXmlPrefixLength), |
| 622 base::StringPiece(kXmlPrefix, kXmlPrefixLength))) { |
613 // Skip XML declarations. | 623 // Skip XML declarations. |
614 ++pos; | 624 ++pos; |
615 continue; | 625 continue; |
616 } else if ((pos + sizeof("<!DOCTYPE") - 1 <= end) && | 626 } else if ((pos + kDocTypePrefixLength <= end) && |
617 (base::strncasecmp(pos, "<!DOCTYPE", sizeof("<!DOCTYPE") - 1) == | 627 base::EqualsCaseInsensitiveASCII( |
618 0)) { | 628 base::StringPiece(pos, kDocTypePrefixLength), |
| 629 base::StringPiece(kDocTypePrefix, kDocTypePrefixLength))) { |
619 // Skip DOCTYPE declarations. | 630 // Skip DOCTYPE declarations. |
620 ++pos; | 631 ++pos; |
621 continue; | 632 continue; |
622 } | 633 } |
623 | 634 |
624 if (CheckForMagicNumbers(pos, end - pos, | 635 if (CheckForMagicNumbers(pos, end - pos, |
625 kMagicXML, arraysize(kMagicXML), | 636 kMagicXML, arraysize(kMagicXML), |
626 counter, result)) | 637 counter, result)) |
627 return true; | 638 return true; |
628 | 639 |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
953 ~(1u << '\t' | 1u << '\n' | 1u << '\r' | 1u << '\f' | 1u << '\x1b'); | 964 ~(1u << '\t' | 1u << '\n' | 1u << '\r' | 1u << '\f' | 1u << '\x1b'); |
954 for (size_t i = 0; i < size; ++i) { | 965 for (size_t i = 0; i < size; ++i) { |
955 uint8_t byte = static_cast<uint8_t>(content[i]); | 966 uint8_t byte = static_cast<uint8_t>(content[i]); |
956 if (byte < 0x20 && (kBinaryBits & (1u << byte))) | 967 if (byte < 0x20 && (kBinaryBits & (1u << byte))) |
957 return true; | 968 return true; |
958 } | 969 } |
959 return false; | 970 return false; |
960 } | 971 } |
961 | 972 |
962 } // namespace net | 973 } // namespace net |
OLD | NEW |