| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "net/base/filename_util.h" | |
| 6 | |
| 7 #include "base/files/file_path.h" | |
| 8 #include "base/files/file_util.h" | |
| 9 #include "base/strings/string_util.h" | |
| 10 #include "base/strings/utf_string_conversions.h" | |
| 11 #include "base/test/test_file_util.h" | |
| 12 #include "testing/gtest/include/gtest/gtest.h" | |
| 13 #include "url/gurl.h" | |
| 14 | |
| 15 namespace net { | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 struct FileCase { | |
| 20 const wchar_t* file; | |
| 21 const char* url; | |
| 22 }; | |
| 23 | |
| 24 struct GenerateFilenameCase { | |
| 25 int lineno; | |
| 26 const char* url; | |
| 27 const char* content_disp_header; | |
| 28 const char* referrer_charset; | |
| 29 const char* suggested_filename; | |
| 30 const char* mime_type; | |
| 31 const wchar_t* default_filename; | |
| 32 const wchar_t* expected_filename; | |
| 33 }; | |
| 34 | |
| 35 // The expected filenames are coded as wchar_t for convenience. | |
| 36 std::wstring FilePathAsWString(const base::FilePath& path) { | |
| 37 #if defined(OS_WIN) | |
| 38 return path.value(); | |
| 39 #else | |
| 40 return base::UTF8ToWide(path.value()); | |
| 41 #endif | |
| 42 } | |
| 43 base::FilePath WStringAsFilePath(const std::wstring& str) { | |
| 44 #if defined(OS_WIN) | |
| 45 return base::FilePath(str); | |
| 46 #else | |
| 47 return base::FilePath(base::WideToUTF8(str)); | |
| 48 #endif | |
| 49 } | |
| 50 | |
| 51 std::string GetLocaleWarningString() { | |
| 52 #if defined(OS_POSIX) && !defined(OS_ANDROID) | |
| 53 // The generate filename tests can fail on certain OS_POSIX platforms when | |
| 54 // LC_CTYPE is not "utf8" or "utf-8" because some of the string conversions | |
| 55 // fail. | |
| 56 // This warning text is appended to any test failures to save people time if | |
| 57 // this happens to be the cause of failure :) | |
| 58 // Note: some platforms (MACOSX, Chromecast) don't have this problem: | |
| 59 // setlocale returns "c" but it functions as utf8. And Android doesn't | |
| 60 // have setlocale at all. | |
| 61 std::string locale = setlocale(LC_CTYPE, NULL); | |
| 62 return " this test may have failed because the current LC_CTYPE locale is " | |
| 63 "not utf8 (currently set to " + | |
| 64 locale + ")"; | |
| 65 #else | |
| 66 return ""; | |
| 67 #endif | |
| 68 } | |
| 69 | |
| 70 void RunGenerateFileNameTestCase(const GenerateFilenameCase* test_case) { | |
| 71 std::string default_filename(base::WideToUTF8(test_case->default_filename)); | |
| 72 base::FilePath file_path = GenerateFileName( | |
| 73 GURL(test_case->url), test_case->content_disp_header, | |
| 74 test_case->referrer_charset, test_case->suggested_filename, | |
| 75 test_case->mime_type, default_filename); | |
| 76 EXPECT_EQ(test_case->expected_filename, FilePathAsWString(file_path)) | |
| 77 << "test case at line number: " << test_case->lineno << "; " | |
| 78 << GetLocaleWarningString(); | |
| 79 } | |
| 80 | |
| 81 } // namespace | |
| 82 | |
| 83 static const base::FilePath::CharType* kSafePortableBasenames[] = { | |
| 84 FILE_PATH_LITERAL("a"), | |
| 85 FILE_PATH_LITERAL("a.txt"), | |
| 86 FILE_PATH_LITERAL("a b.txt"), | |
| 87 FILE_PATH_LITERAL("a-b.txt"), | |
| 88 FILE_PATH_LITERAL("My Computer"), | |
| 89 }; | |
| 90 | |
| 91 static const base::FilePath::CharType* kUnsafePortableBasenames[] = { | |
| 92 FILE_PATH_LITERAL(""), | |
| 93 FILE_PATH_LITERAL("."), | |
| 94 FILE_PATH_LITERAL(".."), | |
| 95 FILE_PATH_LITERAL("..."), | |
| 96 FILE_PATH_LITERAL("con"), | |
| 97 FILE_PATH_LITERAL("con.zip"), | |
| 98 FILE_PATH_LITERAL("NUL"), | |
| 99 FILE_PATH_LITERAL("NUL.zip"), | |
| 100 FILE_PATH_LITERAL(".a"), | |
| 101 FILE_PATH_LITERAL("a."), | |
| 102 FILE_PATH_LITERAL("a\"a"), | |
| 103 FILE_PATH_LITERAL("a<a"), | |
| 104 FILE_PATH_LITERAL("a>a"), | |
| 105 FILE_PATH_LITERAL("a?a"), | |
| 106 FILE_PATH_LITERAL("a/"), | |
| 107 FILE_PATH_LITERAL("a\\"), | |
| 108 FILE_PATH_LITERAL("a "), | |
| 109 FILE_PATH_LITERAL("a . ."), | |
| 110 FILE_PATH_LITERAL(" Computer"), | |
| 111 FILE_PATH_LITERAL("My Computer.{a}"), | |
| 112 FILE_PATH_LITERAL("My Computer.{20D04FE0-3AEA-1069-A2D8-08002B30309D}"), | |
| 113 #if !defined(OS_WIN) | |
| 114 FILE_PATH_LITERAL("a\\a"), | |
| 115 #endif | |
| 116 }; | |
| 117 | |
| 118 static const base::FilePath::CharType* kSafePortableRelativePaths[] = { | |
| 119 FILE_PATH_LITERAL("a/a"), | |
| 120 #if defined(OS_WIN) | |
| 121 FILE_PATH_LITERAL("a\\a"), | |
| 122 #endif | |
| 123 }; | |
| 124 | |
| 125 TEST(FilenameUtilTest, IsSafePortablePathComponent) { | |
| 126 for (size_t i = 0; i < arraysize(kSafePortableBasenames); ++i) { | |
| 127 EXPECT_TRUE( | |
| 128 IsSafePortablePathComponent(base::FilePath(kSafePortableBasenames[i]))) | |
| 129 << kSafePortableBasenames[i]; | |
| 130 } | |
| 131 for (size_t i = 0; i < arraysize(kUnsafePortableBasenames); ++i) { | |
| 132 EXPECT_FALSE(IsSafePortablePathComponent( | |
| 133 base::FilePath(kUnsafePortableBasenames[i]))) | |
| 134 << kUnsafePortableBasenames[i]; | |
| 135 } | |
| 136 for (size_t i = 0; i < arraysize(kSafePortableRelativePaths); ++i) { | |
| 137 EXPECT_FALSE(IsSafePortablePathComponent( | |
| 138 base::FilePath(kSafePortableRelativePaths[i]))) | |
| 139 << kSafePortableRelativePaths[i]; | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 TEST(FilenameUtilTest, IsSafePortableRelativePath) { | |
| 144 base::FilePath safe_dirname(FILE_PATH_LITERAL("a")); | |
| 145 for (size_t i = 0; i < arraysize(kSafePortableBasenames); ++i) { | |
| 146 EXPECT_TRUE( | |
| 147 IsSafePortableRelativePath(base::FilePath(kSafePortableBasenames[i]))) | |
| 148 << kSafePortableBasenames[i]; | |
| 149 EXPECT_TRUE(IsSafePortableRelativePath( | |
| 150 safe_dirname.Append(base::FilePath(kSafePortableBasenames[i])))) | |
| 151 << kSafePortableBasenames[i]; | |
| 152 } | |
| 153 for (size_t i = 0; i < arraysize(kSafePortableRelativePaths); ++i) { | |
| 154 EXPECT_TRUE(IsSafePortableRelativePath( | |
| 155 base::FilePath(kSafePortableRelativePaths[i]))) | |
| 156 << kSafePortableRelativePaths[i]; | |
| 157 EXPECT_TRUE(IsSafePortableRelativePath( | |
| 158 safe_dirname.Append(base::FilePath(kSafePortableRelativePaths[i])))) | |
| 159 << kSafePortableRelativePaths[i]; | |
| 160 } | |
| 161 for (size_t i = 0; i < arraysize(kUnsafePortableBasenames); ++i) { | |
| 162 EXPECT_FALSE( | |
| 163 IsSafePortableRelativePath(base::FilePath(kUnsafePortableBasenames[i]))) | |
| 164 << kUnsafePortableBasenames[i]; | |
| 165 if (!base::FilePath::StringType(kUnsafePortableBasenames[i]).empty()) { | |
| 166 EXPECT_FALSE(IsSafePortableRelativePath( | |
| 167 safe_dirname.Append(base::FilePath(kUnsafePortableBasenames[i])))) | |
| 168 << kUnsafePortableBasenames[i]; | |
| 169 } | |
| 170 } | |
| 171 } | |
| 172 | |
| 173 TEST(FilenameUtilTest, FileURLConversion) { | |
| 174 // a list of test file names and the corresponding URLs | |
| 175 const FileCase round_trip_cases[] = { | |
| 176 #if defined(OS_WIN) | |
| 177 {L"C:\\foo\\bar.txt", "file:///C:/foo/bar.txt"}, | |
| 178 {L"\\\\some computer\\foo\\bar.txt", | |
| 179 "file://some%20computer/foo/bar.txt"}, // UNC | |
| 180 {L"D:\\Name;with%some symbols*#", | |
| 181 "file:///D:/Name%3Bwith%25some%20symbols*%23"}, | |
| 182 // issue 14153: To be tested with the OS default codepage other than 1252. | |
| 183 {L"D:\\latin1\\caf\x00E9\x00DD.txt", | |
| 184 "file:///D:/latin1/caf%C3%A9%C3%9D.txt"}, | |
| 185 {L"D:\\otherlatin\\caf\x0119.txt", "file:///D:/otherlatin/caf%C4%99.txt"}, | |
| 186 {L"D:\\greek\\\x03B1\x03B2\x03B3.txt", | |
| 187 "file:///D:/greek/%CE%B1%CE%B2%CE%B3.txt"}, | |
| 188 {L"D:\\Chinese\\\x6240\x6709\x4e2d\x6587\x7f51\x9875.doc", | |
| 189 "file:///D:/Chinese/%E6%89%80%E6%9C%89%E4%B8%AD%E6%96%87%E7%BD%91" | |
| 190 "%E9%A1%B5.doc"}, | |
| 191 {L"D:\\plane1\\\xD835\xDC00\xD835\xDC01.txt", // Math alphabet "AB" | |
| 192 "file:///D:/plane1/%F0%9D%90%80%F0%9D%90%81.txt"}, | |
| 193 #elif defined(OS_POSIX) | |
| 194 {L"/foo/bar.txt", "file:///foo/bar.txt"}, | |
| 195 {L"/foo/BAR.txt", "file:///foo/BAR.txt"}, | |
| 196 {L"/C:/foo/bar.txt", "file:///C:/foo/bar.txt"}, | |
| 197 {L"/foo/bar?.txt", "file:///foo/bar%3F.txt"}, | |
| 198 {L"/some computer/foo/bar.txt", "file:///some%20computer/foo/bar.txt"}, | |
| 199 {L"/Name;with%some symbols*#", "file:///Name%3Bwith%25some%20symbols*%23"}, | |
| 200 {L"/latin1/caf\x00E9\x00DD.txt", "file:///latin1/caf%C3%A9%C3%9D.txt"}, | |
| 201 {L"/otherlatin/caf\x0119.txt", "file:///otherlatin/caf%C4%99.txt"}, | |
| 202 {L"/greek/\x03B1\x03B2\x03B3.txt", "file:///greek/%CE%B1%CE%B2%CE%B3.txt"}, | |
| 203 {L"/Chinese/\x6240\x6709\x4e2d\x6587\x7f51\x9875.doc", | |
| 204 "file:///Chinese/%E6%89%80%E6%9C%89%E4%B8%AD%E6%96%87%E7%BD" | |
| 205 "%91%E9%A1%B5.doc"}, | |
| 206 {L"/plane1/\x1D400\x1D401.txt", // Math alphabet "AB" | |
| 207 "file:///plane1/%F0%9D%90%80%F0%9D%90%81.txt"}, | |
| 208 #endif | |
| 209 }; | |
| 210 | |
| 211 // First, we'll test that we can round-trip all of the above cases of URLs | |
| 212 base::FilePath output; | |
| 213 for (size_t i = 0; i < arraysize(round_trip_cases); i++) { | |
| 214 // convert to the file URL | |
| 215 GURL file_url( | |
| 216 FilePathToFileURL(WStringAsFilePath(round_trip_cases[i].file))); | |
| 217 EXPECT_EQ(round_trip_cases[i].url, file_url.spec()); | |
| 218 | |
| 219 // Back to the filename. | |
| 220 EXPECT_TRUE(FileURLToFilePath(file_url, &output)); | |
| 221 EXPECT_EQ(round_trip_cases[i].file, FilePathAsWString(output)); | |
| 222 } | |
| 223 | |
| 224 // Test that various file: URLs get decoded into the correct file type | |
| 225 FileCase url_cases[] = { | |
| 226 #if defined(OS_WIN) | |
| 227 {L"C:\\foo\\bar.txt", "file:c|/foo\\bar.txt"}, | |
| 228 {L"C:\\foo\\bar.txt", "file:/c:/foo/bar.txt"}, | |
| 229 {L"\\\\foo\\bar.txt", "file://foo\\bar.txt"}, | |
| 230 {L"C:\\foo\\bar.txt", "file:///c:/foo/bar.txt"}, | |
| 231 {L"\\\\foo\\bar.txt", "file:////foo\\bar.txt"}, | |
| 232 {L"\\\\foo\\bar.txt", "file:/foo/bar.txt"}, | |
| 233 {L"\\\\foo\\bar.txt", "file://foo\\bar.txt"}, | |
| 234 {L"C:\\foo\\bar.txt", "file:\\\\\\c:/foo/bar.txt"}, | |
| 235 #elif defined(OS_POSIX) | |
| 236 {L"/c:/foo/bar.txt", "file:/c:/foo/bar.txt"}, | |
| 237 {L"/c:/foo/bar.txt", "file:///c:/foo/bar.txt"}, | |
| 238 {L"/foo/bar.txt", "file:/foo/bar.txt"}, | |
| 239 {L"/c:/foo/bar.txt", "file:\\\\\\c:/foo/bar.txt"}, | |
| 240 {L"/foo/bar.txt", "file:foo/bar.txt"}, | |
| 241 {L"/bar.txt", "file://foo/bar.txt"}, | |
| 242 {L"/foo/bar.txt", "file:///foo/bar.txt"}, | |
| 243 {L"/foo/bar.txt", "file:////foo/bar.txt"}, | |
| 244 {L"/foo/bar.txt", "file:////foo//bar.txt"}, | |
| 245 {L"/foo/bar.txt", "file:////foo///bar.txt"}, | |
| 246 {L"/foo/bar.txt", "file:////foo////bar.txt"}, | |
| 247 {L"/c:/foo/bar.txt", "file:\\\\\\c:/foo/bar.txt"}, | |
| 248 {L"/c:/foo/bar.txt", "file:c:/foo/bar.txt"}, | |
| 249 // We get these wrong because GURL turns back slashes into forward | |
| 250 // slashes. | |
| 251 // {L"/foo%5Cbar.txt", "file://foo\\bar.txt"}, | |
| 252 // {L"/c|/foo%5Cbar.txt", "file:c|/foo\\bar.txt"}, | |
| 253 // {L"/foo%5Cbar.txt", "file://foo\\bar.txt"}, | |
| 254 // {L"/foo%5Cbar.txt", "file:////foo\\bar.txt"}, | |
| 255 // {L"/foo%5Cbar.txt", "file://foo\\bar.txt"}, | |
| 256 #endif | |
| 257 }; | |
| 258 for (size_t i = 0; i < arraysize(url_cases); i++) { | |
| 259 FileURLToFilePath(GURL(url_cases[i].url), &output); | |
| 260 EXPECT_EQ(url_cases[i].file, FilePathAsWString(output)); | |
| 261 } | |
| 262 | |
| 263 // Unfortunately, UTF8ToWide discards invalid UTF8 input. | |
| 264 #ifdef BUG_878908_IS_FIXED | |
| 265 // Test that no conversion happens if the UTF-8 input is invalid, and that | |
| 266 // the input is preserved in UTF-8 | |
| 267 const char invalid_utf8[] = "file:///d:/Blah/\xff.doc"; | |
| 268 const wchar_t invalid_wide[] = L"D:\\Blah\\\xff.doc"; | |
| 269 EXPECT_TRUE(FileURLToFilePath(GURL(std::string(invalid_utf8)), &output)); | |
| 270 EXPECT_EQ(std::wstring(invalid_wide), output); | |
| 271 #endif | |
| 272 | |
| 273 // Test that if a file URL is malformed, we get a failure | |
| 274 EXPECT_FALSE(FileURLToFilePath(GURL("filefoobar"), &output)); | |
| 275 } | |
| 276 | |
| 277 #if defined(OS_WIN) | |
| 278 #define JPEG_EXT L".jpg" | |
| 279 #define HTML_EXT L".htm" | |
| 280 #elif defined(OS_MACOSX) | |
| 281 #define JPEG_EXT L".jpeg" | |
| 282 #define HTML_EXT L".html" | |
| 283 #else | |
| 284 #define JPEG_EXT L".jpg" | |
| 285 #define HTML_EXT L".html" | |
| 286 #endif | |
| 287 #define TXT_EXT L".txt" | |
| 288 #define TAR_EXT L".tar" | |
| 289 | |
| 290 TEST(FilenameUtilTest, GenerateSafeFileName) { | |
| 291 const struct { | |
| 292 const char* mime_type; | |
| 293 const base::FilePath::CharType* filename; | |
| 294 const base::FilePath::CharType* expected_filename; | |
| 295 } safe_tests[] = { | |
| 296 #if defined(OS_WIN) | |
| 297 {"text/html", | |
| 298 FILE_PATH_LITERAL("C:\\foo\\bar.htm"), | |
| 299 FILE_PATH_LITERAL("C:\\foo\\bar.htm")}, | |
| 300 {"text/html", | |
| 301 FILE_PATH_LITERAL("C:\\foo\\bar.html"), | |
| 302 FILE_PATH_LITERAL("C:\\foo\\bar.html")}, | |
| 303 {"text/html", | |
| 304 FILE_PATH_LITERAL("C:\\foo\\bar"), | |
| 305 FILE_PATH_LITERAL("C:\\foo\\bar.htm")}, | |
| 306 {"image/png", | |
| 307 FILE_PATH_LITERAL("C:\\bar.html"), | |
| 308 FILE_PATH_LITERAL("C:\\bar.html")}, | |
| 309 {"image/png", | |
| 310 FILE_PATH_LITERAL("C:\\bar"), | |
| 311 FILE_PATH_LITERAL("C:\\bar.png")}, | |
| 312 {"text/html", | |
| 313 FILE_PATH_LITERAL("C:\\foo\\bar.exe"), | |
| 314 FILE_PATH_LITERAL("C:\\foo\\bar.exe")}, | |
| 315 {"image/gif", | |
| 316 FILE_PATH_LITERAL("C:\\foo\\bar.exe"), | |
| 317 FILE_PATH_LITERAL("C:\\foo\\bar.exe")}, | |
| 318 {"text/html", | |
| 319 FILE_PATH_LITERAL("C:\\foo\\google.com"), | |
| 320 FILE_PATH_LITERAL("C:\\foo\\google.com")}, | |
| 321 {"text/html", | |
| 322 FILE_PATH_LITERAL("C:\\foo\\con.htm"), | |
| 323 FILE_PATH_LITERAL("C:\\foo\\_con.htm")}, | |
| 324 {"text/html", | |
| 325 FILE_PATH_LITERAL("C:\\foo\\con"), | |
| 326 FILE_PATH_LITERAL("C:\\foo\\_con.htm")}, | |
| 327 {"text/html", | |
| 328 FILE_PATH_LITERAL("C:\\foo\\harmless.{not-really-this-may-be-a-guid}"), | |
| 329 FILE_PATH_LITERAL("C:\\foo\\harmless.download")}, | |
| 330 {"text/html", | |
| 331 FILE_PATH_LITERAL("C:\\foo\\harmless.local"), | |
| 332 FILE_PATH_LITERAL("C:\\foo\\harmless.download")}, | |
| 333 {"text/html", | |
| 334 FILE_PATH_LITERAL("C:\\foo\\harmless.lnk"), | |
| 335 FILE_PATH_LITERAL("C:\\foo\\harmless.download")}, | |
| 336 {"text/html", | |
| 337 FILE_PATH_LITERAL("C:\\foo\\harmless.{mismatched-"), | |
| 338 FILE_PATH_LITERAL("C:\\foo\\harmless.{mismatched-")}, | |
| 339 // Allow extension synonyms. | |
| 340 {"image/jpeg", | |
| 341 FILE_PATH_LITERAL("C:\\foo\\bar.jpg"), | |
| 342 FILE_PATH_LITERAL("C:\\foo\\bar.jpg")}, | |
| 343 {"image/jpeg", | |
| 344 FILE_PATH_LITERAL("C:\\foo\\bar.jpeg"), | |
| 345 FILE_PATH_LITERAL("C:\\foo\\bar.jpeg")}, | |
| 346 #else // !defined(OS_WIN) | |
| 347 {"text/html", | |
| 348 FILE_PATH_LITERAL("/foo/bar.htm"), | |
| 349 FILE_PATH_LITERAL("/foo/bar.htm")}, | |
| 350 {"text/html", | |
| 351 FILE_PATH_LITERAL("/foo/bar.html"), | |
| 352 FILE_PATH_LITERAL("/foo/bar.html")}, | |
| 353 {"text/html", | |
| 354 FILE_PATH_LITERAL("/foo/bar"), | |
| 355 FILE_PATH_LITERAL("/foo/bar.html")}, | |
| 356 {"image/png", | |
| 357 FILE_PATH_LITERAL("/bar.html"), | |
| 358 FILE_PATH_LITERAL("/bar.html")}, | |
| 359 {"image/png", FILE_PATH_LITERAL("/bar"), FILE_PATH_LITERAL("/bar.png")}, | |
| 360 {"image/gif", | |
| 361 FILE_PATH_LITERAL("/foo/bar.exe"), | |
| 362 FILE_PATH_LITERAL("/foo/bar.exe")}, | |
| 363 {"text/html", | |
| 364 FILE_PATH_LITERAL("/foo/google.com"), | |
| 365 FILE_PATH_LITERAL("/foo/google.com")}, | |
| 366 {"text/html", | |
| 367 FILE_PATH_LITERAL("/foo/con.htm"), | |
| 368 FILE_PATH_LITERAL("/foo/con.htm")}, | |
| 369 {"text/html", | |
| 370 FILE_PATH_LITERAL("/foo/con"), | |
| 371 FILE_PATH_LITERAL("/foo/con.html")}, | |
| 372 // Allow extension synonyms. | |
| 373 {"image/jpeg", | |
| 374 FILE_PATH_LITERAL("/bar.jpg"), | |
| 375 FILE_PATH_LITERAL("/bar.jpg")}, | |
| 376 {"image/jpeg", | |
| 377 FILE_PATH_LITERAL("/bar.jpeg"), | |
| 378 FILE_PATH_LITERAL("/bar.jpeg")}, | |
| 379 #endif // !defined(OS_WIN) | |
| 380 }; | |
| 381 | |
| 382 for (size_t i = 0; i < arraysize(safe_tests); ++i) { | |
| 383 base::FilePath file_path(safe_tests[i].filename); | |
| 384 GenerateSafeFileName(safe_tests[i].mime_type, false, &file_path); | |
| 385 EXPECT_EQ(safe_tests[i].expected_filename, file_path.value()) | |
| 386 << "Iteration " << i; | |
| 387 } | |
| 388 } | |
| 389 | |
| 390 TEST(FilenameUtilTest, GenerateFileName) { | |
| 391 // Tests whether the correct filename is selected from the the given | |
| 392 // parameters and that Content-Disposition headers are properly | |
| 393 // handled including failovers when the header is malformed. | |
| 394 const GenerateFilenameCase selection_tests[] = { | |
| 395 {__LINE__, | |
| 396 "http://www.google.com/", | |
| 397 "attachment; filename=test.html", | |
| 398 "", | |
| 399 "", | |
| 400 "", | |
| 401 L"", | |
| 402 L"test.html"}, | |
| 403 {__LINE__, | |
| 404 "http://www.google.com/", | |
| 405 "attachment; filename=\"test.html\"", | |
| 406 "", | |
| 407 "", | |
| 408 "", | |
| 409 L"", | |
| 410 L"test.html"}, | |
| 411 {__LINE__, | |
| 412 "http://www.google.com/", | |
| 413 "attachment; filename= \"test.html\"", | |
| 414 "", | |
| 415 "", | |
| 416 "", | |
| 417 L"", | |
| 418 L"test.html"}, | |
| 419 {__LINE__, | |
| 420 "http://www.google.com/", | |
| 421 "attachment; filename = \"test.html\"", | |
| 422 "", | |
| 423 "", | |
| 424 "", | |
| 425 L"", | |
| 426 L"test.html"}, | |
| 427 {// filename is whitespace. Should failover to URL host | |
| 428 __LINE__, | |
| 429 "http://www.google.com/", | |
| 430 "attachment; filename= ", | |
| 431 "", | |
| 432 "", | |
| 433 "", | |
| 434 L"", | |
| 435 L"www.google.com"}, | |
| 436 {// No filename. | |
| 437 __LINE__, | |
| 438 "http://www.google.com/path/test.html", | |
| 439 "attachment", | |
| 440 "", | |
| 441 "", | |
| 442 "", | |
| 443 L"", | |
| 444 L"test.html"}, | |
| 445 {// Ditto | |
| 446 __LINE__, | |
| 447 "http://www.google.com/path/test.html", | |
| 448 "attachment;", | |
| 449 "", | |
| 450 "", | |
| 451 "", | |
| 452 L"", | |
| 453 L"test.html"}, | |
| 454 {// No C-D | |
| 455 __LINE__, | |
| 456 "http://www.google.com/", | |
| 457 "", | |
| 458 "", | |
| 459 "", | |
| 460 "", | |
| 461 L"", | |
| 462 L"www.google.com"}, | |
| 463 {__LINE__, | |
| 464 "http://www.google.com/test.html", | |
| 465 "", | |
| 466 "", | |
| 467 "", | |
| 468 "", | |
| 469 L"", | |
| 470 L"test.html"}, | |
| 471 {// Now that we use src/url's ExtractFileName, this case falls back to | |
| 472 // the hostname. If this behavior is not desirable, we'd better change | |
| 473 // ExtractFileName (in url_parse.cc). | |
| 474 __LINE__, | |
| 475 "http://www.google.com/path/", | |
| 476 "", | |
| 477 "", | |
| 478 "", | |
| 479 "", | |
| 480 L"", | |
| 481 L"www.google.com"}, | |
| 482 {__LINE__, "http://www.google.com/path", "", "", "", "", L"", L"path"}, | |
| 483 {__LINE__, "file:///", "", "", "", "", L"", L"download"}, | |
| 484 {__LINE__, "file:///path/testfile", "", "", "", "", L"", L"testfile"}, | |
| 485 {__LINE__, "non-standard-scheme:", "", "", "", "", L"", L"download"}, | |
| 486 {// C-D should override default | |
| 487 __LINE__, | |
| 488 "http://www.google.com/", | |
| 489 "attachment; filename =\"test.html\"", | |
| 490 "", | |
| 491 "", | |
| 492 "", | |
| 493 L"download", | |
| 494 L"test.html"}, | |
| 495 {// But the URL shouldn't | |
| 496 __LINE__, | |
| 497 "http://www.google.com/", | |
| 498 "", | |
| 499 "", | |
| 500 "", | |
| 501 "", | |
| 502 L"download", | |
| 503 L"download"}, | |
| 504 {__LINE__, | |
| 505 "http://www.google.com/", | |
| 506 "attachment; filename=\"../test.html\"", | |
| 507 "", | |
| 508 "", | |
| 509 "", | |
| 510 L"", | |
| 511 L"-test.html"}, | |
| 512 {__LINE__, | |
| 513 "http://www.google.com/", | |
| 514 "attachment; filename=\"..\\test.html\"", | |
| 515 "", | |
| 516 "", | |
| 517 "", | |
| 518 L"", | |
| 519 L"test.html"}, | |
| 520 {__LINE__, | |
| 521 "http://www.google.com/", | |
| 522 "attachment; filename=\"..\\\\test.html\"", | |
| 523 "", | |
| 524 "", | |
| 525 "", | |
| 526 L"", | |
| 527 L"-test.html"}, | |
| 528 {// Filename disappears after leading and trailing periods are removed. | |
| 529 __LINE__, | |
| 530 "http://www.google.com/", | |
| 531 "attachment; filename=\"..\"", | |
| 532 "", | |
| 533 "", | |
| 534 "", | |
| 535 L"default", | |
| 536 L"default"}, | |
| 537 {// C-D specified filename disappears. Failover to final filename. | |
| 538 __LINE__, | |
| 539 "http://www.google.com/test.html", | |
| 540 "attachment; filename=\"..\"", | |
| 541 "", | |
| 542 "", | |
| 543 "", | |
| 544 L"default", | |
| 545 L"default"}, | |
| 546 // Below is a small subset of cases taken from HttpContentDisposition tests. | |
| 547 {__LINE__, | |
| 548 "http://www.google.com/", | |
| 549 "attachment; filename=\"%EC%98%88%EC%88%A0%20" | |
| 550 "%EC%98%88%EC%88%A0.jpg\"", | |
| 551 "", | |
| 552 "", | |
| 553 "", | |
| 554 L"", | |
| 555 L"\uc608\uc220 \uc608\uc220.jpg"}, | |
| 556 {__LINE__, | |
| 557 "http://www.google.com/%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg", | |
| 558 "", | |
| 559 "", | |
| 560 "", | |
| 561 "", | |
| 562 L"download", | |
| 563 L"\uc608\uc220 \uc608\uc220.jpg"}, | |
| 564 {__LINE__, | |
| 565 "http://www.google.com/", | |
| 566 "attachment;", | |
| 567 "", | |
| 568 "", | |
| 569 "", | |
| 570 L"\uB2E4\uC6B4\uB85C\uB4DC", | |
| 571 L"\uB2E4\uC6B4\uB85C\uB4DC"}, | |
| 572 {__LINE__, | |
| 573 "http://www.google.com/", | |
| 574 "attachment; filename=\"=?EUC-JP?Q?=B7=DD=BD=" | |
| 575 "D13=2Epng?=\"", | |
| 576 "", | |
| 577 "", | |
| 578 "", | |
| 579 L"download", | |
| 580 L"\u82b8\u88533.png"}, | |
| 581 {__LINE__, | |
| 582 "http://www.example.com/images?id=3", | |
| 583 "attachment; filename=caf\xc3\xa9.png", | |
| 584 "iso-8859-1", | |
| 585 "", | |
| 586 "", | |
| 587 L"", | |
| 588 L"caf\u00e9.png"}, | |
| 589 {__LINE__, | |
| 590 "http://www.example.com/images?id=3", | |
| 591 "attachment; filename=caf\xe5.png", | |
| 592 "windows-1253", | |
| 593 "", | |
| 594 "", | |
| 595 L"", | |
| 596 L"caf\u03b5.png"}, | |
| 597 {__LINE__, | |
| 598 "http://www.example.com/file?id=3", | |
| 599 "attachment; name=\xcf\xc2\xd4\xd8.zip", | |
| 600 "GBK", | |
| 601 "", | |
| 602 "", | |
| 603 L"", | |
| 604 L"\u4e0b\u8f7d.zip"}, | |
| 605 {// Invalid C-D header. Extracts filename from url. | |
| 606 __LINE__, | |
| 607 "http://www.google.com/test.html", | |
| 608 "attachment; filename==?iiso88591?Q?caf=EG?=", | |
| 609 "", | |
| 610 "", | |
| 611 "", | |
| 612 L"", | |
| 613 L"test.html"}, | |
| 614 // about: and data: URLs | |
| 615 {__LINE__, "about:chrome", "", "", "", "", L"", L"download"}, | |
| 616 {__LINE__, "data:,looks/like/a.path", "", "", "", "", L"", L"download"}, | |
| 617 {__LINE__, | |
| 618 "data:text/plain;base64,VG8gYmUgb3Igbm90IHRvIGJlLg=", | |
| 619 "", | |
| 620 "", | |
| 621 "", | |
| 622 "", | |
| 623 L"", | |
| 624 L"download"}, | |
| 625 {__LINE__, | |
| 626 "data:,looks/like/a.path", | |
| 627 "", | |
| 628 "", | |
| 629 "", | |
| 630 "", | |
| 631 L"default_filename_is_given", | |
| 632 L"default_filename_is_given"}, | |
| 633 {__LINE__, | |
| 634 "data:,looks/like/a.path", | |
| 635 "", | |
| 636 "", | |
| 637 "", | |
| 638 "", | |
| 639 L"\u65e5\u672c\u8a9e", // Japanese Kanji. | |
| 640 L"\u65e5\u672c\u8a9e"}, | |
| 641 {// The filename encoding is specified by the referrer charset. | |
| 642 __LINE__, | |
| 643 "http://example.com/V%FDvojov%E1%20psychologie.doc", | |
| 644 "", | |
| 645 "iso-8859-1", | |
| 646 "", | |
| 647 "", | |
| 648 L"", | |
| 649 L"V\u00fdvojov\u00e1 psychologie.doc"}, | |
| 650 {// Suggested filename takes precedence over URL | |
| 651 __LINE__, | |
| 652 "http://www.google.com/test", | |
| 653 "", | |
| 654 "", | |
| 655 "suggested", | |
| 656 "", | |
| 657 L"", | |
| 658 L"suggested"}, | |
| 659 {// The content-disposition has higher precedence over the suggested name. | |
| 660 __LINE__, | |
| 661 "http://www.google.com/test", | |
| 662 "attachment; filename=test.html", | |
| 663 "", | |
| 664 "suggested", | |
| 665 "", | |
| 666 L"", | |
| 667 L"test.html"}, | |
| 668 {__LINE__, | |
| 669 "http://www.google.com/test", | |
| 670 "attachment; filename=test", | |
| 671 "utf-8", | |
| 672 "", | |
| 673 "image/png", | |
| 674 L"", | |
| 675 L"test"}, | |
| 676 #if 0 | |
| 677 { // The filename encoding doesn't match the referrer charset, the system | |
| 678 // charset, or UTF-8. | |
| 679 // TODO(jshin): we need to handle this case. | |
| 680 __LINE__, | |
| 681 "http://example.com/V%FDvojov%E1%20psychologie.doc", | |
| 682 "", | |
| 683 "utf-8", | |
| 684 "", | |
| 685 "", | |
| 686 L"", | |
| 687 L"V\u00fdvojov\u00e1 psychologie.doc", | |
| 688 }, | |
| 689 #endif | |
| 690 // Raw 8bit characters in C-D | |
| 691 {__LINE__, | |
| 692 "http://www.example.com/images?id=3", | |
| 693 "attachment; filename=caf\xc3\xa9.png", | |
| 694 "iso-8859-1", | |
| 695 "", | |
| 696 "image/png", | |
| 697 L"", | |
| 698 L"caf\u00e9.png"}, | |
| 699 {__LINE__, | |
| 700 "http://www.example.com/images?id=3", | |
| 701 "attachment; filename=caf\xe5.png", | |
| 702 "windows-1253", | |
| 703 "", | |
| 704 "image/png", | |
| 705 L"", | |
| 706 L"caf\u03b5.png"}, | |
| 707 {// No 'filename' keyword in the disposition, use the URL | |
| 708 __LINE__, | |
| 709 "http://www.evil.com/my_download.txt", | |
| 710 "a_file_name.txt", | |
| 711 "", | |
| 712 "", | |
| 713 "text/plain", | |
| 714 L"download", | |
| 715 L"my_download.txt"}, | |
| 716 {// Spaces in the disposition file name | |
| 717 __LINE__, | |
| 718 "http://www.frontpagehacker.com/a_download.exe", | |
| 719 "filename=My Downloaded File.exe", | |
| 720 "", | |
| 721 "", | |
| 722 "application/octet-stream", | |
| 723 L"download", | |
| 724 L"My Downloaded File.exe"}, | |
| 725 {// % encoded | |
| 726 __LINE__, | |
| 727 "http://www.examples.com/", | |
| 728 "attachment; " | |
| 729 "filename=\"%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg\"", | |
| 730 "", | |
| 731 "", | |
| 732 "image/jpeg", | |
| 733 L"download", | |
| 734 L"\uc608\uc220 \uc608\uc220.jpg"}, | |
| 735 {// name= parameter | |
| 736 __LINE__, | |
| 737 "http://www.examples.com/q.cgi?id=abc", | |
| 738 "attachment; name=abc de.pdf", | |
| 739 "", | |
| 740 "", | |
| 741 "application/octet-stream", | |
| 742 L"download", | |
| 743 L"abc de.pdf"}, | |
| 744 {__LINE__, | |
| 745 "http://www.example.com/path", | |
| 746 "filename=\"=?EUC-JP?Q?=B7=DD=BD=D13=2Epng?=\"", | |
| 747 "", | |
| 748 "", | |
| 749 "image/png", | |
| 750 L"download", | |
| 751 L"\x82b8\x8853" | |
| 752 L"3.png"}, | |
| 753 {// The following two have invalid CD headers and filenames come from the | |
| 754 // URL. | |
| 755 __LINE__, | |
| 756 "http://www.example.com/test%20123", | |
| 757 "attachment; filename==?iiso88591?Q?caf=EG?=", | |
| 758 "", | |
| 759 "", | |
| 760 "image/jpeg", | |
| 761 L"download", | |
| 762 L"test 123" JPEG_EXT}, | |
| 763 {__LINE__, | |
| 764 "http://www.google.com/%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg", | |
| 765 "malformed_disposition", | |
| 766 "", | |
| 767 "", | |
| 768 "image/jpeg", | |
| 769 L"download", | |
| 770 L"\uc608\uc220 \uc608\uc220.jpg"}, | |
| 771 {// Invalid C-D. No filename from URL. Falls back to 'download'. | |
| 772 __LINE__, | |
| 773 "http://www.google.com/path1/path2/", | |
| 774 "attachment; filename==?iso88591?Q?caf=E3?", | |
| 775 "", | |
| 776 "", | |
| 777 "image/jpeg", | |
| 778 L"download", | |
| 779 L"download" JPEG_EXT}, | |
| 780 }; | |
| 781 | |
| 782 // Tests filename generation. Once the correct filename is | |
| 783 // selected, they should be passed through the validation steps and | |
| 784 // a correct extension should be added if necessary. | |
| 785 const GenerateFilenameCase generation_tests[] = { | |
| 786 // Dotfiles. Ensures preceeding period(s) stripped. | |
| 787 {__LINE__, | |
| 788 "http://www.google.com/.test.html", | |
| 789 "", | |
| 790 "", | |
| 791 "", | |
| 792 "", | |
| 793 L"", | |
| 794 L"test.html"}, | |
| 795 {__LINE__, "http://www.google.com/.test", "", "", "", "", L"", L"test"}, | |
| 796 {__LINE__, "http://www.google.com/..test", "", "", "", "", L"", L"test"}, | |
| 797 {// Disposition has relative paths, remove directory separators | |
| 798 __LINE__, | |
| 799 "http://www.evil.com/my_download.txt", | |
| 800 "filename=../../../../././../a_file_name.txt", | |
| 801 "", | |
| 802 "", | |
| 803 "text/plain", | |
| 804 L"download", | |
| 805 L"-..-..-..-.-.-..-a_file_name.txt"}, | |
| 806 {// Disposition has parent directories, remove directory separators | |
| 807 __LINE__, | |
| 808 "http://www.evil.com/my_download.txt", | |
| 809 "filename=dir1/dir2/a_file_name.txt", | |
| 810 "", | |
| 811 "", | |
| 812 "text/plain", | |
| 813 L"download", | |
| 814 L"dir1-dir2-a_file_name.txt"}, | |
| 815 {// Disposition has relative paths, remove directory separators | |
| 816 __LINE__, | |
| 817 "http://www.evil.com/my_download.txt", | |
| 818 "filename=..\\..\\..\\..\\.\\.\\..\\a_file_name.txt", | |
| 819 "", | |
| 820 "", | |
| 821 "text/plain", | |
| 822 L"download", | |
| 823 L"-..-..-..-.-.-..-a_file_name.txt"}, | |
| 824 {// Disposition has parent directories, remove directory separators | |
| 825 __LINE__, | |
| 826 "http://www.evil.com/my_download.txt", | |
| 827 "filename=dir1\\dir2\\a_file_name.txt", | |
| 828 "", | |
| 829 "", | |
| 830 "text/plain", | |
| 831 L"download", | |
| 832 L"dir1-dir2-a_file_name.txt"}, | |
| 833 {// No useful information in disposition or URL, use default | |
| 834 __LINE__, | |
| 835 "http://www.truncated.com/path/", | |
| 836 "", | |
| 837 "", | |
| 838 "", | |
| 839 "text/plain", | |
| 840 L"download", | |
| 841 L"download" TXT_EXT}, | |
| 842 {// Filename looks like HTML? | |
| 843 __LINE__, | |
| 844 "http://www.evil.com/get/malware/here", | |
| 845 "filename=\"<blink>Hello kitty</blink>\"", | |
| 846 "", | |
| 847 "", | |
| 848 "text/plain", | |
| 849 L"default", | |
| 850 L"-blink-Hello kitty--blink-"}, | |
| 851 {// A normal avi should get .avi and not .avi.avi | |
| 852 __LINE__, | |
| 853 "https://blah.google.com/misc/2.avi", | |
| 854 "", | |
| 855 "", | |
| 856 "", | |
| 857 "video/x-msvideo", | |
| 858 L"download", | |
| 859 L"2.avi"}, | |
| 860 {// Extension generation | |
| 861 __LINE__, | |
| 862 "http://www.example.com/my-cat", | |
| 863 "filename=my-cat", | |
| 864 "", | |
| 865 "", | |
| 866 "image/jpeg", | |
| 867 L"download", | |
| 868 L"my-cat"}, | |
| 869 {__LINE__, | |
| 870 "http://www.example.com/my-cat", | |
| 871 "filename=my-cat", | |
| 872 "", | |
| 873 "", | |
| 874 "text/plain", | |
| 875 L"download", | |
| 876 L"my-cat"}, | |
| 877 {__LINE__, | |
| 878 "http://www.example.com/my-cat", | |
| 879 "filename=my-cat", | |
| 880 "", | |
| 881 "", | |
| 882 "text/html", | |
| 883 L"download", | |
| 884 L"my-cat"}, | |
| 885 {// Unknown MIME type | |
| 886 __LINE__, | |
| 887 "http://www.example.com/my-cat", | |
| 888 "filename=my-cat", | |
| 889 "", | |
| 890 "", | |
| 891 "dance/party", | |
| 892 L"download", | |
| 893 L"my-cat"}, | |
| 894 {__LINE__, | |
| 895 "http://www.example.com/my-cat.jpg", | |
| 896 "filename=my-cat.jpg", | |
| 897 "", | |
| 898 "", | |
| 899 "text/plain", | |
| 900 L"download", | |
| 901 L"my-cat.jpg"}, | |
| 902 // Windows specific tests | |
| 903 #if defined(OS_WIN) | |
| 904 {__LINE__, | |
| 905 "http://www.goodguy.com/evil.exe", | |
| 906 "filename=evil.exe", | |
| 907 "", | |
| 908 "", | |
| 909 "image/jpeg", | |
| 910 L"download", | |
| 911 L"evil.exe"}, | |
| 912 {__LINE__, | |
| 913 "http://www.goodguy.com/ok.exe", | |
| 914 "filename=ok.exe", | |
| 915 "", | |
| 916 "", | |
| 917 "binary/octet-stream", | |
| 918 L"download", | |
| 919 L"ok.exe"}, | |
| 920 {__LINE__, | |
| 921 "http://www.goodguy.com/evil.dll", | |
| 922 "filename=evil.dll", | |
| 923 "", | |
| 924 "", | |
| 925 "dance/party", | |
| 926 L"download", | |
| 927 L"evil.dll"}, | |
| 928 {__LINE__, | |
| 929 "http://www.goodguy.com/evil.exe", | |
| 930 "filename=evil", | |
| 931 "", | |
| 932 "", | |
| 933 "application/rss+xml", | |
| 934 L"download", | |
| 935 L"evil"}, | |
| 936 // Test truncation of trailing dots and spaces | |
| 937 {__LINE__, | |
| 938 "http://www.goodguy.com/evil.exe ", | |
| 939 "filename=evil.exe ", | |
| 940 "", | |
| 941 "", | |
| 942 "binary/octet-stream", | |
| 943 L"download", | |
| 944 L"evil.exe"}, | |
| 945 {__LINE__, | |
| 946 "http://www.goodguy.com/evil.exe.", | |
| 947 "filename=evil.exe.", | |
| 948 "", | |
| 949 "", | |
| 950 "binary/octet-stream", | |
| 951 L"download", | |
| 952 L"evil.exe-"}, | |
| 953 {__LINE__, | |
| 954 "http://www.goodguy.com/evil.exe. . .", | |
| 955 "filename=evil.exe. . .", | |
| 956 "", | |
| 957 "", | |
| 958 "binary/octet-stream", | |
| 959 L"download", | |
| 960 L"evil.exe-------"}, | |
| 961 {__LINE__, | |
| 962 "http://www.goodguy.com/evil.", | |
| 963 "filename=evil.", | |
| 964 "", | |
| 965 "", | |
| 966 "binary/octet-stream", | |
| 967 L"download", | |
| 968 L"evil-"}, | |
| 969 {__LINE__, | |
| 970 "http://www.goodguy.com/. . . . .", | |
| 971 "filename=. . . . .", | |
| 972 "", | |
| 973 "", | |
| 974 "binary/octet-stream", | |
| 975 L"download", | |
| 976 L"download"}, | |
| 977 {__LINE__, | |
| 978 "http://www.badguy.com/attachment?name=meh.exe%C2%A0", | |
| 979 "attachment; filename=\"meh.exe\xC2\xA0\"", | |
| 980 "", | |
| 981 "", | |
| 982 "binary/octet-stream", | |
| 983 L"", | |
| 984 L"meh.exe-"}, | |
| 985 #endif // OS_WIN | |
| 986 {__LINE__, | |
| 987 "http://www.goodguy.com/utils.js", | |
| 988 "filename=utils.js", | |
| 989 "", | |
| 990 "", | |
| 991 "application/x-javascript", | |
| 992 L"download", | |
| 993 L"utils.js"}, | |
| 994 {__LINE__, | |
| 995 "http://www.goodguy.com/contacts.js", | |
| 996 "filename=contacts.js", | |
| 997 "", | |
| 998 "", | |
| 999 "application/json", | |
| 1000 L"download", | |
| 1001 L"contacts.js"}, | |
| 1002 {__LINE__, | |
| 1003 "http://www.goodguy.com/utils.js", | |
| 1004 "filename=utils.js", | |
| 1005 "", | |
| 1006 "", | |
| 1007 "text/javascript", | |
| 1008 L"download", | |
| 1009 L"utils.js"}, | |
| 1010 {__LINE__, | |
| 1011 "http://www.goodguy.com/utils.js", | |
| 1012 "filename=utils.js", | |
| 1013 "", | |
| 1014 "", | |
| 1015 "text/javascript;version=2", | |
| 1016 L"download", | |
| 1017 L"utils.js"}, | |
| 1018 {__LINE__, | |
| 1019 "http://www.goodguy.com/utils.js", | |
| 1020 "filename=utils.js", | |
| 1021 "", | |
| 1022 "", | |
| 1023 "application/ecmascript", | |
| 1024 L"download", | |
| 1025 L"utils.js"}, | |
| 1026 {__LINE__, | |
| 1027 "http://www.goodguy.com/utils.js", | |
| 1028 "filename=utils.js", | |
| 1029 "", | |
| 1030 "", | |
| 1031 "application/ecmascript;version=4", | |
| 1032 L"download", | |
| 1033 L"utils.js"}, | |
| 1034 {__LINE__, | |
| 1035 "http://www.goodguy.com/program.exe", | |
| 1036 "filename=program.exe", | |
| 1037 "", | |
| 1038 "", | |
| 1039 "application/foo-bar", | |
| 1040 L"download", | |
| 1041 L"program.exe"}, | |
| 1042 {__LINE__, | |
| 1043 "http://www.evil.com/../foo.txt", | |
| 1044 "filename=../foo.txt", | |
| 1045 "", | |
| 1046 "", | |
| 1047 "text/plain", | |
| 1048 L"download", | |
| 1049 L"-foo.txt"}, | |
| 1050 {__LINE__, | |
| 1051 "http://www.evil.com/..\\foo.txt", | |
| 1052 "filename=..\\foo.txt", | |
| 1053 "", | |
| 1054 "", | |
| 1055 "text/plain", | |
| 1056 L"download", | |
| 1057 L"-foo.txt"}, | |
| 1058 {__LINE__, | |
| 1059 "http://www.evil.com/.hidden", | |
| 1060 "filename=.hidden", | |
| 1061 "", | |
| 1062 "", | |
| 1063 "text/plain", | |
| 1064 L"download", | |
| 1065 L"hidden"}, | |
| 1066 {__LINE__, | |
| 1067 "http://www.evil.com/trailing.", | |
| 1068 "filename=trailing.", | |
| 1069 "", | |
| 1070 "", | |
| 1071 "dance/party", | |
| 1072 L"download", | |
| 1073 #if defined(OS_WIN) | |
| 1074 L"trailing-" | |
| 1075 #else | |
| 1076 L"trailing" | |
| 1077 #endif | |
| 1078 }, | |
| 1079 {__LINE__, | |
| 1080 "http://www.evil.com/trailing.", | |
| 1081 "filename=trailing.", | |
| 1082 "", | |
| 1083 "", | |
| 1084 "text/plain", | |
| 1085 L"download", | |
| 1086 #if defined(OS_WIN) | |
| 1087 L"trailing-" | |
| 1088 #else | |
| 1089 L"trailing" | |
| 1090 #endif | |
| 1091 }, | |
| 1092 {__LINE__, | |
| 1093 "http://www.evil.com/.", | |
| 1094 "filename=.", | |
| 1095 "", | |
| 1096 "", | |
| 1097 "dance/party", | |
| 1098 L"download", | |
| 1099 L"download"}, | |
| 1100 {__LINE__, | |
| 1101 "http://www.evil.com/..", | |
| 1102 "filename=..", | |
| 1103 "", | |
| 1104 "", | |
| 1105 "dance/party", | |
| 1106 L"download", | |
| 1107 L"download"}, | |
| 1108 {__LINE__, | |
| 1109 "http://www.evil.com/...", | |
| 1110 "filename=...", | |
| 1111 "", | |
| 1112 "", | |
| 1113 "dance/party", | |
| 1114 L"download", | |
| 1115 L"download"}, | |
| 1116 {// Note that this one doesn't have "filename=" on it. | |
| 1117 __LINE__, | |
| 1118 "http://www.evil.com/", | |
| 1119 "a_file_name.txt", | |
| 1120 "", | |
| 1121 "", | |
| 1122 "image/jpeg", | |
| 1123 L"download", | |
| 1124 L"download" JPEG_EXT}, | |
| 1125 {__LINE__, | |
| 1126 "http://www.evil.com/", | |
| 1127 "filename=", | |
| 1128 "", | |
| 1129 "", | |
| 1130 "image/jpeg", | |
| 1131 L"download", | |
| 1132 L"download" JPEG_EXT}, | |
| 1133 {__LINE__, | |
| 1134 "http://www.example.com/simple", | |
| 1135 "filename=simple", | |
| 1136 "", | |
| 1137 "", | |
| 1138 "application/octet-stream", | |
| 1139 L"download", | |
| 1140 L"simple"}, | |
| 1141 // Reserved words on Windows | |
| 1142 {__LINE__, | |
| 1143 "http://www.goodguy.com/COM1", | |
| 1144 "filename=COM1", | |
| 1145 "", | |
| 1146 "", | |
| 1147 "application/foo-bar", | |
| 1148 L"download", | |
| 1149 #if defined(OS_WIN) | |
| 1150 L"_COM1" | |
| 1151 #else | |
| 1152 L"COM1" | |
| 1153 #endif | |
| 1154 }, | |
| 1155 {__LINE__, | |
| 1156 "http://www.goodguy.com/COM4.txt", | |
| 1157 "filename=COM4.txt", | |
| 1158 "", | |
| 1159 "", | |
| 1160 "text/plain", | |
| 1161 L"download", | |
| 1162 #if defined(OS_WIN) | |
| 1163 L"_COM4.txt" | |
| 1164 #else | |
| 1165 L"COM4.txt" | |
| 1166 #endif | |
| 1167 }, | |
| 1168 {__LINE__, | |
| 1169 "http://www.goodguy.com/lpt1.TXT", | |
| 1170 "filename=lpt1.TXT", | |
| 1171 "", | |
| 1172 "", | |
| 1173 "text/plain", | |
| 1174 L"download", | |
| 1175 #if defined(OS_WIN) | |
| 1176 L"_lpt1.TXT" | |
| 1177 #else | |
| 1178 L"lpt1.TXT" | |
| 1179 #endif | |
| 1180 }, | |
| 1181 {__LINE__, | |
| 1182 "http://www.goodguy.com/clock$.txt", | |
| 1183 "filename=clock$.txt", | |
| 1184 "", | |
| 1185 "", | |
| 1186 "text/plain", | |
| 1187 L"download", | |
| 1188 #if defined(OS_WIN) | |
| 1189 L"_clock$.txt" | |
| 1190 #else | |
| 1191 L"clock$.txt" | |
| 1192 #endif | |
| 1193 }, | |
| 1194 {// Validation should also apply to sugested name | |
| 1195 __LINE__, | |
| 1196 "http://www.goodguy.com/blah$.txt", | |
| 1197 "filename=clock$.txt", | |
| 1198 "", | |
| 1199 "clock$.txt", | |
| 1200 "text/plain", | |
| 1201 L"download", | |
| 1202 #if defined(OS_WIN) | |
| 1203 L"_clock$.txt" | |
| 1204 #else | |
| 1205 L"clock$.txt" | |
| 1206 #endif | |
| 1207 }, | |
| 1208 {__LINE__, | |
| 1209 "http://www.goodguy.com/mycom1.foo", | |
| 1210 "filename=mycom1.foo", | |
| 1211 "", | |
| 1212 "", | |
| 1213 "text/plain", | |
| 1214 L"download", | |
| 1215 L"mycom1.foo"}, | |
| 1216 {__LINE__, | |
| 1217 "http://www.badguy.com/Setup.exe.local", | |
| 1218 "filename=Setup.exe.local", | |
| 1219 "", | |
| 1220 "", | |
| 1221 "application/foo-bar", | |
| 1222 L"download", | |
| 1223 #if defined(OS_WIN) | |
| 1224 L"Setup.exe.download" | |
| 1225 #else | |
| 1226 L"Setup.exe.local" | |
| 1227 #endif | |
| 1228 }, | |
| 1229 {__LINE__, | |
| 1230 "http://www.badguy.com/Setup.exe.local", | |
| 1231 "filename=Setup.exe.local.local", | |
| 1232 "", | |
| 1233 "", | |
| 1234 "application/foo-bar", | |
| 1235 L"download", | |
| 1236 #if defined(OS_WIN) | |
| 1237 L"Setup.exe.local.download" | |
| 1238 #else | |
| 1239 L"Setup.exe.local.local" | |
| 1240 #endif | |
| 1241 }, | |
| 1242 {__LINE__, | |
| 1243 "http://www.badguy.com/Setup.exe.lnk", | |
| 1244 "filename=Setup.exe.lnk", | |
| 1245 "", | |
| 1246 "", | |
| 1247 "application/foo-bar", | |
| 1248 L"download", | |
| 1249 #if defined(OS_WIN) | |
| 1250 L"Setup.exe.download" | |
| 1251 #else | |
| 1252 L"Setup.exe.lnk" | |
| 1253 #endif | |
| 1254 }, | |
| 1255 {__LINE__, | |
| 1256 "http://www.badguy.com/Desktop.ini", | |
| 1257 "filename=Desktop.ini", | |
| 1258 "", | |
| 1259 "", | |
| 1260 "application/foo-bar", | |
| 1261 L"download", | |
| 1262 #if defined(OS_WIN) | |
| 1263 L"_Desktop.ini" | |
| 1264 #else | |
| 1265 L"Desktop.ini" | |
| 1266 #endif | |
| 1267 }, | |
| 1268 {__LINE__, | |
| 1269 "http://www.badguy.com/Thumbs.db", | |
| 1270 "filename=Thumbs.db", | |
| 1271 "", | |
| 1272 "", | |
| 1273 "application/foo-bar", | |
| 1274 L"download", | |
| 1275 #if defined(OS_WIN) | |
| 1276 L"_Thumbs.db" | |
| 1277 #else | |
| 1278 L"Thumbs.db" | |
| 1279 #endif | |
| 1280 }, | |
| 1281 {__LINE__, | |
| 1282 "http://www.hotmail.com", | |
| 1283 "filename=source.jpg", | |
| 1284 "", | |
| 1285 "", | |
| 1286 "application/x-javascript", | |
| 1287 L"download", | |
| 1288 L"source.jpg"}, | |
| 1289 {// http://crbug.com/5772. | |
| 1290 __LINE__, | |
| 1291 "http://www.example.com/foo.tar.gz", | |
| 1292 "", | |
| 1293 "", | |
| 1294 "", | |
| 1295 "application/x-tar", | |
| 1296 L"download", | |
| 1297 L"foo.tar.gz"}, | |
| 1298 {// http://crbug.com/52250. | |
| 1299 __LINE__, | |
| 1300 "http://www.example.com/foo.tgz", | |
| 1301 "", | |
| 1302 "", | |
| 1303 "", | |
| 1304 "application/x-tar", | |
| 1305 L"download", | |
| 1306 L"foo.tgz"}, | |
| 1307 {// http://crbug.com/7337. | |
| 1308 __LINE__, | |
| 1309 "http://maged.lordaeron.org/blank.reg", | |
| 1310 "", | |
| 1311 "", | |
| 1312 "", | |
| 1313 "text/x-registry", | |
| 1314 L"download", | |
| 1315 L"blank.reg"}, | |
| 1316 {__LINE__, | |
| 1317 "http://www.example.com/bar.tar", | |
| 1318 "", | |
| 1319 "", | |
| 1320 "", | |
| 1321 "application/x-tar", | |
| 1322 L"download", | |
| 1323 L"bar.tar"}, | |
| 1324 {__LINE__, | |
| 1325 "http://www.example.com/bar.bogus", | |
| 1326 "", | |
| 1327 "", | |
| 1328 "", | |
| 1329 "application/x-tar", | |
| 1330 L"download", | |
| 1331 L"bar.bogus"}, | |
| 1332 {// http://crbug.com/20337 | |
| 1333 __LINE__, | |
| 1334 "http://www.example.com/.download.txt", | |
| 1335 "filename=.download.txt", | |
| 1336 "", | |
| 1337 "", | |
| 1338 "text/plain", | |
| 1339 L"-download", | |
| 1340 L"download.txt"}, | |
| 1341 {// http://crbug.com/56855. | |
| 1342 __LINE__, | |
| 1343 "http://www.example.com/bar.sh", | |
| 1344 "", | |
| 1345 "", | |
| 1346 "", | |
| 1347 "application/x-sh", | |
| 1348 L"download", | |
| 1349 L"bar.sh"}, | |
| 1350 {// http://crbug.com/61571 | |
| 1351 __LINE__, | |
| 1352 "http://www.example.com/npdf.php?fn=foobar.pdf", | |
| 1353 "", | |
| 1354 "", | |
| 1355 "", | |
| 1356 "text/plain", | |
| 1357 L"download", | |
| 1358 L"npdf" TXT_EXT}, | |
| 1359 {// Shouldn't overwrite C-D specified extension. | |
| 1360 __LINE__, | |
| 1361 "http://www.example.com/npdf.php?fn=foobar.pdf", | |
| 1362 "filename=foobar.jpg", | |
| 1363 "", | |
| 1364 "", | |
| 1365 "text/plain", | |
| 1366 L"download", | |
| 1367 L"foobar.jpg"}, | |
| 1368 {// http://crbug.com/87719 | |
| 1369 __LINE__, | |
| 1370 "http://www.example.com/image.aspx?id=blargh", | |
| 1371 "", | |
| 1372 "", | |
| 1373 "", | |
| 1374 "image/jpeg", | |
| 1375 L"download", | |
| 1376 L"image" JPEG_EXT}, | |
| 1377 {__LINE__, | |
| 1378 "http://www.example.com/image.aspx?id=blargh", | |
| 1379 "", | |
| 1380 "", | |
| 1381 " .foo", | |
| 1382 "", | |
| 1383 L"download", | |
| 1384 L"-.foo"}, | |
| 1385 #if defined(OS_CHROMEOS) | |
| 1386 {// http://crosbug.com/26028 | |
| 1387 __LINE__, | |
| 1388 "http://www.example.com/fooa%cc%88.txt", | |
| 1389 "", | |
| 1390 "", | |
| 1391 "", | |
| 1392 "image/jpeg", | |
| 1393 L"foo\xe4", | |
| 1394 L"foo\xe4.txt"}, | |
| 1395 #endif | |
| 1396 }; | |
| 1397 | |
| 1398 for (size_t i = 0; i < arraysize(selection_tests); ++i) | |
| 1399 RunGenerateFileNameTestCase(&selection_tests[i]); | |
| 1400 | |
| 1401 for (size_t i = 0; i < arraysize(generation_tests); ++i) | |
| 1402 RunGenerateFileNameTestCase(&generation_tests[i]); | |
| 1403 | |
| 1404 for (size_t i = 0; i < arraysize(generation_tests); ++i) { | |
| 1405 GenerateFilenameCase test_case = generation_tests[i]; | |
| 1406 test_case.referrer_charset = "GBK"; | |
| 1407 RunGenerateFileNameTestCase(&test_case); | |
| 1408 } | |
| 1409 } | |
| 1410 | |
| 1411 } // namespace net | |
| OLD | NEW |