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