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