| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 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 "chrome/browser/download/download_util.h" | |
| 6 | |
| 7 #if defined(OS_POSIX) && !defined(OS_MACOSX) | |
| 8 #include <locale.h> | |
| 9 #endif | |
| 10 | |
| 11 #include "base/string_util.h" | |
| 12 #include "base/test/test_file_util.h" | |
| 13 #include "googleurl/src/gurl.h" | |
| 14 #include "testing/gtest/include/gtest/gtest.h" | |
| 15 | |
| 16 #if defined(OS_WIN) | |
| 17 #define JPEG_EXT L".jpg" | |
| 18 #define HTML_EXT L".htm" | |
| 19 #define TXT_EXT L".txt" | |
| 20 #define TAR_EXT L".tar" | |
| 21 #elif defined(OS_MACOSX) | |
| 22 #define JPEG_EXT L".jpeg" | |
| 23 #define HTML_EXT L".html" | |
| 24 #define TXT_EXT L".txt" | |
| 25 #define TAR_EXT L".tar" | |
| 26 #else | |
| 27 #define JPEG_EXT L".jpg" | |
| 28 #define HTML_EXT L".html" | |
| 29 #define TXT_EXT L".txt" | |
| 30 #define TAR_EXT L".tar" | |
| 31 #endif | |
| 32 | |
| 33 namespace { | |
| 34 | |
| 35 const struct { | |
| 36 const char* disposition; | |
| 37 const char* url; | |
| 38 const char* mime_type; | |
| 39 const wchar_t* expected_name; | |
| 40 } kGenerateFileNameTestCases[] = { | |
| 41 // No 'filename' keyword in the disposition, use the URL | |
| 42 {"a_file_name.txt", | |
| 43 "http://www.evil.com/my_download.txt", | |
| 44 "text/plain", | |
| 45 L"my_download.txt"}, | |
| 46 | |
| 47 // Disposition has relative paths, remove directory separators | |
| 48 {"filename=../../../../././../a_file_name.txt", | |
| 49 "http://www.evil.com/my_download.txt", | |
| 50 "text/plain", | |
| 51 L"_.._.._.._._._.._a_file_name.txt"}, | |
| 52 | |
| 53 // Disposition has parent directories, remove directory separators | |
| 54 {"filename=dir1/dir2/a_file_name.txt", | |
| 55 "http://www.evil.com/my_download.txt", | |
| 56 "text/plain", | |
| 57 L"dir1_dir2_a_file_name.txt"}, | |
| 58 | |
| 59 // Disposition has relative paths, remove directory separators | |
| 60 {"filename=..\\..\\..\\..\\.\\.\\..\\a_file_name.txt", | |
| 61 "http://www.evil.com/my_download.txt", | |
| 62 "text/plain", | |
| 63 L"_.._.._.._._._.._a_file_name.txt"}, | |
| 64 | |
| 65 // Disposition has parent directories, remove directory separators | |
| 66 {"filename=dir1\\dir2\\a_file_name.txt", | |
| 67 "http://www.evil.com/my_download.txt", | |
| 68 "text/plain", | |
| 69 L"dir1_dir2_a_file_name.txt"}, | |
| 70 | |
| 71 // No useful information in disposition or URL, use default | |
| 72 {"", "http://www.truncated.com/path/", "text/plain", | |
| 73 L"download" TXT_EXT | |
| 74 }, | |
| 75 | |
| 76 // A normal avi should get .avi and not .avi.avi | |
| 77 {"", "https://blah.google.com/misc/2.avi", "video/x-msvideo", L"2.avi"}, | |
| 78 | |
| 79 // Spaces in the disposition file name | |
| 80 {"filename=My Downloaded File.exe", | |
| 81 "http://www.frontpagehacker.com/a_download.exe", | |
| 82 "application/octet-stream", | |
| 83 L"My Downloaded File.exe"}, | |
| 84 | |
| 85 {"filename=my-cat", | |
| 86 "http://www.example.com/my-cat", | |
| 87 "image/jpeg", | |
| 88 L"my-cat" JPEG_EXT | |
| 89 }, | |
| 90 | |
| 91 {"filename=my-cat", | |
| 92 "http://www.example.com/my-cat", | |
| 93 "text/plain", | |
| 94 L"my-cat.txt"}, | |
| 95 | |
| 96 {"filename=my-cat", | |
| 97 "http://www.example.com/my-cat", | |
| 98 "text/html", | |
| 99 L"my-cat" HTML_EXT | |
| 100 }, | |
| 101 | |
| 102 {"filename=my-cat", | |
| 103 "http://www.example.com/my-cat", | |
| 104 "dance/party", | |
| 105 L"my-cat"}, | |
| 106 | |
| 107 {"filename=my-cat.jpg", | |
| 108 "http://www.example.com/my-cat.jpg", | |
| 109 "text/plain", | |
| 110 L"my-cat.jpg"}, | |
| 111 | |
| 112 // .exe tests. | |
| 113 #if defined(OS_WIN) | |
| 114 {"filename=evil.exe", | |
| 115 "http://www.goodguy.com/evil.exe", | |
| 116 "image/jpeg", | |
| 117 L"evil.exe"}, | |
| 118 | |
| 119 {"filename=ok.exe", | |
| 120 "http://www.goodguy.com/ok.exe", | |
| 121 "binary/octet-stream", | |
| 122 L"ok.exe"}, | |
| 123 | |
| 124 {"filename=evil.dll", | |
| 125 "http://www.goodguy.com/evil.dll", | |
| 126 "dance/party", | |
| 127 L"evil.dll"}, | |
| 128 | |
| 129 {"filename=evil", | |
| 130 "http://www.goodguy.com/evil.exe", | |
| 131 "application/rss+xml", | |
| 132 L"evil"}, | |
| 133 | |
| 134 // Test truncation of trailing dots and spaces | |
| 135 {"filename=evil.exe ", | |
| 136 "http://www.goodguy.com/evil.exe ", | |
| 137 "binary/octet-stream", | |
| 138 L"evil.exe"}, | |
| 139 | |
| 140 {"filename=evil.exe.", | |
| 141 "http://www.goodguy.com/evil.exe.", | |
| 142 "binary/octet-stream", | |
| 143 L"evil.exe"}, | |
| 144 | |
| 145 {"filename=evil.exe. . .", | |
| 146 "http://www.goodguy.com/evil.exe. . .", | |
| 147 "binary/octet-stream", | |
| 148 L"evil.exe"}, | |
| 149 | |
| 150 {"filename=evil.", | |
| 151 "http://www.goodguy.com/evil.", | |
| 152 "binary/octet-stream", | |
| 153 L"evil"}, | |
| 154 | |
| 155 {"filename=. . . . .", | |
| 156 "http://www.goodguy.com/. . . . .", | |
| 157 "binary/octet-stream", | |
| 158 L"download"}, | |
| 159 | |
| 160 #endif // OS_WIN | |
| 161 | |
| 162 {"filename=utils.js", | |
| 163 "http://www.goodguy.com/utils.js", | |
| 164 "application/x-javascript", | |
| 165 L"utils.js"}, | |
| 166 | |
| 167 {"filename=contacts.js", | |
| 168 "http://www.goodguy.com/contacts.js", | |
| 169 "application/json", | |
| 170 L"contacts.js"}, | |
| 171 | |
| 172 {"filename=utils.js", | |
| 173 "http://www.goodguy.com/utils.js", | |
| 174 "text/javascript", | |
| 175 L"utils.js"}, | |
| 176 | |
| 177 {"filename=utils.js", | |
| 178 "http://www.goodguy.com/utils.js", | |
| 179 "text/javascript;version=2", | |
| 180 L"utils.js"}, | |
| 181 | |
| 182 {"filename=utils.js", | |
| 183 "http://www.goodguy.com/utils.js", | |
| 184 "application/ecmascript", | |
| 185 L"utils.js"}, | |
| 186 | |
| 187 {"filename=utils.js", | |
| 188 "http://www.goodguy.com/utils.js", | |
| 189 "application/ecmascript;version=4", | |
| 190 L"utils.js"}, | |
| 191 | |
| 192 {"filename=program.exe", | |
| 193 "http://www.goodguy.com/program.exe", | |
| 194 "application/foo-bar", | |
| 195 L"program.exe"}, | |
| 196 | |
| 197 {"filename=../foo.txt", | |
| 198 "http://www.evil.com/../foo.txt", | |
| 199 "text/plain", | |
| 200 L"_foo.txt"}, | |
| 201 | |
| 202 {"filename=..\\foo.txt", | |
| 203 "http://www.evil.com/..\\foo.txt", | |
| 204 "text/plain", | |
| 205 L"_foo.txt" | |
| 206 }, | |
| 207 | |
| 208 {"filename=.hidden", | |
| 209 "http://www.evil.com/.hidden", | |
| 210 "text/plain", | |
| 211 L"hidden" TXT_EXT | |
| 212 }, | |
| 213 | |
| 214 {"filename=trailing.", | |
| 215 "http://www.evil.com/trailing.", | |
| 216 "dance/party", | |
| 217 L"trailing" | |
| 218 }, | |
| 219 | |
| 220 {"filename=trailing.", | |
| 221 "http://www.evil.com/trailing.", | |
| 222 "text/plain", | |
| 223 L"trailing" TXT_EXT | |
| 224 }, | |
| 225 | |
| 226 {"filename=.", | |
| 227 "http://www.evil.com/.", | |
| 228 "dance/party", | |
| 229 L"download"}, | |
| 230 | |
| 231 {"filename=..", | |
| 232 "http://www.evil.com/..", | |
| 233 "dance/party", | |
| 234 L"download"}, | |
| 235 | |
| 236 {"filename=...", | |
| 237 "http://www.evil.com/...", | |
| 238 "dance/party", | |
| 239 L"download"}, | |
| 240 | |
| 241 // Note that this one doesn't have "filename=" on it. | |
| 242 {"a_file_name.txt", | |
| 243 "http://www.evil.com/", | |
| 244 "image/jpeg", | |
| 245 L"download" JPEG_EXT | |
| 246 }, | |
| 247 | |
| 248 {"filename=", | |
| 249 "http://www.evil.com/", | |
| 250 "image/jpeg", | |
| 251 L"download" JPEG_EXT | |
| 252 }, | |
| 253 | |
| 254 {"filename=simple", | |
| 255 "http://www.example.com/simple", | |
| 256 "application/octet-stream", | |
| 257 L"simple"}, | |
| 258 | |
| 259 {"filename=COM1", | |
| 260 "http://www.goodguy.com/COM1", | |
| 261 "application/foo-bar", | |
| 262 #if defined(OS_WIN) | |
| 263 L"_COM1" | |
| 264 #else | |
| 265 L"COM1" | |
| 266 #endif | |
| 267 }, | |
| 268 | |
| 269 {"filename=COM4.txt", | |
| 270 "http://www.goodguy.com/COM4.txt", | |
| 271 "text/plain", | |
| 272 #if defined(OS_WIN) | |
| 273 L"_COM4.txt" | |
| 274 #else | |
| 275 L"COM4.txt" | |
| 276 #endif | |
| 277 }, | |
| 278 | |
| 279 {"filename=lpt1.TXT", | |
| 280 "http://www.goodguy.com/lpt1.TXT", | |
| 281 "text/plain", | |
| 282 #if defined(OS_WIN) | |
| 283 L"_lpt1.TXT" | |
| 284 #else | |
| 285 L"lpt1.TXT" | |
| 286 #endif | |
| 287 }, | |
| 288 | |
| 289 {"filename=clock$.txt", | |
| 290 "http://www.goodguy.com/clock$.txt", | |
| 291 "text/plain", | |
| 292 #if defined(OS_WIN) | |
| 293 L"_clock$.txt" | |
| 294 #else | |
| 295 L"clock$.txt" | |
| 296 #endif | |
| 297 }, | |
| 298 | |
| 299 {"filename=mycom1.foo", | |
| 300 "http://www.goodguy.com/mycom1.foo", | |
| 301 "text/plain", | |
| 302 L"mycom1.foo"}, | |
| 303 | |
| 304 {"filename=Setup.exe.local", | |
| 305 "http://www.badguy.com/Setup.exe.local", | |
| 306 "application/foo-bar", | |
| 307 #if defined(OS_WIN) | |
| 308 L"Setup.exe.download" | |
| 309 #else | |
| 310 L"Setup.exe.local" | |
| 311 #endif | |
| 312 }, | |
| 313 | |
| 314 {"filename=Setup.exe.local.local", | |
| 315 "http://www.badguy.com/Setup.exe.local", | |
| 316 "application/foo-bar", | |
| 317 #if defined(OS_WIN) | |
| 318 L"Setup.exe.local.download" | |
| 319 #else | |
| 320 L"Setup.exe.local.local" | |
| 321 #endif | |
| 322 }, | |
| 323 | |
| 324 {"filename=Setup.exe.lnk", | |
| 325 "http://www.badguy.com/Setup.exe.lnk", | |
| 326 "application/foo-bar", | |
| 327 #if defined(OS_WIN) | |
| 328 L"Setup.exe.download" | |
| 329 #else | |
| 330 L"Setup.exe.lnk" | |
| 331 #endif | |
| 332 }, | |
| 333 | |
| 334 {"filename=Desktop.ini", | |
| 335 "http://www.badguy.com/Desktop.ini", | |
| 336 "application/foo-bar", | |
| 337 #if defined(OS_WIN) | |
| 338 L"_Desktop.ini" | |
| 339 #else | |
| 340 L"Desktop.ini" | |
| 341 #endif | |
| 342 }, | |
| 343 | |
| 344 {"filename=Thumbs.db", | |
| 345 "http://www.badguy.com/Thumbs.db", | |
| 346 "application/foo-bar", | |
| 347 #if defined(OS_WIN) | |
| 348 L"_Thumbs.db" | |
| 349 #else | |
| 350 L"Thumbs.db" | |
| 351 #endif | |
| 352 }, | |
| 353 | |
| 354 {"filename=source.jpg", | |
| 355 "http://www.hotmail.com", | |
| 356 "application/x-javascript", | |
| 357 L"source.jpg" | |
| 358 }, | |
| 359 | |
| 360 // NetUtilTest.{GetSuggestedFilename, GetFileNameFromCD} test these | |
| 361 // more thoroughly. Tested below are a small set of samples. | |
| 362 {"attachment; filename=\"%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg\"", | |
| 363 "http://www.examples.com/", | |
| 364 "image/jpeg", | |
| 365 L"\uc608\uc220 \uc608\uc220.jpg"}, | |
| 366 | |
| 367 {"attachment; name=abc de.pdf", | |
| 368 "http://www.examples.com/q.cgi?id=abc", | |
| 369 "application/octet-stream", | |
| 370 L"abc de.pdf"}, | |
| 371 | |
| 372 {"filename=\"=?EUC-JP?Q?=B7=DD=BD=D13=2Epng?=\"", | |
| 373 "http://www.example.com/path", | |
| 374 "image/png", | |
| 375 L"\x82b8\x8853" L"3.png"}, | |
| 376 | |
| 377 // The following two have invalid CD headers and filenames come | |
| 378 // from the URL. | |
| 379 {"attachment; filename==?iiso88591?Q?caf=EG?=", | |
| 380 "http://www.example.com/test%20123", | |
| 381 "image/jpeg", | |
| 382 L"test 123" JPEG_EXT | |
| 383 }, | |
| 384 | |
| 385 {"malformed_disposition", | |
| 386 "http://www.google.com/%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg", | |
| 387 "image/jpeg", | |
| 388 L"\uc608\uc220 \uc608\uc220.jpg"}, | |
| 389 | |
| 390 // Invalid C-D. No filename from URL. Falls back to 'download'. | |
| 391 {"attachment; filename==?iso88591?Q?caf=E3?", | |
| 392 "http://www.google.com/path1/path2/", | |
| 393 "image/jpeg", | |
| 394 L"download" JPEG_EXT | |
| 395 }, | |
| 396 | |
| 397 // Issue=5772. | |
| 398 {"", | |
| 399 "http://www.example.com/foo.tar.gz", | |
| 400 "application/x-tar", | |
| 401 L"foo.tar.gz"}, | |
| 402 | |
| 403 // Issue=52250. | |
| 404 {"", | |
| 405 "http://www.example.com/foo.tgz", | |
| 406 "application/x-tar", | |
| 407 L"foo.tgz"}, | |
| 408 | |
| 409 // Issue=7337. | |
| 410 {"", | |
| 411 "http://maged.lordaeron.org/blank.reg", | |
| 412 "text/x-registry", | |
| 413 L"blank.reg"}, | |
| 414 | |
| 415 {"", | |
| 416 "http://www.example.com/bar.tar", | |
| 417 "application/x-tar", | |
| 418 L"bar.tar"}, | |
| 419 | |
| 420 {"", | |
| 421 "http://www.example.com/bar.bogus", | |
| 422 "application/x-tar", | |
| 423 L"bar.bogus" | |
| 424 }, | |
| 425 | |
| 426 // http://code.google.com/p/chromium/issues/detail?id=20337 | |
| 427 {"filename=.download.txt", | |
| 428 "http://www.example.com/.download.txt", | |
| 429 "text/plain", | |
| 430 L"download.txt"}, | |
| 431 | |
| 432 // Issue=56855. | |
| 433 {"", | |
| 434 "http://www.example.com/bar.sh", | |
| 435 "application/x-sh", | |
| 436 L"bar.sh" | |
| 437 }, | |
| 438 }; | |
| 439 | |
| 440 // Tests to ensure that the file names we generate from hints from the server | |
| 441 // (content-disposition, URL name, etc) don't cause security holes. | |
| 442 TEST(DownloadUtilTest, GenerateFileName) { | |
| 443 #if defined(OS_POSIX) && !defined(OS_MACOSX) | |
| 444 // This test doesn't run when the locale is not UTF-8 because some of the | |
| 445 // string conversions fail. This is OK (we have the default value) but they | |
| 446 // don't match our expectations. | |
| 447 std::string locale = setlocale(LC_CTYPE, NULL); | |
| 448 StringToLowerASCII(&locale); | |
| 449 EXPECT_NE(std::string::npos, locale.find("utf-8")) | |
| 450 << "Your locale (" << locale << ") must be set to UTF-8 " | |
| 451 << "for this test to pass!"; | |
| 452 #endif | |
| 453 | |
| 454 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGenerateFileNameTestCases); ++i) { | |
| 455 FilePath generated_name; | |
| 456 download_util::GenerateFileName(GURL(kGenerateFileNameTestCases[i].url), | |
| 457 kGenerateFileNameTestCases[i].disposition, | |
| 458 "", | |
| 459 kGenerateFileNameTestCases[i].mime_type, | |
| 460 &generated_name); | |
| 461 EXPECT_EQ(kGenerateFileNameTestCases[i].expected_name, | |
| 462 file_util::FilePathAsWString(generated_name)) << i; | |
| 463 } | |
| 464 | |
| 465 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGenerateFileNameTestCases); ++i) { | |
| 466 FilePath generated_name; | |
| 467 download_util::GenerateFileName(GURL(kGenerateFileNameTestCases[i].url), | |
| 468 kGenerateFileNameTestCases[i].disposition, | |
| 469 "GBK", | |
| 470 kGenerateFileNameTestCases[i].mime_type, | |
| 471 &generated_name); | |
| 472 EXPECT_EQ(kGenerateFileNameTestCases[i].expected_name, | |
| 473 file_util::FilePathAsWString(generated_name)) << i; | |
| 474 } | |
| 475 | |
| 476 // A couple of cases with raw 8bit characters in C-D. | |
| 477 { | |
| 478 FilePath generated_name; | |
| 479 download_util::GenerateFileName(GURL("http://www.example.com/images?id=3"), | |
| 480 "attachment; filename=caf\xc3\xa9.png", | |
| 481 "iso-8859-1", | |
| 482 "image/png", | |
| 483 &generated_name); | |
| 484 EXPECT_EQ(L"caf\u00e9.png", file_util::FilePathAsWString(generated_name)); | |
| 485 } | |
| 486 | |
| 487 { | |
| 488 FilePath generated_name; | |
| 489 download_util::GenerateFileName(GURL("http://www.example.com/images?id=3"), | |
| 490 "attachment; filename=caf\xe5.png", | |
| 491 "windows-1253", | |
| 492 "image/png", | |
| 493 &generated_name); | |
| 494 EXPECT_EQ(L"caf\u03b5.png", file_util::FilePathAsWString(generated_name)); | |
| 495 } | |
| 496 } | |
| 497 | |
| 498 const struct { | |
| 499 const FilePath::CharType* path; | |
| 500 const char* mime_type; | |
| 501 const FilePath::CharType* expected_path; | |
| 502 } kSafeFilenameCases[] = { | |
| 503 #if defined(OS_WIN) | |
| 504 { FILE_PATH_LITERAL("C:\\foo\\bar.htm"), | |
| 505 "text/html", | |
| 506 FILE_PATH_LITERAL("C:\\foo\\bar.htm") }, | |
| 507 { FILE_PATH_LITERAL("C:\\foo\\bar.html"), | |
| 508 "text/html", | |
| 509 FILE_PATH_LITERAL("C:\\foo\\bar.html") }, | |
| 510 { FILE_PATH_LITERAL("C:\\foo\\bar"), | |
| 511 "text/html", | |
| 512 FILE_PATH_LITERAL("C:\\foo\\bar.htm") }, | |
| 513 | |
| 514 { FILE_PATH_LITERAL("C:\\bar.html"), | |
| 515 "image/png", | |
| 516 FILE_PATH_LITERAL("C:\\bar.html") }, | |
| 517 { FILE_PATH_LITERAL("C:\\bar"), | |
| 518 "image/png", | |
| 519 FILE_PATH_LITERAL("C:\\bar.png") }, | |
| 520 | |
| 521 { FILE_PATH_LITERAL("C:\\foo\\bar.exe"), | |
| 522 "text/html", | |
| 523 FILE_PATH_LITERAL("C:\\foo\\bar.exe") }, | |
| 524 { FILE_PATH_LITERAL("C:\\foo\\bar.exe"), | |
| 525 "image/gif", | |
| 526 FILE_PATH_LITERAL("C:\\foo\\bar.exe") }, | |
| 527 | |
| 528 { FILE_PATH_LITERAL("C:\\foo\\google.com"), | |
| 529 "text/html", | |
| 530 FILE_PATH_LITERAL("C:\\foo\\google.com") }, | |
| 531 | |
| 532 { FILE_PATH_LITERAL("C:\\foo\\con.htm"), | |
| 533 "text/html", | |
| 534 FILE_PATH_LITERAL("C:\\foo\\_con.htm") }, | |
| 535 { FILE_PATH_LITERAL("C:\\foo\\con"), | |
| 536 "text/html", | |
| 537 FILE_PATH_LITERAL("C:\\foo\\_con.htm") }, | |
| 538 #else // !defined(OS_WIN) | |
| 539 { FILE_PATH_LITERAL("/foo/bar.htm"), | |
| 540 "text/html", | |
| 541 FILE_PATH_LITERAL("/foo/bar.htm") }, | |
| 542 { FILE_PATH_LITERAL("/foo/bar.html"), | |
| 543 "text/html", | |
| 544 FILE_PATH_LITERAL("/foo/bar.html") }, | |
| 545 { FILE_PATH_LITERAL("/foo/bar"), | |
| 546 "text/html", | |
| 547 FILE_PATH_LITERAL("/foo/bar.html") }, | |
| 548 | |
| 549 { FILE_PATH_LITERAL("/bar.html"), | |
| 550 "image/png", | |
| 551 FILE_PATH_LITERAL("/bar.html") }, | |
| 552 { FILE_PATH_LITERAL("/bar"), | |
| 553 "image/png", | |
| 554 FILE_PATH_LITERAL("/bar.png") }, | |
| 555 | |
| 556 { FILE_PATH_LITERAL("/foo/bar.exe"), | |
| 557 "image/gif", | |
| 558 FILE_PATH_LITERAL("/foo/bar.exe") }, | |
| 559 | |
| 560 { FILE_PATH_LITERAL("/foo/google.com"), | |
| 561 "text/html", | |
| 562 FILE_PATH_LITERAL("/foo/google.com") }, | |
| 563 | |
| 564 { FILE_PATH_LITERAL("/foo/con.htm"), | |
| 565 "text/html", | |
| 566 FILE_PATH_LITERAL("/foo/con.htm") }, | |
| 567 { FILE_PATH_LITERAL("/foo/con"), | |
| 568 "text/html", | |
| 569 FILE_PATH_LITERAL("/foo/con.html") }, | |
| 570 #endif // !defined(OS_WIN) | |
| 571 }; | |
| 572 | |
| 573 TEST(DownloadUtilTest, GenerateSafeFileName) { | |
| 574 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSafeFilenameCases); ++i) { | |
| 575 FilePath path(kSafeFilenameCases[i].path); | |
| 576 download_util::GenerateSafeFileName(kSafeFilenameCases[i].mime_type, &path); | |
| 577 EXPECT_EQ(kSafeFilenameCases[i].expected_path, path.value()) << i; | |
| 578 } | |
| 579 } | |
| 580 | |
| 581 } // namespace | |
| 582 | |
| OLD | NEW |