OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <string> | 5 #include <string> |
6 | 6 |
7 #include "base/string_util.h" | 7 #include "base/string_util.h" |
8 #include "build/build_config.h" | 8 #include "build/build_config.h" |
9 #include "chrome/browser/chrome_thread.h" | 9 #include "chrome/browser/chrome_thread.h" |
10 #include "chrome/browser/download/download_file.h" | 10 #include "chrome/browser/download/download_file.h" |
11 #include "chrome/browser/download/download_file_manager.h" | 11 #include "chrome/browser/download/download_file_manager.h" |
12 #include "chrome/browser/download/download_manager.h" | 12 #include "chrome/browser/download/download_manager.h" |
13 #include "chrome/browser/download/download_util.h" | 13 #include "chrome/browser/download/download_util.h" |
14 #include "chrome/browser/history/download_types.h" | 14 #include "chrome/browser/history/download_types.h" |
15 #include "chrome/common/pref_names.h" | 15 #include "chrome/common/pref_names.h" |
16 #include "chrome/test/testing_profile.h" | 16 #include "chrome/test/testing_profile.h" |
17 #include "testing/gmock/include/gmock/gmock.h" | 17 #include "testing/gmock/include/gmock/gmock.h" |
18 #include "testing/gmock_mutant.h" | 18 #include "testing/gmock_mutant.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
20 | 20 |
21 #if defined(OS_POSIX) && !defined(OS_MACOSX) | |
22 #include <locale.h> | |
23 #endif | |
24 | |
25 #if defined(OS_WIN) | |
26 #define JPEG_EXT L".jpg" | |
27 #define HTML_EXT L".htm" | |
28 #define TXT_EXT L".txt" | |
29 #define TAR_EXT L".tar" | |
30 #elif defined(OS_MACOSX) | |
31 #define JPEG_EXT L".jpeg" | |
32 #define HTML_EXT L".html" | |
33 #define TXT_EXT L".txt" | |
34 #define TAR_EXT L".tar" | |
35 #else | |
36 #define JPEG_EXT L".jpg" | |
37 #define HTML_EXT L".html" | |
38 #define TXT_EXT L".txt" | |
39 #define TAR_EXT L".tar" | |
40 #endif | |
41 | |
42 class MockDownloadManager : public DownloadManager { | 21 class MockDownloadManager : public DownloadManager { |
43 public: | 22 public: |
44 // Override some functions. | 23 // Override some functions. |
45 virtual void UpdateAppIcon() { } | 24 virtual void UpdateAppIcon() { } |
46 virtual void UpdateHistoryForDownload(DownloadItem*) { } | 25 virtual void UpdateHistoryForDownload(DownloadItem*) { } |
47 virtual void ContinueDownloadFinished(DownloadItem*) { } | 26 virtual void ContinueDownloadFinished(DownloadItem*) { } |
48 }; | 27 }; |
49 | 28 |
50 class DownloadManagerTest : public testing::Test { | 29 class DownloadManagerTest : public testing::Test { |
51 public: | 30 public: |
52 DownloadManagerTest() | 31 DownloadManagerTest() |
53 : profile_(new TestingProfile()), | 32 : profile_(new TestingProfile()), |
54 download_manager_(new MockDownloadManager()), | 33 download_manager_(new MockDownloadManager()), |
55 ui_thread_(ChromeThread::UI, &message_loop_) { | 34 ui_thread_(ChromeThread::UI, &message_loop_) { |
56 download_manager_->Init(profile_.get()); | 35 download_manager_->Init(profile_.get()); |
57 } | 36 } |
58 | 37 |
59 ~DownloadManagerTest() { | 38 ~DownloadManagerTest() { |
60 // profile_ must outlive download_manager_, so we explicitly delete | 39 // profile_ must outlive download_manager_, so we explicitly delete |
61 // download_manager_ first. | 40 // download_manager_ first. |
62 download_manager_ = NULL; | 41 download_manager_ = NULL; |
63 profile_.reset(NULL); | 42 profile_.reset(NULL); |
64 message_loop_.RunAllPending(); | 43 message_loop_.RunAllPending(); |
65 } | 44 } |
66 | 45 |
67 void GetGeneratedFilename(const std::string& content_disposition, | |
68 const std::string& url, | |
69 const std::string& mime_type, | |
70 const std::string& referrer_charset, | |
71 std::wstring* generated_name_string) { | |
72 DownloadCreateInfo info; | |
73 info.content_disposition = content_disposition; | |
74 info.url = GURL(url); | |
75 info.mime_type = mime_type; | |
76 info.referrer_charset = referrer_charset; | |
77 FilePath generated_name; | |
78 DownloadManager::GenerateFileNameFromInfo(&info, &generated_name); | |
79 *generated_name_string = generated_name.ToWStringHack(); | |
80 } | |
81 | |
82 void AddDownloadToFileManager(int id, DownloadFile* download) { | 46 void AddDownloadToFileManager(int id, DownloadFile* download) { |
83 file_manager()->downloads_[id] = download; | 47 file_manager()->downloads_[id] = download; |
84 } | 48 } |
85 | 49 |
86 protected: | 50 protected: |
87 scoped_ptr<TestingProfile> profile_; | 51 scoped_ptr<TestingProfile> profile_; |
88 scoped_refptr<DownloadManager> download_manager_; | 52 scoped_refptr<DownloadManager> download_manager_; |
89 scoped_refptr<DownloadFileManager> file_manager_; | 53 scoped_refptr<DownloadFileManager> file_manager_; |
90 MessageLoopForUI message_loop_; | 54 MessageLoopForUI message_loop_; |
91 ChromeThread ui_thread_; | 55 ChromeThread ui_thread_; |
92 | 56 |
93 DownloadFileManager* file_manager() { | 57 DownloadFileManager* file_manager() { |
94 if (!file_manager_) { | 58 if (!file_manager_) { |
95 file_manager_ = new DownloadFileManager(NULL); | 59 file_manager_ = new DownloadFileManager(NULL); |
96 download_manager_->file_manager_ = file_manager_; | 60 download_manager_->file_manager_ = file_manager_; |
97 } | 61 } |
98 return file_manager_; | 62 return file_manager_; |
99 } | 63 } |
100 | 64 |
101 DISALLOW_COPY_AND_ASSIGN(DownloadManagerTest); | 65 DISALLOW_COPY_AND_ASSIGN(DownloadManagerTest); |
102 }; | 66 }; |
103 | 67 |
104 namespace { | 68 namespace { |
105 | 69 |
106 const struct { | 70 const struct { |
107 const char* disposition; | |
108 const char* url; | |
109 const char* mime_type; | |
110 const wchar_t* expected_name; | |
111 } kGeneratedFiles[] = { | |
112 // No 'filename' keyword in the disposition, use the URL | |
113 {"a_file_name.txt", | |
114 "http://www.evil.com/my_download.txt", | |
115 "text/plain", | |
116 L"my_download.txt"}, | |
117 | |
118 // Disposition has relative paths, remove them | |
119 {"filename=../../../../././../a_file_name.txt", | |
120 "http://www.evil.com/my_download.txt", | |
121 "text/plain", | |
122 L"a_file_name.txt"}, | |
123 | |
124 // Disposition has parent directories, remove them | |
125 {"filename=dir1/dir2/a_file_name.txt", | |
126 "http://www.evil.com/my_download.txt", | |
127 "text/plain", | |
128 L"a_file_name.txt"}, | |
129 | |
130 // No useful information in disposition or URL, use default | |
131 {"", "http://www.truncated.com/path/", "text/plain", | |
132 L"download" TXT_EXT | |
133 }, | |
134 | |
135 // A normal avi should get .avi and not .avi.avi | |
136 {"", "https://blah.google.com/misc/2.avi", "video/x-msvideo", L"2.avi"}, | |
137 | |
138 // Spaces in the disposition file name | |
139 {"filename=My Downloaded File.exe", | |
140 "http://www.frontpagehacker.com/a_download.exe", | |
141 "application/octet-stream", | |
142 L"My Downloaded File.exe"}, | |
143 | |
144 // This block tests whether we append extensions based on MIME types; | |
145 // we don't do this on Linux, so we skip the tests rather than #ifdef | |
146 // them up. | |
147 #if !defined(OS_POSIX) || defined(OS_MACOSX) | |
148 {"filename=my-cat", | |
149 "http://www.example.com/my-cat", | |
150 "image/jpeg", | |
151 L"my-cat" JPEG_EXT | |
152 }, | |
153 | |
154 {"filename=my-cat", | |
155 "http://www.example.com/my-cat", | |
156 "text/plain", | |
157 L"my-cat.txt"}, | |
158 | |
159 {"filename=my-cat", | |
160 "http://www.example.com/my-cat", | |
161 "text/html", | |
162 L"my-cat" HTML_EXT | |
163 }, | |
164 | |
165 {"filename=my-cat", | |
166 "http://www.example.com/my-cat", | |
167 "dance/party", | |
168 L"my-cat"}, | |
169 #endif // !defined(OS_POSIX) || defined(OS_MACOSX) | |
170 | |
171 {"filename=my-cat.jpg", | |
172 "http://www.example.com/my-cat.jpg", | |
173 "text/plain", | |
174 L"my-cat.jpg"}, | |
175 | |
176 // .exe tests. | |
177 #if defined(OS_WIN) | |
178 {"filename=evil.exe", | |
179 "http://www.goodguy.com/evil.exe", | |
180 "image/jpeg", | |
181 L"evil.jpg"}, | |
182 | |
183 {"filename=ok.exe", | |
184 "http://www.goodguy.com/ok.exe", | |
185 "binary/octet-stream", | |
186 L"ok.exe"}, | |
187 | |
188 {"filename=evil.exe.exe", | |
189 "http://www.goodguy.com/evil.exe.exe", | |
190 "dance/party", | |
191 L"evil.exe.download"}, | |
192 | |
193 {"filename=evil.exe", | |
194 "http://www.goodguy.com/evil.exe", | |
195 "application/xml", | |
196 L"evil.xml"}, | |
197 | |
198 {"filename=evil.exe", | |
199 "http://www.goodguy.com/evil.exe", | |
200 "application/html+xml", | |
201 L"evil.download"}, | |
202 | |
203 {"filename=evil.exe", | |
204 "http://www.goodguy.com/evil.exe", | |
205 "application/rss+xml", | |
206 L"evil.download"}, | |
207 | |
208 // Test truncation of trailing dots and spaces | |
209 {"filename=evil.exe ", | |
210 "http://www.goodguy.com/evil.exe ", | |
211 "binary/octet-stream", | |
212 L"evil.exe"}, | |
213 | |
214 {"filename=evil.exe.", | |
215 "http://www.goodguy.com/evil.exe.", | |
216 "binary/octet-stream", | |
217 L"evil.exe"}, | |
218 | |
219 {"filename=evil.exe. . .", | |
220 "http://www.goodguy.com/evil.exe. . .", | |
221 "binary/octet-stream", | |
222 L"evil.exe"}, | |
223 | |
224 {"filename=evil.", | |
225 "http://www.goodguy.com/evil.", | |
226 "binary/octet-stream", | |
227 L"evil"}, | |
228 | |
229 {"filename=. . . . .", | |
230 "http://www.goodguy.com/. . . . .", | |
231 "binary/octet-stream", | |
232 L"download"}, | |
233 | |
234 #endif // OS_WIN | |
235 | |
236 {"filename=utils.js", | |
237 "http://www.goodguy.com/utils.js", | |
238 "application/x-javascript", | |
239 L"utils.js"}, | |
240 | |
241 {"filename=contacts.js", | |
242 "http://www.goodguy.com/contacts.js", | |
243 "application/json", | |
244 L"contacts.js"}, | |
245 | |
246 {"filename=utils.js", | |
247 "http://www.goodguy.com/utils.js", | |
248 "text/javascript", | |
249 L"utils.js"}, | |
250 | |
251 {"filename=utils.js", | |
252 "http://www.goodguy.com/utils.js", | |
253 "text/javascript;version=2", | |
254 L"utils.js"}, | |
255 | |
256 {"filename=utils.js", | |
257 "http://www.goodguy.com/utils.js", | |
258 "application/ecmascript", | |
259 L"utils.js"}, | |
260 | |
261 {"filename=utils.js", | |
262 "http://www.goodguy.com/utils.js", | |
263 "application/ecmascript;version=4", | |
264 L"utils.js"}, | |
265 | |
266 {"filename=program.exe", | |
267 "http://www.goodguy.com/program.exe", | |
268 "application/foo-bar", | |
269 L"program.exe"}, | |
270 | |
271 {"filename=../foo.txt", | |
272 "http://www.evil.com/../foo.txt", | |
273 "text/plain", | |
274 L"foo.txt"}, | |
275 | |
276 {"filename=..\\foo.txt", | |
277 "http://www.evil.com/..\\foo.txt", | |
278 "text/plain", | |
279 #if defined(OS_WIN) | |
280 L"foo.txt" | |
281 #else | |
282 L"\\foo.txt" | |
283 #endif | |
284 }, | |
285 | |
286 {"filename=.hidden", | |
287 "http://www.evil.com/.hidden", | |
288 "text/plain", | |
289 L"hidden" TXT_EXT | |
290 }, | |
291 | |
292 {"filename=trailing.", | |
293 "http://www.evil.com/trailing.", | |
294 "dance/party", | |
295 L"trailing" | |
296 }, | |
297 | |
298 {"filename=trailing.", | |
299 "http://www.evil.com/trailing.", | |
300 "text/plain", | |
301 L"trailing" TXT_EXT | |
302 }, | |
303 | |
304 {"filename=.", | |
305 "http://www.evil.com/.", | |
306 "dance/party", | |
307 L"download"}, | |
308 | |
309 {"filename=..", | |
310 "http://www.evil.com/..", | |
311 "dance/party", | |
312 L"download"}, | |
313 | |
314 {"filename=...", | |
315 "http://www.evil.com/...", | |
316 "dance/party", | |
317 L"download"}, | |
318 | |
319 // Note that this one doesn't have "filename=" on it. | |
320 {"a_file_name.txt", | |
321 "http://www.evil.com/", | |
322 "image/jpeg", | |
323 L"download" JPEG_EXT | |
324 }, | |
325 | |
326 {"filename=", | |
327 "http://www.evil.com/", | |
328 "image/jpeg", | |
329 L"download" JPEG_EXT | |
330 }, | |
331 | |
332 {"filename=simple", | |
333 "http://www.example.com/simple", | |
334 "application/octet-stream", | |
335 L"simple"}, | |
336 | |
337 {"filename=COM1", | |
338 "http://www.goodguy.com/COM1", | |
339 "application/foo-bar", | |
340 #if defined(OS_WIN) | |
341 L"_COM1" | |
342 #else | |
343 L"COM1" | |
344 #endif | |
345 }, | |
346 | |
347 {"filename=COM4.txt", | |
348 "http://www.goodguy.com/COM4.txt", | |
349 "text/plain", | |
350 #if defined(OS_WIN) | |
351 L"_COM4.txt" | |
352 #else | |
353 L"COM4.txt" | |
354 #endif | |
355 }, | |
356 | |
357 {"filename=lpt1.TXT", | |
358 "http://www.goodguy.com/lpt1.TXT", | |
359 "text/plain", | |
360 #if defined(OS_WIN) | |
361 L"_lpt1.TXT" | |
362 #else | |
363 L"lpt1.TXT" | |
364 #endif | |
365 }, | |
366 | |
367 {"filename=clock$.txt", | |
368 "http://www.goodguy.com/clock$.txt", | |
369 "text/plain", | |
370 #if defined(OS_WIN) | |
371 L"_clock$.txt" | |
372 #else | |
373 L"clock$.txt" | |
374 #endif | |
375 }, | |
376 | |
377 {"filename=mycom1.foo", | |
378 "http://www.goodguy.com/mycom1.foo", | |
379 "text/plain", | |
380 L"mycom1.foo"}, | |
381 | |
382 {"filename=Setup.exe.local", | |
383 "http://www.badguy.com/Setup.exe.local", | |
384 "application/foo-bar", | |
385 #if defined(OS_WIN) | |
386 L"Setup.exe.download" | |
387 #else | |
388 L"Setup.exe.local" | |
389 #endif | |
390 }, | |
391 | |
392 {"filename=Setup.exe.local.local", | |
393 "http://www.badguy.com/Setup.exe.local", | |
394 "application/foo-bar", | |
395 #if defined(OS_WIN) | |
396 L"Setup.exe.local.download" | |
397 #else | |
398 L"Setup.exe.local.local" | |
399 #endif | |
400 }, | |
401 | |
402 {"filename=Setup.exe.lnk", | |
403 "http://www.badguy.com/Setup.exe.lnk", | |
404 "application/foo-bar", | |
405 #if defined(OS_WIN) | |
406 L"Setup.exe.download" | |
407 #else | |
408 L"Setup.exe.lnk" | |
409 #endif | |
410 }, | |
411 | |
412 {"filename=Desktop.ini", | |
413 "http://www.badguy.com/Desktop.ini", | |
414 "application/foo-bar", | |
415 #if defined(OS_WIN) | |
416 L"_Desktop.ini" | |
417 #else | |
418 L"Desktop.ini" | |
419 #endif | |
420 }, | |
421 | |
422 {"filename=Thumbs.db", | |
423 "http://www.badguy.com/Thumbs.db", | |
424 "application/foo-bar", | |
425 #if defined(OS_WIN) | |
426 L"_Thumbs.db" | |
427 #else | |
428 L"Thumbs.db" | |
429 #endif | |
430 }, | |
431 | |
432 {"filename=source.srf", | |
433 "http://www.hotmail.com", | |
434 "image/jpeg", | |
435 L"source.srf" JPEG_EXT | |
436 }, | |
437 | |
438 {"filename=source.jpg", | |
439 "http://www.hotmail.com", | |
440 "application/x-javascript", | |
441 #if defined(OS_WIN) | |
442 L"source.jpg" | |
443 #elif defined(OS_MACOSX) | |
444 L"source.jpg.js" | |
445 #else | |
446 L"source.jpg" | |
447 #endif | |
448 }, | |
449 | |
450 // NetUtilTest.{GetSuggestedFilename, GetFileNameFromCD} test these | |
451 // more thoroughly. Tested below are a small set of samples. | |
452 {"attachment; filename=\"%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg\"", | |
453 "http://www.examples.com/", | |
454 "image/jpeg", | |
455 L"\uc608\uc220 \uc608\uc220.jpg"}, | |
456 | |
457 {"attachment; name=abc de.pdf", | |
458 "http://www.examples.com/q.cgi?id=abc", | |
459 "application/octet-stream", | |
460 L"abc de.pdf"}, | |
461 | |
462 {"filename=\"=?EUC-JP?Q?=B7=DD=BD=D13=2Epng?=\"", | |
463 "http://www.example.com/path", | |
464 "image/png", | |
465 L"\x82b8\x8853" L"3.png"}, | |
466 | |
467 // The following two have invalid CD headers and filenames come | |
468 // from the URL. | |
469 {"attachment; filename==?iiso88591?Q?caf=EG?=", | |
470 "http://www.example.com/test%20123", | |
471 "image/jpeg", | |
472 L"test 123" JPEG_EXT | |
473 }, | |
474 | |
475 {"malformed_disposition", | |
476 "http://www.google.com/%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg", | |
477 "image/jpeg", | |
478 L"\uc608\uc220 \uc608\uc220.jpg"}, | |
479 | |
480 // Invalid C-D. No filename from URL. Falls back to 'download'. | |
481 {"attachment; filename==?iso88591?Q?caf=E3?", | |
482 "http://www.google.com/path1/path2/", | |
483 "image/jpeg", | |
484 L"download" JPEG_EXT | |
485 }, | |
486 | |
487 // Issue=5772. | |
488 {"", | |
489 "http://www.example.com/foo.tar.gz", | |
490 "application/x-tar", | |
491 L"foo.tar.gz"}, | |
492 | |
493 // Issue=7337. | |
494 {"", | |
495 "http://maged.lordaeron.org/blank.reg", | |
496 "text/x-registry", | |
497 L"blank.reg"}, | |
498 | |
499 {"", | |
500 "http://www.example.com/bar.tar", | |
501 "application/x-tar", | |
502 L"bar.tar"}, | |
503 | |
504 {"", | |
505 "http://www.example.com/bar.bogus", | |
506 "application/x-tar", | |
507 L"bar.bogus" TAR_EXT | |
508 }, | |
509 | |
510 // http://code.google.com/p/chromium/issues/detail?id=20337 | |
511 {"filename=.download.txt", | |
512 "http://www.example.com/.download.txt", | |
513 "text/plain", | |
514 L"download.txt"}, | |
515 }; | |
516 | |
517 } // namespace | |
518 | |
519 // Tests to ensure that the file names we generate from hints from the server | |
520 // (content-disposition, URL name, etc) don't cause security holes. | |
521 TEST_F(DownloadManagerTest, TestDownloadFilename) { | |
522 #if defined(OS_POSIX) && !defined(OS_MACOSX) | |
523 // This test doesn't run when the locale is not UTF-8 becuase some of the | |
524 // string conversions fail. This is OK (we have the default value) but they | |
525 // don't match our expectations. | |
526 std::string locale = setlocale(LC_CTYPE, NULL); | |
527 StringToLowerASCII(&locale); | |
528 ASSERT_NE(std::string::npos, locale.find("utf-8")) | |
529 << "Your locale must be set to UTF-8 for this test to pass!"; | |
530 #endif | |
531 | |
532 std::wstring file_name; | |
533 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGeneratedFiles); ++i) { | |
534 GetGeneratedFilename(kGeneratedFiles[i].disposition, | |
535 kGeneratedFiles[i].url, | |
536 kGeneratedFiles[i].mime_type, | |
537 "", | |
538 &file_name); | |
539 EXPECT_EQ(kGeneratedFiles[i].expected_name, file_name); | |
540 GetGeneratedFilename(kGeneratedFiles[i].disposition, | |
541 kGeneratedFiles[i].url, | |
542 kGeneratedFiles[i].mime_type, | |
543 "GBK", | |
544 &file_name); | |
545 EXPECT_EQ(kGeneratedFiles[i].expected_name, file_name); | |
546 } | |
547 | |
548 // A couple of cases with raw 8bit characters in C-D. | |
549 GetGeneratedFilename("attachment; filename=caf\xc3\xa9.png", | |
550 "http://www.example.com/images?id=3", | |
551 "image/png", | |
552 "iso-8859-1", | |
553 &file_name); | |
554 EXPECT_EQ(L"caf\u00e9.png", file_name); | |
555 GetGeneratedFilename("attachment; filename=caf\xe5.png", | |
556 "http://www.example.com/images?id=3", | |
557 "image/png", | |
558 "windows-1253", | |
559 &file_name); | |
560 EXPECT_EQ(L"caf\u03b5.png", file_name); | |
561 } | |
562 | |
563 namespace { | |
564 | |
565 const struct { | |
566 const FilePath::CharType* path; | |
567 const char* mime_type; | |
568 const FilePath::CharType* expected_path; | |
569 } kSafeFilenameCases[] = { | |
570 #if defined(OS_WIN) | |
571 { FILE_PATH_LITERAL("C:\\foo\\bar.htm"), | |
572 "text/html", | |
573 FILE_PATH_LITERAL("C:\\foo\\bar.htm") }, | |
574 { FILE_PATH_LITERAL("C:\\foo\\bar.html"), | |
575 "text/html", | |
576 FILE_PATH_LITERAL("C:\\foo\\bar.html") }, | |
577 { FILE_PATH_LITERAL("C:\\foo\\bar"), | |
578 "text/html", | |
579 FILE_PATH_LITERAL("C:\\foo\\bar.htm") }, | |
580 | |
581 { FILE_PATH_LITERAL("C:\\bar.html"), | |
582 "image/png", | |
583 FILE_PATH_LITERAL("C:\\bar.png") }, | |
584 { FILE_PATH_LITERAL("C:\\bar"), | |
585 "image/png", | |
586 FILE_PATH_LITERAL("C:\\bar.png") }, | |
587 | |
588 { FILE_PATH_LITERAL("C:\\foo\\bar.exe"), | |
589 "text/html", | |
590 FILE_PATH_LITERAL("C:\\foo\\bar.htm") }, | |
591 { FILE_PATH_LITERAL("C:\\foo\\bar.exe"), | |
592 "image/gif", | |
593 FILE_PATH_LITERAL("C:\\foo\\bar.gif") }, | |
594 | |
595 { FILE_PATH_LITERAL("C:\\foo\\google.com"), | |
596 "text/html", | |
597 FILE_PATH_LITERAL("C:\\foo\\google.htm") }, | |
598 | |
599 { FILE_PATH_LITERAL("C:\\foo\\con.htm"), | |
600 "text/html", | |
601 FILE_PATH_LITERAL("C:\\foo\\_con.htm") }, | |
602 { FILE_PATH_LITERAL("C:\\foo\\con"), | |
603 "text/html", | |
604 FILE_PATH_LITERAL("C:\\foo\\_con.htm") }, | |
605 #else | |
606 { FILE_PATH_LITERAL("/foo/bar.htm"), | |
607 "text/html", | |
608 FILE_PATH_LITERAL("/foo/bar.htm") }, | |
609 { FILE_PATH_LITERAL("/foo/bar.html"), | |
610 "text/html", | |
611 FILE_PATH_LITERAL("/foo/bar.html") }, | |
612 { FILE_PATH_LITERAL("/foo/bar"), | |
613 "text/html", | |
614 FILE_PATH_LITERAL("/foo/bar.html") }, | |
615 | |
616 { FILE_PATH_LITERAL("/bar.html"), | |
617 "image/png", | |
618 FILE_PATH_LITERAL("/bar.html.png") }, | |
619 { FILE_PATH_LITERAL("/bar"), | |
620 "image/png", | |
621 FILE_PATH_LITERAL("/bar.png") }, | |
622 | |
623 { FILE_PATH_LITERAL("/foo/bar.exe"), | |
624 "text/html", | |
625 FILE_PATH_LITERAL("/foo/bar.exe.html") }, | |
626 { FILE_PATH_LITERAL("/foo/bar.exe"), | |
627 "image/gif", | |
628 FILE_PATH_LITERAL("/foo/bar.exe.gif") }, | |
629 | |
630 { FILE_PATH_LITERAL("/foo/google.com"), | |
631 "text/html", | |
632 FILE_PATH_LITERAL("/foo/google.com.html") }, | |
633 | |
634 { FILE_PATH_LITERAL("/foo/con.htm"), | |
635 "text/html", | |
636 FILE_PATH_LITERAL("/foo/con.htm") }, | |
637 { FILE_PATH_LITERAL("/foo/con"), | |
638 "text/html", | |
639 FILE_PATH_LITERAL("/foo/con.html") }, | |
640 #endif // OS_WIN | |
641 }; | |
642 | |
643 } // namespace | |
644 | |
645 #if defined(OS_WIN) || defined(OS_MACOSX) | |
646 // TODO(port): port to Linux/BSD. | |
647 TEST_F(DownloadManagerTest, GetSafeFilename) { | |
648 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSafeFilenameCases); ++i) { | |
649 FilePath path(kSafeFilenameCases[i].path); | |
650 download_manager_->GenerateSafeFileName(kSafeFilenameCases[i].mime_type, | |
651 &path); | |
652 EXPECT_EQ(kSafeFilenameCases[i].expected_path, path.value()); | |
653 } | |
654 } | |
655 #endif // defined(OS_WIN) || defined(OS_MACOSX) | |
656 | |
657 namespace { | |
658 | |
659 const struct { | |
660 const char* url; | 71 const char* url; |
661 const char* mime_type; | 72 const char* mime_type; |
662 bool save_as; | 73 bool save_as; |
663 bool prompt_for_download; | 74 bool prompt_for_download; |
664 bool expected_save_as; | 75 bool expected_save_as; |
665 } kStartDownloadCases[] = { | 76 } kStartDownloadCases[] = { |
666 { "http://www.foo.com/dont-open.html", | 77 { "http://www.foo.com/dont-open.html", |
667 "text/html", | 78 "text/html", |
668 false, | 79 false, |
669 false, | 80 false, |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
832 download_manager_->DownloadFinished(i, 1024); | 243 download_manager_->DownloadFinished(i, 1024); |
833 download_manager_->FileSelected(new_path, i, info); | 244 download_manager_->FileSelected(new_path, i, info); |
834 } else { | 245 } else { |
835 download_manager_->FileSelected(new_path, i, info); | 246 download_manager_->FileSelected(new_path, i, info); |
836 download_manager_->DownloadFinished(i, 1024); | 247 download_manager_->DownloadFinished(i, 1024); |
837 } | 248 } |
838 | 249 |
839 message_loop_.RunAllPending(); | 250 message_loop_.RunAllPending(); |
840 } | 251 } |
841 } | 252 } |
OLD | NEW |