Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
| 6 #include "net/base/mime_sniffer.h" | 6 #include "net/base/mime_sniffer.h" |
| 7 #include "testing/gtest/include/gtest/gtest.h" | 7 #include "testing/gtest/include/gtest/gtest.h" |
| 8 #include "url/gurl.h" | 8 #include "url/gurl.h" |
| 9 | 9 |
| 10 namespace net { | 10 namespace net { |
| 11 | 11 |
| 12 struct SnifferTest { | 12 struct SnifferTest { |
| 13 const char* content; | 13 const char* content; |
| 14 size_t content_len; | 14 size_t content_len; |
| 15 std::string url; | 15 std::string url; |
| 16 std::string type_hint; | 16 std::string type_hint; |
| 17 const char* mime_type; | 17 const char* mime_type; |
| 18 }; | 18 }; |
| 19 | 19 |
| 20 static void TestArray(SnifferTest* tests, size_t count) { | 20 static void TestArray(SnifferTest* tests, size_t count) { |
| 21 std::string mime_type; | 21 std::string mime_type; |
| 22 | 22 |
| 23 for (size_t i = 0; i < count; ++i) { | 23 for (size_t i = 0; i < count; ++i) { |
| 24 SniffMimeType(tests[i].content, | 24 SniffMimeType(tests[i].content, |
| 25 tests[i].content_len, | 25 tests[i].content_len, |
| 26 GURL(tests[i].url), | 26 GURL(tests[i].url), |
| 27 tests[i].type_hint, | 27 tests[i].type_hint, |
| 28 &mime_type); | 28 &mime_type); |
| 29 EXPECT_EQ(tests[i].mime_type, mime_type); | 29 EXPECT_EQ(tests[i].mime_type, mime_type); |
| 30 } | 30 } |
| 31 } | 31 } |
| 32 | 32 |
| 33 // TODO(evanm): convert other tests to use SniffMimeType instead of TestArray, | 33 // TODO(evanm): convert other tests to use SniffMimeType instead of TestArray, |
| 34 // so the error messages produced by test failures are more useful. | 34 // so the error messages produced by test failures are more useful. |
| 35 static std::string SniffMimeType(const std::string& content, | 35 static std::string SniffMimeType(const std::string& content, |
| 36 const std::string& url, | 36 const std::string& url, |
| 37 const std::string& mime_type_hint) { | 37 const std::string& mime_type_hint) { |
| 38 std::string mime_type; | 38 std::string mime_type; |
| 39 SniffMimeType(content.data(), content.size(), GURL(url), | 39 SniffMimeType( |
| 40 mime_type_hint, &mime_type); | 40 content.data(), content.size(), GURL(url), mime_type_hint, &mime_type); |
| 41 return mime_type; | 41 return mime_type; |
| 42 } | 42 } |
| 43 | 43 |
| 44 TEST(MimeSnifferTest, BoundaryConditionsTest) { | 44 TEST(MimeSnifferTest, BoundaryConditionsTest) { |
| 45 std::string mime_type; | 45 std::string mime_type; |
| 46 std::string type_hint; | 46 std::string type_hint; |
| 47 | 47 |
| 48 char buf[] = { | 48 char buf[] = {'d', '\x1f', '\xFF'}; |
| 49 'd', '\x1f', '\xFF' | |
| 50 }; | |
| 51 | 49 |
| 52 GURL url; | 50 GURL url; |
| 53 | 51 |
| 54 SniffMimeType(buf, 0, url, type_hint, &mime_type); | 52 SniffMimeType(buf, 0, url, type_hint, &mime_type); |
| 55 EXPECT_EQ("text/plain", mime_type); | 53 EXPECT_EQ("text/plain", mime_type); |
| 56 SniffMimeType(buf, 1, url, type_hint, &mime_type); | 54 SniffMimeType(buf, 1, url, type_hint, &mime_type); |
| 57 EXPECT_EQ("text/plain", mime_type); | 55 EXPECT_EQ("text/plain", mime_type); |
| 58 SniffMimeType(buf, 2, url, type_hint, &mime_type); | 56 SniffMimeType(buf, 2, url, type_hint, &mime_type); |
| 59 EXPECT_EQ("application/octet-stream", mime_type); | 57 EXPECT_EQ("application/octet-stream", mime_type); |
| 60 } | 58 } |
| 61 | 59 |
| 62 TEST(MimeSnifferTest, BasicSniffingTest) { | 60 TEST(MimeSnifferTest, BasicSniffingTest) { |
| 63 SnifferTest tests[] = { | 61 SnifferTest tests[] = { |
| 64 { "<!DOCTYPE html PUBLIC", sizeof("<!DOCTYPE html PUBLIC")-1, | 62 {"<!DOCTYPE html PUBLIC", sizeof("<!DOCTYPE html PUBLIC") - 1, |
| 65 "http://www.example.com/", | 63 "http://www.example.com/", "", "text/html"}, |
| 66 "", "text/html" }, | 64 {"<HtMl><Body></body></htMl>", sizeof("<HtMl><Body></body></htMl>") - 1, |
| 67 { "<HtMl><Body></body></htMl>", sizeof("<HtMl><Body></body></htMl>")-1, | 65 "http://www.example.com/foo.gif", "application/octet-stream", |
| 68 "http://www.example.com/foo.gif", | 66 "application/octet-stream"}, |
| 69 "application/octet-stream", "application/octet-stream" }, | 67 {"GIF89a\x1F\x83\x94", sizeof("GIF89a\xAF\x83\x94") - 1, |
| 70 { "GIF89a\x1F\x83\x94", sizeof("GIF89a\xAF\x83\x94")-1, | 68 "http://www.example.com/foo", "text/plain", "image/gif"}, |
| 71 "http://www.example.com/foo", | 69 {"Gif87a\x1F\x83\x94", sizeof("Gif87a\xAF\x83\x94") - 1, |
| 72 "text/plain", "image/gif" }, | 70 "http://www.example.com/foo?param=tt.gif", "", |
| 73 { "Gif87a\x1F\x83\x94", sizeof("Gif87a\xAF\x83\x94")-1, | 71 "application/octet-stream"}, |
| 74 "http://www.example.com/foo?param=tt.gif", | 72 {"%!PS-Adobe-3.0", sizeof("%!PS-Adobe-3.0") - 1, |
| 75 "", "application/octet-stream" }, | 73 "http://www.example.com/foo", "text/plain", "text/plain"}, |
| 76 { "%!PS-Adobe-3.0", sizeof("%!PS-Adobe-3.0")-1, | 74 {"\x89" |
| 77 "http://www.example.com/foo", | 75 "PNG\x0D\x0A\x1A\x0A", |
| 78 "text/plain", "text/plain" }, | 76 sizeof( |
| 79 { "\x89" "PNG\x0D\x0A\x1A\x0A", sizeof("\x89" "PNG\x0D\x0A\x1A\x0A")-1, | 77 "\x89" |
| 80 "http://www.example.com/foo", | 78 "PNG\x0D\x0A\x1A\x0A") - |
| 81 "application/octet-stream", "application/octet-stream" }, | 79 1, |
| 82 { "\xFF\xD8\xFF\x23\x49\xAF", sizeof("\xFF\xD8\xFF\x23\x49\xAF")-1, | 80 "http://www.example.com/foo", "application/octet-stream", |
| 83 "http://www.example.com/foo", | 81 "application/octet-stream"}, |
| 84 "", "image/jpeg" }, | 82 {"\xFF\xD8\xFF\x23\x49\xAF", sizeof("\xFF\xD8\xFF\x23\x49\xAF") - 1, |
| 83 "http://www.example.com/foo", "", "image/jpeg"}, | |
| 85 }; | 84 }; |
| 86 | 85 |
| 87 TestArray(tests, arraysize(tests)); | 86 TestArray(tests, arraysize(tests)); |
| 88 } | 87 } |
| 89 | 88 |
| 90 TEST(MimeSnifferTest, ChromeExtensionsTest) { | 89 TEST(MimeSnifferTest, ChromeExtensionsTest) { |
| 91 SnifferTest tests[] = { | 90 SnifferTest tests[] = { |
| 92 // schemes | 91 // schemes |
| 93 { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1, | 92 {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, |
| 94 "http://www.example.com/foo.crx", | 93 "http://www.example.com/foo.crx", "", "application/x-chrome-extension"}, |
| 95 "", "application/x-chrome-extension" }, | 94 {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, |
| 96 { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1, | 95 "https://www.example.com/foo.crx", "", "application/x-chrome-extension"}, |
| 97 "https://www.example.com/foo.crx", | 96 {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, |
| 98 "", "application/x-chrome-extension" }, | 97 "ftp://www.example.com/foo.crx", "", "application/x-chrome-extension"}, |
| 99 { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1, | |
| 100 "ftp://www.example.com/foo.crx", | |
| 101 "", "application/x-chrome-extension" }, | |
| 102 | 98 |
| 103 // some other mimetypes that should get converted | 99 // some other mimetypes that should get converted |
| 104 { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1, | 100 {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, |
| 105 "http://www.example.com/foo.crx", | 101 "http://www.example.com/foo.crx", "text/plain", |
| 106 "text/plain", "application/x-chrome-extension" }, | 102 "application/x-chrome-extension"}, |
| 107 { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1, | 103 {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, |
| 108 "http://www.example.com/foo.crx", | 104 "http://www.example.com/foo.crx", "application/octet-stream", |
| 109 "application/octet-stream", "application/x-chrome-extension" }, | 105 "application/x-chrome-extension"}, |
| 110 | 106 |
| 111 // success edge cases | 107 // success edge cases |
| 112 { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1, | 108 {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, |
| 113 "http://www.example.com/foo.crx?query=string", | 109 "http://www.example.com/foo.crx?query=string", "", |
| 114 "", "application/x-chrome-extension" }, | 110 "application/x-chrome-extension"}, |
| 115 { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1, | 111 {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, |
| 116 "http://www.example.com/foo..crx", | 112 "http://www.example.com/foo..crx", "", "application/x-chrome-extension"}, |
| 117 "", "application/x-chrome-extension" }, | |
| 118 | 113 |
| 119 // wrong file extension | 114 // wrong file extension |
| 120 { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1, | 115 {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, |
| 121 "http://www.example.com/foo.bin", | 116 "http://www.example.com/foo.bin", "", "application/octet-stream"}, |
| 122 "", "application/octet-stream" }, | 117 {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, |
| 123 { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1, | 118 "http://www.example.com/foo.bin?monkey", "", "application/octet-stream"}, |
| 124 "http://www.example.com/foo.bin?monkey", | 119 {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, |
| 125 "", "application/octet-stream" }, | 120 "invalid-url", "", "application/octet-stream"}, |
| 126 { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1, | 121 {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, |
| 127 "invalid-url", | 122 "http://www.example.com", "", "application/octet-stream"}, |
| 128 "", "application/octet-stream" }, | 123 {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, |
| 129 { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1, | 124 "http://www.example.com/", "", "application/octet-stream"}, |
| 130 "http://www.example.com", | 125 {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, |
| 131 "", "application/octet-stream" }, | 126 "http://www.example.com/foo", "", "application/octet-stream"}, |
| 132 { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1, | 127 {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, |
| 133 "http://www.example.com/", | 128 "http://www.example.com/foocrx", "", "application/octet-stream"}, |
| 134 "", "application/octet-stream" }, | 129 {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, |
| 135 { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1, | 130 "http://www.example.com/foo.crx.blech", "", "application/octet-stream"}, |
| 136 "http://www.example.com/foo", | |
| 137 "", "application/octet-stream" }, | |
| 138 { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1, | |
| 139 "http://www.example.com/foocrx", | |
| 140 "", "application/octet-stream" }, | |
| 141 { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1, | |
| 142 "http://www.example.com/foo.crx.blech", | |
| 143 "", "application/octet-stream" }, | |
| 144 | 131 |
| 145 // wrong magic | 132 // wrong magic |
| 146 { "Cr24\x02\x00\x00\x01", sizeof("Cr24\x02\x00\x00\x01")-1, | 133 {"Cr24\x02\x00\x00\x01", sizeof("Cr24\x02\x00\x00\x01") - 1, |
| 147 "http://www.example.com/foo.crx?monkey", | 134 "http://www.example.com/foo.crx?monkey", "", "application/octet-stream"}, |
| 148 "", "application/octet-stream" }, | 135 {"PADDING_Cr24\x02\x00\x00\x00", |
| 149 { "PADDING_Cr24\x02\x00\x00\x00", sizeof("PADDING_Cr24\x02\x00\x00\x00")-1, | 136 sizeof("PADDING_Cr24\x02\x00\x00\x00") - 1, |
| 150 "http://www.example.com/foo.crx?monkey", | 137 "http://www.example.com/foo.crx?monkey", "", "application/octet-stream"}, |
| 151 "", "application/octet-stream" }, | |
| 152 }; | 138 }; |
| 153 | 139 |
| 154 TestArray(tests, arraysize(tests)); | 140 TestArray(tests, arraysize(tests)); |
| 155 } | 141 } |
| 156 | 142 |
| 157 TEST(MimeSnifferTest, MozillaCompatibleTest) { | 143 TEST(MimeSnifferTest, MozillaCompatibleTest) { |
| 158 SnifferTest tests[] = { | 144 SnifferTest tests[] = { |
| 159 { " \n <hTmL>\n <hea", sizeof(" \n <hTmL>\n <hea")-1, | 145 {" \n <hTmL>\n <hea", sizeof(" \n <hTmL>\n <hea") - 1, |
| 160 "http://www.example.com/", | 146 "http://www.example.com/", "", "text/html"}, |
| 161 "", "text/html" }, | 147 {" \n <hTmL>\n <hea", sizeof(" \n <hTmL>\n <hea") - 1, |
| 162 { " \n <hTmL>\n <hea", sizeof(" \n <hTmL>\n <hea")-1, | 148 "http://www.example.com/", "text/plain", "text/plain"}, |
| 163 "http://www.example.com/", | 149 {"BMjlakdsfk", sizeof("BMjlakdsfk") - 1, "http://www.example.com/foo", "", |
| 164 "text/plain", "text/plain" }, | 150 "image/bmp"}, |
| 165 { "BMjlakdsfk", sizeof("BMjlakdsfk")-1, | 151 {"\x00\x00\x30\x00", sizeof("\x00\x00\x30\x00") - 1, |
| 166 "http://www.example.com/foo", | 152 "http://www.example.com/favicon.ico", "", "application/octet-stream"}, |
| 167 "", "image/bmp" }, | 153 {"#!/bin/sh\nls /\n", sizeof("#!/bin/sh\nls /\n") - 1, |
| 168 { "\x00\x00\x30\x00", sizeof("\x00\x00\x30\x00")-1, | 154 "http://www.example.com/foo", "", "text/plain"}, |
| 169 "http://www.example.com/favicon.ico", | 155 {"From: Fred\nTo: Bob\n\nHi\n.\n", |
| 170 "", "application/octet-stream" }, | 156 sizeof("From: Fred\nTo: Bob\n\nHi\n.\n") - 1, |
| 171 { "#!/bin/sh\nls /\n", sizeof("#!/bin/sh\nls /\n")-1, | 157 "http://www.example.com/foo", "", "text/plain"}, |
| 172 "http://www.example.com/foo", | 158 {"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", |
| 173 "", "text/plain" }, | 159 sizeof("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") - 1, |
| 174 { "From: Fred\nTo: Bob\n\nHi\n.\n", | 160 "http://www.example.com/foo", "", "text/xml"}, |
| 175 sizeof("From: Fred\nTo: Bob\n\nHi\n.\n")-1, | 161 {"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", |
| 176 "http://www.example.com/foo", | 162 sizeof("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") - 1, |
| 177 "", "text/plain" }, | 163 "http://www.example.com/foo", "application/octet-stream", |
| 178 { "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", | 164 "application/octet-stream"}, |
| 179 sizeof("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")-1, | |
| 180 "http://www.example.com/foo", | |
| 181 "", "text/xml" }, | |
| 182 { "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", | |
| 183 sizeof("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")-1, | |
| 184 "http://www.example.com/foo", | |
| 185 "application/octet-stream", "application/octet-stream" }, | |
| 186 }; | 165 }; |
| 187 | 166 |
| 188 TestArray(tests, arraysize(tests)); | 167 TestArray(tests, arraysize(tests)); |
| 189 } | 168 } |
| 190 | 169 |
| 191 TEST(MimeSnifferTest, DontAllowPrivilegeEscalationTest) { | 170 TEST(MimeSnifferTest, DontAllowPrivilegeEscalationTest) { |
| 192 SnifferTest tests[] = { | 171 SnifferTest tests[] = { |
| 193 { "GIF87a\n<html>\n<body>" | 172 {"GIF87a\n<html>\n<body>" |
| 194 "<script>alert('haxorzed');\n</script>" | 173 "<script>alert('haxorzed');\n</script>" |
| 195 "</body></html>\n", | 174 "</body></html>\n", |
| 196 sizeof("GIF87a\n<html>\n<body>" | 175 sizeof( |
| 197 "<script>alert('haxorzed');\n</script>" | 176 "GIF87a\n<html>\n<body>" |
| 198 "</body></html>\n")-1, | 177 "<script>alert('haxorzed');\n</script>" |
| 199 "http://www.example.com/foo", | 178 "</body></html>\n") - |
| 200 "", "image/gif" }, | 179 1, |
| 201 { "GIF87a\n<html>\n<body>" | 180 "http://www.example.com/foo", "", "image/gif"}, |
| 202 "<script>alert('haxorzed');\n</script>" | 181 {"GIF87a\n<html>\n<body>" |
| 203 "</body></html>\n", | 182 "<script>alert('haxorzed');\n</script>" |
| 204 sizeof("GIF87a\n<html>\n<body>" | 183 "</body></html>\n", |
| 205 "<script>alert('haxorzed');\n</script>" | 184 sizeof( |
| 206 "</body></html>\n")-1, | 185 "GIF87a\n<html>\n<body>" |
| 207 "http://www.example.com/foo?q=ttt.html", | 186 "<script>alert('haxorzed');\n</script>" |
| 208 "", "image/gif" }, | 187 "</body></html>\n") - |
| 209 { "GIF87a\n<html>\n<body>" | 188 1, |
| 210 "<script>alert('haxorzed');\n</script>" | 189 "http://www.example.com/foo?q=ttt.html", "", "image/gif"}, |
| 211 "</body></html>\n", | 190 {"GIF87a\n<html>\n<body>" |
| 212 sizeof("GIF87a\n<html>\n<body>" | 191 "<script>alert('haxorzed');\n</script>" |
| 213 "<script>alert('haxorzed');\n</script>" | 192 "</body></html>\n", |
| 214 "</body></html>\n")-1, | 193 sizeof( |
| 215 "http://www.example.com/foo#ttt.html", | 194 "GIF87a\n<html>\n<body>" |
| 216 "", "image/gif" }, | 195 "<script>alert('haxorzed');\n</script>" |
| 217 { "a\n<html>\n<body>" | 196 "</body></html>\n") - |
| 218 "<script>alert('haxorzed');\n</script>" | 197 1, |
| 219 "</body></html>\n", | 198 "http://www.example.com/foo#ttt.html", "", "image/gif"}, |
| 220 sizeof("a\n<html>\n<body>" | 199 {"a\n<html>\n<body>" |
| 221 "<script>alert('haxorzed');\n</script>" | 200 "<script>alert('haxorzed');\n</script>" |
| 222 "</body></html>\n")-1, | 201 "</body></html>\n", |
| 223 "http://www.example.com/foo", | 202 sizeof( |
| 224 "", "text/plain" }, | 203 "a\n<html>\n<body>" |
| 225 { "a\n<html>\n<body>" | 204 "<script>alert('haxorzed');\n</script>" |
| 226 "<script>alert('haxorzed');\n</script>" | 205 "</body></html>\n") - |
| 227 "</body></html>\n", | 206 1, |
| 228 sizeof("a\n<html>\n<body>" | 207 "http://www.example.com/foo", "", "text/plain"}, |
| 229 "<script>alert('haxorzed');\n</script>" | 208 {"a\n<html>\n<body>" |
| 230 "</body></html>\n")-1, | 209 "<script>alert('haxorzed');\n</script>" |
| 231 "http://www.example.com/foo?q=ttt.html", | 210 "</body></html>\n", |
| 232 "", "text/plain" }, | 211 sizeof( |
| 233 { "a\n<html>\n<body>" | 212 "a\n<html>\n<body>" |
| 234 "<script>alert('haxorzed');\n</script>" | 213 "<script>alert('haxorzed');\n</script>" |
| 235 "</body></html>\n", | 214 "</body></html>\n") - |
| 236 sizeof("a\n<html>\n<body>" | 215 1, |
| 237 "<script>alert('haxorzed');\n</script>" | 216 "http://www.example.com/foo?q=ttt.html", "", "text/plain"}, |
| 238 "</body></html>\n")-1, | 217 {"a\n<html>\n<body>" |
| 239 "http://www.example.com/foo#ttt.html", | 218 "<script>alert('haxorzed');\n</script>" |
| 240 "", "text/plain" }, | 219 "</body></html>\n", |
| 241 { "a\n<html>\n<body>" | 220 sizeof( |
| 242 "<script>alert('haxorzed');\n</script>" | 221 "a\n<html>\n<body>" |
| 243 "</body></html>\n", | 222 "<script>alert('haxorzed');\n</script>" |
| 244 sizeof("a\n<html>\n<body>" | 223 "</body></html>\n") - |
| 245 "<script>alert('haxorzed');\n</script>" | 224 1, |
| 246 "</body></html>\n")-1, | 225 "http://www.example.com/foo#ttt.html", "", "text/plain"}, |
| 247 "http://www.example.com/foo.html", | 226 {"a\n<html>\n<body>" |
| 248 "", "text/plain" }, | 227 "<script>alert('haxorzed');\n</script>" |
| 228 "</body></html>\n", | |
| 229 sizeof( | |
| 230 "a\n<html>\n<body>" | |
| 231 "<script>alert('haxorzed');\n</script>" | |
| 232 "</body></html>\n") - | |
| 233 1, | |
|
mmenke
2014/10/10 18:12:39
Confusing indentation here, methinks.
| |
| 234 "http://www.example.com/foo.html", "", "text/plain"}, | |
| 249 }; | 235 }; |
| 250 | 236 |
| 251 TestArray(tests, arraysize(tests)); | 237 TestArray(tests, arraysize(tests)); |
| 252 } | 238 } |
| 253 | 239 |
| 254 TEST(MimeSnifferTest, UnicodeTest) { | 240 TEST(MimeSnifferTest, UnicodeTest) { |
| 255 SnifferTest tests[] = { | 241 SnifferTest tests[] = { |
| 256 { "\xEF\xBB\xBF" "Hi there", sizeof("\xEF\xBB\xBF" "Hi there")-1, | 242 {"\xEF\xBB\xBF" |
| 257 "http://www.example.com/foo", | 243 "Hi there", |
| 258 "", "text/plain" }, | 244 sizeof( |
| 259 { "\xEF\xBB\xBF\xED\x7A\xAD\x7A\x0D\x79", | 245 "\xEF\xBB\xBF" |
| 260 sizeof("\xEF\xBB\xBF\xED\x7A\xAD\x7A\x0D\x79")-1, | 246 "Hi there") - |
| 261 "http://www.example.com/foo", | 247 1, |
| 262 "", "text/plain" }, | 248 "http://www.example.com/foo", "", "text/plain"}, |
| 263 { "\xFE\xFF\xD0\xA5\xD0\xBE\xD0\xBB\xD1\x83\xD0\xB9", | 249 {"\xEF\xBB\xBF\xED\x7A\xAD\x7A\x0D\x79", |
| 264 sizeof("\xFE\xFF\xD0\xA5\xD0\xBE\xD0\xBB\xD1\x83\xD0\xB9")-1, | 250 sizeof("\xEF\xBB\xBF\xED\x7A\xAD\x7A\x0D\x79") - 1, |
| 265 "http://www.example.com/foo", | 251 "http://www.example.com/foo", "", "text/plain"}, |
| 266 "", "text/plain" }, | 252 {"\xFE\xFF\xD0\xA5\xD0\xBE\xD0\xBB\xD1\x83\xD0\xB9", |
| 267 { "\xFE\xFF\x00\x41\x00\x20\xD8\x00\xDC\x00\xD8\x00\xDC\x01", | 253 sizeof("\xFE\xFF\xD0\xA5\xD0\xBE\xD0\xBB\xD1\x83\xD0\xB9") - 1, |
| 268 sizeof("\xFE\xFF\x00\x41\x00\x20\xD8\x00\xDC\x00\xD8\x00\xDC\x01")-1, | 254 "http://www.example.com/foo", "", "text/plain"}, |
| 269 "http://www.example.com/foo", | 255 {"\xFE\xFF\x00\x41\x00\x20\xD8\x00\xDC\x00\xD8\x00\xDC\x01", |
| 270 "", "text/plain" }, | 256 sizeof("\xFE\xFF\x00\x41\x00\x20\xD8\x00\xDC\x00\xD8\x00\xDC\x01") - 1, |
| 257 "http://www.example.com/foo", "", "text/plain"}, | |
| 271 }; | 258 }; |
| 272 | 259 |
| 273 TestArray(tests, arraysize(tests)); | 260 TestArray(tests, arraysize(tests)); |
| 274 } | 261 } |
| 275 | 262 |
| 276 TEST(MimeSnifferTest, FlashTest) { | 263 TEST(MimeSnifferTest, FlashTest) { |
| 277 SnifferTest tests[] = { | 264 SnifferTest tests[] = { |
| 278 { "CWSdd\x00\xB3", sizeof("CWSdd\x00\xB3")-1, | 265 {"CWSdd\x00\xB3", sizeof("CWSdd\x00\xB3") - 1, |
| 279 "http://www.example.com/foo", | 266 "http://www.example.com/foo", "", "application/octet-stream"}, |
| 280 "", "application/octet-stream" }, | 267 {"FLVjdkl*(#)0sdj\x00", sizeof("FLVjdkl*(#)0sdj\x00") - 1, |
| 281 { "FLVjdkl*(#)0sdj\x00", sizeof("FLVjdkl*(#)0sdj\x00")-1, | 268 "http://www.example.com/foo?q=ttt.swf", "", "application/octet-stream"}, |
| 282 "http://www.example.com/foo?q=ttt.swf", | 269 {"FWS3$9\r\b\x00", sizeof("FWS3$9\r\b\x00") - 1, |
| 283 "", "application/octet-stream" }, | 270 "http://www.example.com/foo#ttt.swf", "", "application/octet-stream"}, |
| 284 { "FWS3$9\r\b\x00", sizeof("FWS3$9\r\b\x00")-1, | 271 {"FLVjdkl*(#)0sdj", sizeof("FLVjdkl*(#)0sdj") - 1, |
| 285 "http://www.example.com/foo#ttt.swf", | 272 "http://www.example.com/foo.swf", "", "text/plain"}, |
| 286 "", "application/octet-stream" }, | 273 {"FLVjdkl*(#)0s\x01dj", sizeof("FLVjdkl*(#)0s\x01dj") - 1, |
| 287 { "FLVjdkl*(#)0sdj", sizeof("FLVjdkl*(#)0sdj")-1, | 274 "http://www.example.com/foo/bar.swf", "", "application/octet-stream"}, |
| 288 "http://www.example.com/foo.swf", | 275 {"FWS3$9\r\b\x1A", sizeof("FWS3$9\r\b\x1A") - 1, |
| 289 "", "text/plain" }, | 276 "http://www.example.com/foo.swf?clickTAG=http://www.adnetwork.com/bar", |
| 290 { "FLVjdkl*(#)0s\x01dj", sizeof("FLVjdkl*(#)0s\x01dj")-1, | 277 "", "application/octet-stream"}, |
| 291 "http://www.example.com/foo/bar.swf", | 278 {"FWS3$9\r\x1C\b", sizeof("FWS3$9\r\x1C\b") - 1, |
| 292 "", "application/octet-stream" }, | 279 "http://www.example.com/foo.swf?clickTAG=http://www.adnetwork.com/bar", |
| 293 { "FWS3$9\r\b\x1A", sizeof("FWS3$9\r\b\x1A")-1, | 280 "text/plain", "application/octet-stream"}, |
| 294 "http://www.example.com/foo.swf?clickTAG=http://www.adnetwork.com/bar", | |
| 295 "", "application/octet-stream" }, | |
| 296 { "FWS3$9\r\x1C\b", sizeof("FWS3$9\r\x1C\b")-1, | |
| 297 "http://www.example.com/foo.swf?clickTAG=http://www.adnetwork.com/bar", | |
| 298 "text/plain", "application/octet-stream" }, | |
| 299 }; | 281 }; |
| 300 | 282 |
| 301 TestArray(tests, arraysize(tests)); | 283 TestArray(tests, arraysize(tests)); |
| 302 } | 284 } |
| 303 | 285 |
| 304 TEST(MimeSnifferTest, XMLTest) { | 286 TEST(MimeSnifferTest, XMLTest) { |
| 305 // An easy feed to identify. | 287 // An easy feed to identify. |
| 306 EXPECT_EQ("application/atom+xml", | 288 EXPECT_EQ("application/atom+xml", |
| 307 SniffMimeType("<?xml?><feed", std::string(), "text/xml")); | 289 SniffMimeType("<?xml?><feed", std::string(), "text/xml")); |
| 308 // Don't sniff out of plain text. | 290 // Don't sniff out of plain text. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 366 // Test content which is >= 1024 bytes, and includes no open angle bracket. | 348 // Test content which is >= 1024 bytes, and includes no open angle bracket. |
| 367 // http://code.google.com/p/chromium/issues/detail?id=3521 | 349 // http://code.google.com/p/chromium/issues/detail?id=3521 |
| 368 TEST(MimeSnifferTest, XMLTestLargeNoAngledBracket) { | 350 TEST(MimeSnifferTest, XMLTestLargeNoAngledBracket) { |
| 369 // Make a large input, with 1024 bytes of "x". | 351 // Make a large input, with 1024 bytes of "x". |
| 370 std::string content; | 352 std::string content; |
| 371 content.resize(1024); | 353 content.resize(1024); |
| 372 std::fill(content.begin(), content.end(), 'x'); | 354 std::fill(content.begin(), content.end(), 'x'); |
| 373 | 355 |
| 374 // content.size() >= 1024 so the sniff is unambiguous. | 356 // content.size() >= 1024 so the sniff is unambiguous. |
| 375 std::string mime_type; | 357 std::string mime_type; |
| 376 EXPECT_TRUE(SniffMimeType(content.data(), content.size(), GURL(), | 358 EXPECT_TRUE(SniffMimeType( |
| 377 "text/xml", &mime_type)); | 359 content.data(), content.size(), GURL(), "text/xml", &mime_type)); |
| 378 EXPECT_EQ("text/xml", mime_type); | 360 EXPECT_EQ("text/xml", mime_type); |
| 379 } | 361 } |
| 380 | 362 |
| 381 // Test content which is >= 1024 bytes, and includes a binary looking byte. | 363 // Test content which is >= 1024 bytes, and includes a binary looking byte. |
| 382 // http://code.google.com/p/chromium/issues/detail?id=15314 | 364 // http://code.google.com/p/chromium/issues/detail?id=15314 |
| 383 TEST(MimeSnifferTest, LooksBinary) { | 365 TEST(MimeSnifferTest, LooksBinary) { |
| 384 // Make a large input, with 1024 bytes of "x" and 1 byte of 0x01. | 366 // Make a large input, with 1024 bytes of "x" and 1 byte of 0x01. |
| 385 std::string content; | 367 std::string content; |
| 386 content.resize(1024); | 368 content.resize(1024); |
| 387 std::fill(content.begin(), content.end(), 'x'); | 369 std::fill(content.begin(), content.end(), 'x'); |
| 388 content[1000] = 0x01; | 370 content[1000] = 0x01; |
| 389 | 371 |
| 390 // content.size() >= 1024 so the sniff is unambiguous. | 372 // content.size() >= 1024 so the sniff is unambiguous. |
| 391 std::string mime_type; | 373 std::string mime_type; |
| 392 EXPECT_TRUE(SniffMimeType(content.data(), content.size(), GURL(), | 374 EXPECT_TRUE(SniffMimeType( |
| 393 "text/plain", &mime_type)); | 375 content.data(), content.size(), GURL(), "text/plain", &mime_type)); |
| 394 EXPECT_EQ("application/octet-stream", mime_type); | 376 EXPECT_EQ("application/octet-stream", mime_type); |
| 395 } | 377 } |
| 396 | 378 |
| 397 TEST(MimeSnifferTest, OfficeTest) { | 379 TEST(MimeSnifferTest, OfficeTest) { |
| 398 SnifferTest tests[] = { | 380 SnifferTest tests[] = { |
| 399 // Check for URLs incorrectly reported as Microsoft Office files. | 381 // Check for URLs incorrectly reported as Microsoft Office files. |
| 400 { "Hi there", | 382 {"Hi there", sizeof("Hi there") - 1, "http://www.example.com/foo.doc", |
| 401 sizeof("Hi there")-1, | 383 "application/msword", "application/octet-stream"}, |
| 402 "http://www.example.com/foo.doc", | 384 {"Hi there", sizeof("Hi there") - 1, "http://www.example.com/foo.xls", |
| 403 "application/msword", "application/octet-stream" }, | 385 "application/vnd.ms-excel", "application/octet-stream"}, |
| 404 { "Hi there", | 386 {"Hi there", sizeof("Hi there") - 1, "http://www.example.com/foo.ppt", |
| 405 sizeof("Hi there")-1, | 387 "application/vnd.ms-powerpoint", "application/octet-stream"}, |
| 406 "http://www.example.com/foo.xls", | 388 // Check for Microsoft Office files incorrectly reported as text. |
| 407 "application/vnd.ms-excel", "application/octet-stream" }, | 389 {"\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" |
| 408 { "Hi there", | 390 "Hi there", |
| 409 sizeof("Hi there")-1, | 391 sizeof( |
| 410 "http://www.example.com/foo.ppt", | 392 "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" |
| 411 "application/vnd.ms-powerpoint", "application/octet-stream" }, | 393 "Hi there") - |
| 412 // Check for Microsoft Office files incorrectly reported as text. | 394 1, |
| 413 { "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" "Hi there", | 395 "http://www.example.com/foo.doc", "text/plain", "application/msword"}, |
| 414 sizeof("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" "Hi there")-1, | 396 {"PK\x03\x04" |
| 415 "http://www.example.com/foo.doc", | 397 "Hi there", |
| 416 "text/plain", "application/msword" }, | 398 sizeof( |
| 417 { "PK\x03\x04" "Hi there", | 399 "PK\x03\x04" |
| 418 sizeof("PK\x03\x04" "Hi there")-1, | 400 "Hi there") - |
| 419 "http://www.example.com/foo.doc", | 401 1, |
| 420 "text/plain", | 402 "http://www.example.com/foo.doc", "text/plain", |
| 421 "application/vnd.openxmlformats-officedocument." | 403 "application/vnd.openxmlformats-officedocument." |
| 422 "wordprocessingml.document" }, | 404 "wordprocessingml.document"}, |
| 423 { "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" "Hi there", | 405 {"\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" |
| 424 sizeof("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" "Hi there")-1, | 406 "Hi there", |
| 425 "http://www.example.com/foo.xls", | 407 sizeof( |
| 426 "text/plain", "application/vnd.ms-excel" }, | 408 "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" |
| 427 { "PK\x03\x04" "Hi there", | 409 "Hi there") - |
| 428 sizeof("PK\x03\x04" "Hi there")-1, | 410 1, |
| 429 "http://www.example.com/foo.xls", | 411 "http://www.example.com/foo.xls", "text/plain", |
| 430 "text/plain", | 412 "application/vnd.ms-excel"}, |
| 431 "application/vnd.openxmlformats-officedocument." | 413 {"PK\x03\x04" |
| 432 "spreadsheetml.sheet" }, | 414 "Hi there", |
| 433 { "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" "Hi there", | 415 sizeof( |
| 434 sizeof("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" "Hi there")-1, | 416 "PK\x03\x04" |
| 435 "http://www.example.com/foo.ppt", | 417 "Hi there") - |
| 436 "text/plain", "application/vnd.ms-powerpoint" }, | 418 1, |
|
mmenke
2014/10/10 18:12:39
Line split completely not needed.
| |
| 437 { "PK\x03\x04" "Hi there", | 419 "http://www.example.com/foo.xls", "text/plain", |
| 438 sizeof("PK\x03\x04" "Hi there")-1, | 420 "application/vnd.openxmlformats-officedocument." |
| 439 "http://www.example.com/foo.ppt", | 421 "spreadsheetml.sheet"}, |
| 440 "text/plain", | 422 {"\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" |
| 441 "application/vnd.openxmlformats-officedocument." | 423 "Hi there", |
| 442 "presentationml.presentation" }, | 424 sizeof( |
| 425 "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" | |
| 426 "Hi there") - | |
| 427 1, | |
| 428 "http://www.example.com/foo.ppt", "text/plain", | |
| 429 "application/vnd.ms-powerpoint"}, | |
| 430 {"PK\x03\x04" | |
| 431 "Hi there", | |
| 432 sizeof( | |
| 433 "PK\x03\x04" | |
| 434 "Hi there") - | |
| 435 1, | |
| 436 "http://www.example.com/foo.ppt", "text/plain", | |
| 437 "application/vnd.openxmlformats-officedocument." | |
| 438 "presentationml.presentation"}, | |
| 443 }; | 439 }; |
| 444 | 440 |
| 445 TestArray(tests, arraysize(tests)); | 441 TestArray(tests, arraysize(tests)); |
| 446 } | 442 } |
| 447 | 443 |
| 448 // TODO(thestig) Add more tests for other AV formats. Add another test case for | 444 // TODO(thestig) Add more tests for other AV formats. Add another test case for |
| 449 // RAW images. | 445 // RAW images. |
| 450 TEST(MimeSnifferTest, AudioVideoTest) { | 446 TEST(MimeSnifferTest, AudioVideoTest) { |
| 451 std::string mime_type; | 447 std::string mime_type; |
| 452 const char kFlacTestData[] = | 448 const char kFlacTestData[] = |
| 453 "fLaC\x00\x00\x00\x22\x12\x00\x12\x00\x00\x00\x00\x00"; | 449 "fLaC\x00\x00\x00\x22\x12\x00\x12\x00\x00\x00\x00\x00"; |
| 454 EXPECT_TRUE(SniffMimeTypeFromLocalData(kFlacTestData, | 450 EXPECT_TRUE(SniffMimeTypeFromLocalData( |
| 455 sizeof(kFlacTestData), | 451 kFlacTestData, sizeof(kFlacTestData), &mime_type)); |
| 456 &mime_type)); | |
| 457 EXPECT_EQ("audio/x-flac", mime_type); | 452 EXPECT_EQ("audio/x-flac", mime_type); |
| 458 mime_type.clear(); | 453 mime_type.clear(); |
| 459 | 454 |
| 460 const char kWMATestData[] = | 455 const char kWMATestData[] = |
| 461 "\x30\x26\xb2\x75\x8e\x66\xcf\x11\xa6\xd9\x00\xaa\x00\x62\xce\x6c"; | 456 "\x30\x26\xb2\x75\x8e\x66\xcf\x11\xa6\xd9\x00\xaa\x00\x62\xce\x6c"; |
| 462 EXPECT_TRUE(SniffMimeTypeFromLocalData(kWMATestData, | 457 EXPECT_TRUE(SniffMimeTypeFromLocalData( |
| 463 sizeof(kWMATestData), | 458 kWMATestData, sizeof(kWMATestData), &mime_type)); |
| 464 &mime_type)); | |
| 465 EXPECT_EQ("video/x-ms-asf", mime_type); | 459 EXPECT_EQ("video/x-ms-asf", mime_type); |
| 466 mime_type.clear(); | 460 mime_type.clear(); |
| 467 | 461 |
| 468 // mp4a, m4b, m4p, and alac extension files which share the same container | 462 // mp4a, m4b, m4p, and alac extension files which share the same container |
| 469 // format. | 463 // format. |
| 470 const char kMP4TestData[] = | 464 const char kMP4TestData[] = |
| 471 "\x00\x00\x00\x20\x66\x74\x79\x70\x4d\x34\x41\x20\x00\x00\x00\x00"; | 465 "\x00\x00\x00\x20\x66\x74\x79\x70\x4d\x34\x41\x20\x00\x00\x00\x00"; |
| 472 EXPECT_TRUE(SniffMimeTypeFromLocalData(kMP4TestData, | 466 EXPECT_TRUE(SniffMimeTypeFromLocalData( |
| 473 sizeof(kMP4TestData), | 467 kMP4TestData, sizeof(kMP4TestData), &mime_type)); |
| 474 &mime_type)); | |
| 475 EXPECT_EQ("video/mp4", mime_type); | 468 EXPECT_EQ("video/mp4", mime_type); |
| 476 mime_type.clear(); | 469 mime_type.clear(); |
| 477 | 470 |
| 478 const char kAACTestData[] = | 471 const char kAACTestData[] = |
| 479 "\xff\xf1\x50\x80\x02\x20\xb0\x23\x0a\x83\x20\x7d\x61\x90\x3e\xb1"; | 472 "\xff\xf1\x50\x80\x02\x20\xb0\x23\x0a\x83\x20\x7d\x61\x90\x3e\xb1"; |
| 480 EXPECT_TRUE(SniffMimeTypeFromLocalData(kAACTestData, | 473 EXPECT_TRUE(SniffMimeTypeFromLocalData( |
| 481 sizeof(kAACTestData), | 474 kAACTestData, sizeof(kAACTestData), &mime_type)); |
| 482 &mime_type)); | |
| 483 EXPECT_EQ("audio/mpeg", mime_type); | 475 EXPECT_EQ("audio/mpeg", mime_type); |
| 484 mime_type.clear(); | 476 mime_type.clear(); |
| 485 } | 477 } |
| 486 | 478 |
| 487 } // namespace net | 479 } // namespace net |
| OLD | NEW |