Upstream version 10.39.225.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_UNSAFE(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_UNSAFE(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_UNSAFE(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 #if 0
814     { // The filename encoding doesn't match the referrer charset, the system
815       // charset, or UTF-8.
816       // TODO(jshin): we need to handle this case.
817       __LINE__,
818       "http://example.com/V%FDvojov%E1%20psychologie.doc",
819       "",
820       "utf-8",
821       "",
822       "",
823       L"",
824       L"V\u00fdvojov\u00e1 psychologie.doc",
825     },
826 #endif
827     // Raw 8bit characters in C-D
828     {
829       __LINE__,
830       "http://www.example.com/images?id=3",
831       "attachment; filename=caf\xc3\xa9.png",
832       "iso-8859-1",
833       "",
834       "image/png",
835       L"",
836       L"caf\u00e9.png"
837     },
838     {
839       __LINE__,
840       "http://www.example.com/images?id=3",
841       "attachment; filename=caf\xe5.png",
842       "windows-1253",
843       "",
844       "image/png",
845       L"",
846       L"caf\u03b5.png"
847     },
848     { // No 'filename' keyword in the disposition, use the URL
849       __LINE__,
850       "http://www.evil.com/my_download.txt",
851       "a_file_name.txt",
852       "",
853       "",
854       "text/plain",
855       L"download",
856       L"my_download.txt"
857     },
858     { // Spaces in the disposition file name
859       __LINE__,
860       "http://www.frontpagehacker.com/a_download.exe",
861       "filename=My Downloaded File.exe",
862       "",
863       "",
864       "application/octet-stream",
865       L"download",
866       L"My Downloaded File.exe"
867     },
868     { // % encoded
869       __LINE__,
870       "http://www.examples.com/",
871       "attachment; "
872       "filename=\"%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg\"",
873       "",
874       "",
875       "image/jpeg",
876       L"download",
877       L"\uc608\uc220 \uc608\uc220.jpg"
878     },
879     { // name= parameter
880       __LINE__,
881       "http://www.examples.com/q.cgi?id=abc",
882       "attachment; name=abc de.pdf",
883       "",
884       "",
885       "application/octet-stream",
886       L"download",
887       L"abc de.pdf"
888     },
889     {
890       __LINE__,
891       "http://www.example.com/path",
892       "filename=\"=?EUC-JP?Q?=B7=DD=BD=D13=2Epng?=\"",
893       "",
894       "",
895       "image/png",
896       L"download",
897       L"\x82b8\x8853" L"3.png"
898     },
899     { // The following two have invalid CD headers and filenames come from the
900       // URL.
901       __LINE__,
902       "http://www.example.com/test%20123",
903       "attachment; filename==?iiso88591?Q?caf=EG?=",
904       "",
905       "",
906       "image/jpeg",
907       L"download",
908       L"test 123" JPEG_EXT
909     },
910     {
911       __LINE__,
912       "http://www.google.com/%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg",
913       "malformed_disposition",
914       "",
915       "",
916       "image/jpeg",
917       L"download",
918       L"\uc608\uc220 \uc608\uc220.jpg"
919     },
920     { // Invalid C-D. No filename from URL. Falls back to 'download'.
921       __LINE__,
922       "http://www.google.com/path1/path2/",
923       "attachment; filename==?iso88591?Q?caf=E3?",
924       "",
925       "",
926       "image/jpeg",
927       L"download",
928       L"download" JPEG_EXT
929     },
930   };
931
932   // Tests filename generation.  Once the correct filename is
933   // selected, they should be passed through the validation steps and
934   // a correct extension should be added if necessary.
935   const GenerateFilenameCase generation_tests[] = {
936     // Dotfiles. Ensures preceeding period(s) stripped.
937     {
938       __LINE__,
939       "http://www.google.com/.test.html",
940       "",
941       "",
942       "",
943       "",
944       L"",
945       L"test.html"
946     },
947     {
948       __LINE__,
949       "http://www.google.com/.test",
950       "",
951       "",
952       "",
953       "",
954       L"",
955       L"test"
956     },
957     {
958       __LINE__,
959       "http://www.google.com/..test",
960       "",
961       "",
962       "",
963       "",
964       L"",
965       L"test"
966     },
967     { // Disposition has relative paths, remove directory separators
968       __LINE__,
969       "http://www.evil.com/my_download.txt",
970       "filename=../../../../././../a_file_name.txt",
971       "",
972       "",
973       "text/plain",
974       L"download",
975       L"-..-..-..-.-.-..-a_file_name.txt"
976     },
977     { // Disposition has parent directories, remove directory separators
978       __LINE__,
979       "http://www.evil.com/my_download.txt",
980       "filename=dir1/dir2/a_file_name.txt",
981       "",
982       "",
983       "text/plain",
984       L"download",
985       L"dir1-dir2-a_file_name.txt"
986     },
987     { // Disposition has relative paths, remove directory separators
988       __LINE__,
989       "http://www.evil.com/my_download.txt",
990       "filename=..\\..\\..\\..\\.\\.\\..\\a_file_name.txt",
991       "",
992       "",
993       "text/plain",
994       L"download",
995       L"-..-..-..-.-.-..-a_file_name.txt"
996     },
997     { // Disposition has parent directories, remove directory separators
998       __LINE__,
999       "http://www.evil.com/my_download.txt",
1000       "filename=dir1\\dir2\\a_file_name.txt",
1001       "",
1002       "",
1003       "text/plain",
1004       L"download",
1005       L"dir1-dir2-a_file_name.txt"
1006     },
1007     { // No useful information in disposition or URL, use default
1008       __LINE__,
1009       "http://www.truncated.com/path/",
1010       "",
1011       "",
1012       "",
1013       "text/plain",
1014       L"download",
1015       L"download" TXT_EXT
1016     },
1017     { // Filename looks like HTML?
1018       __LINE__,
1019       "http://www.evil.com/get/malware/here",
1020       "filename=\"<blink>Hello kitty</blink>\"",
1021       "",
1022       "",
1023       "text/plain",
1024       L"default",
1025       L"-blink-Hello kitty--blink-" TXT_EXT
1026     },
1027     { // A normal avi should get .avi and not .avi.avi
1028       __LINE__,
1029       "https://blah.google.com/misc/2.avi",
1030       "",
1031       "",
1032       "",
1033       "video/x-msvideo",
1034       L"download",
1035       L"2.avi"
1036     },
1037     { // Extension generation
1038       __LINE__,
1039       "http://www.example.com/my-cat",
1040       "filename=my-cat",
1041       "",
1042       "",
1043       "image/jpeg",
1044       L"download",
1045       L"my-cat" JPEG_EXT
1046     },
1047     {
1048       __LINE__,
1049       "http://www.example.com/my-cat",
1050       "filename=my-cat",
1051       "",
1052       "",
1053       "text/plain",
1054       L"download",
1055       L"my-cat.txt"
1056     },
1057     {
1058       __LINE__,
1059       "http://www.example.com/my-cat",
1060       "filename=my-cat",
1061       "",
1062       "",
1063       "text/html",
1064       L"download",
1065       L"my-cat" HTML_EXT
1066     },
1067     { // Unknown MIME type
1068       __LINE__,
1069       "http://www.example.com/my-cat",
1070       "filename=my-cat",
1071       "",
1072       "",
1073       "dance/party",
1074       L"download",
1075       L"my-cat"
1076     },
1077     {
1078       __LINE__,
1079       "http://www.example.com/my-cat.jpg",
1080       "filename=my-cat.jpg",
1081       "",
1082       "",
1083       "text/plain",
1084       L"download",
1085       L"my-cat.jpg"
1086     },
1087     // Windows specific tests
1088 #if defined(OS_WIN)
1089     {
1090       __LINE__,
1091       "http://www.goodguy.com/evil.exe",
1092       "filename=evil.exe",
1093       "",
1094       "",
1095       "image/jpeg",
1096       L"download",
1097       L"evil.exe"
1098     },
1099     {
1100       __LINE__,
1101       "http://www.goodguy.com/ok.exe",
1102       "filename=ok.exe",
1103       "",
1104       "",
1105       "binary/octet-stream",
1106       L"download",
1107       L"ok.exe"
1108     },
1109     {
1110       __LINE__,
1111       "http://www.goodguy.com/evil.dll",
1112       "filename=evil.dll",
1113       "",
1114       "",
1115       "dance/party",
1116       L"download",
1117       L"evil.dll"
1118     },
1119     {
1120       __LINE__,
1121       "http://www.goodguy.com/evil.exe",
1122       "filename=evil",
1123       "",
1124       "",
1125       "application/rss+xml",
1126       L"download",
1127       L"evil"
1128     },
1129     // Test truncation of trailing dots and spaces
1130     {
1131       __LINE__,
1132       "http://www.goodguy.com/evil.exe ",
1133       "filename=evil.exe ",
1134       "",
1135       "",
1136       "binary/octet-stream",
1137       L"download",
1138       L"evil.exe"
1139     },
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.",
1163       "filename=evil.",
1164       "",
1165       "",
1166       "binary/octet-stream",
1167       L"download",
1168       L"evil-"
1169     },
1170     {
1171       __LINE__,
1172       "http://www.goodguy.com/. . . . .",
1173       "filename=. . . . .",
1174       "",
1175       "",
1176       "binary/octet-stream",
1177       L"download",
1178       L"download"
1179     },
1180     {
1181       __LINE__,
1182       "http://www.badguy.com/attachment?name=meh.exe%C2%A0",
1183       "attachment; filename=\"meh.exe\xC2\xA0\"",
1184       "",
1185       "",
1186       "binary/octet-stream",
1187       L"",
1188       L"meh.exe-"
1189     },
1190 #endif  // OS_WIN
1191     {
1192       __LINE__,
1193       "http://www.goodguy.com/utils.js",
1194       "filename=utils.js",
1195       "",
1196       "",
1197       "application/x-javascript",
1198       L"download",
1199       L"utils.js"
1200     },
1201     {
1202       __LINE__,
1203       "http://www.goodguy.com/contacts.js",
1204       "filename=contacts.js",
1205       "",
1206       "",
1207       "application/json",
1208       L"download",
1209       L"contacts.js"
1210     },
1211     {
1212       __LINE__,
1213       "http://www.goodguy.com/utils.js",
1214       "filename=utils.js",
1215       "",
1216       "",
1217       "text/javascript",
1218       L"download",
1219       L"utils.js"
1220     },
1221     {
1222       __LINE__,
1223       "http://www.goodguy.com/utils.js",
1224       "filename=utils.js",
1225       "",
1226       "",
1227       "text/javascript;version=2",
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       "application/ecmascript",
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;version=4",
1248       L"download",
1249       L"utils.js"
1250     },
1251     {
1252       __LINE__,
1253       "http://www.goodguy.com/program.exe",
1254       "filename=program.exe",
1255       "",
1256       "",
1257       "application/foo-bar",
1258       L"download",
1259       L"program.exe"
1260     },
1261     {
1262       __LINE__,
1263       "http://www.evil.com/../foo.txt",
1264       "filename=../foo.txt",
1265       "",
1266       "",
1267       "text/plain",
1268       L"download",
1269       L"-foo.txt"
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/.hidden",
1284       "filename=.hidden",
1285       "",
1286       "",
1287       "text/plain",
1288       L"download",
1289       L"hidden" TXT_EXT
1290     },
1291     {
1292       __LINE__,
1293       "http://www.evil.com/trailing.",
1294       "filename=trailing.",
1295       "",
1296       "",
1297       "dance/party",
1298       L"download",
1299 #if defined(OS_WIN)
1300       L"trailing-"
1301 #else
1302       L"trailing"
1303 #endif
1304     },
1305     {
1306       __LINE__,
1307       "http://www.evil.com/trailing.",
1308       "filename=trailing.",
1309       "",
1310       "",
1311       "text/plain",
1312       L"download",
1313 #if defined(OS_WIN)
1314       L"trailing-" TXT_EXT
1315 #else
1316       L"trailing" TXT_EXT
1317 #endif
1318     },
1319     {
1320       __LINE__,
1321       "http://www.evil.com/.",
1322       "filename=.",
1323       "",
1324       "",
1325       "dance/party",
1326       L"download",
1327       L"download"
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     { // Note that this one doesn't have "filename=" on it.
1350       __LINE__,
1351       "http://www.evil.com/",
1352       "a_file_name.txt",
1353       "",
1354       "",
1355       "image/jpeg",
1356       L"download",
1357       L"download" JPEG_EXT
1358     },
1359     {
1360       __LINE__,
1361       "http://www.evil.com/",
1362       "filename=",
1363       "",
1364       "",
1365       "image/jpeg",
1366       L"download",
1367       L"download" JPEG_EXT
1368     },
1369     {
1370       __LINE__,
1371       "http://www.example.com/simple",
1372       "filename=simple",
1373       "",
1374       "",
1375       "application/octet-stream",
1376       L"download",
1377       L"simple"
1378     },
1379     // Reserved words on Windows
1380     {
1381       __LINE__,
1382       "http://www.goodguy.com/COM1",
1383       "filename=COM1",
1384       "",
1385       "",
1386       "application/foo-bar",
1387       L"download",
1388 #if defined(OS_WIN)
1389       L"_COM1"
1390 #else
1391       L"COM1"
1392 #endif
1393     },
1394     {
1395       __LINE__,
1396       "http://www.goodguy.com/COM4.txt",
1397       "filename=COM4.txt",
1398       "",
1399       "",
1400       "text/plain",
1401       L"download",
1402 #if defined(OS_WIN)
1403       L"_COM4.txt"
1404 #else
1405       L"COM4.txt"
1406 #endif
1407     },
1408     {
1409       __LINE__,
1410       "http://www.goodguy.com/lpt1.TXT",
1411       "filename=lpt1.TXT",
1412       "",
1413       "",
1414       "text/plain",
1415       L"download",
1416 #if defined(OS_WIN)
1417       L"_lpt1.TXT"
1418 #else
1419       L"lpt1.TXT"
1420 #endif
1421     },
1422     {
1423       __LINE__,
1424       "http://www.goodguy.com/clock$.txt",
1425       "filename=clock$.txt",
1426       "",
1427       "",
1428       "text/plain",
1429       L"download",
1430 #if defined(OS_WIN)
1431       L"_clock$.txt"
1432 #else
1433       L"clock$.txt"
1434 #endif
1435     },
1436     { // Validation should also apply to sugested name
1437       __LINE__,
1438       "http://www.goodguy.com/blah$.txt",
1439       "filename=clock$.txt",
1440       "",
1441       "clock$.txt",
1442       "text/plain",
1443       L"download",
1444 #if defined(OS_WIN)
1445       L"_clock$.txt"
1446 #else
1447       L"clock$.txt"
1448 #endif
1449     },
1450     {
1451       __LINE__,
1452       "http://www.goodguy.com/mycom1.foo",
1453       "filename=mycom1.foo",
1454       "",
1455       "",
1456       "text/plain",
1457       L"download",
1458       L"mycom1.foo"
1459     },
1460     {
1461       __LINE__,
1462       "http://www.badguy.com/Setup.exe.local",
1463       "filename=Setup.exe.local",
1464       "",
1465       "",
1466       "application/foo-bar",
1467       L"download",
1468 #if defined(OS_WIN)
1469       L"Setup.exe.download"
1470 #else
1471       L"Setup.exe.local"
1472 #endif
1473     },
1474     {
1475       __LINE__,
1476       "http://www.badguy.com/Setup.exe.local",
1477       "filename=Setup.exe.local.local",
1478       "",
1479       "",
1480       "application/foo-bar",
1481       L"download",
1482 #if defined(OS_WIN)
1483       L"Setup.exe.local.download"
1484 #else
1485       L"Setup.exe.local.local"
1486 #endif
1487     },
1488     {
1489       __LINE__,
1490       "http://www.badguy.com/Setup.exe.lnk",
1491       "filename=Setup.exe.lnk",
1492       "",
1493       "",
1494       "application/foo-bar",
1495       L"download",
1496 #if defined(OS_WIN)
1497       L"Setup.exe.download"
1498 #else
1499       L"Setup.exe.lnk"
1500 #endif
1501     },
1502     {
1503       __LINE__,
1504       "http://www.badguy.com/Desktop.ini",
1505       "filename=Desktop.ini",
1506       "",
1507       "",
1508       "application/foo-bar",
1509       L"download",
1510 #if defined(OS_WIN)
1511       L"_Desktop.ini"
1512 #else
1513       L"Desktop.ini"
1514 #endif
1515     },
1516     {
1517       __LINE__,
1518       "http://www.badguy.com/Thumbs.db",
1519       "filename=Thumbs.db",
1520       "",
1521       "",
1522       "application/foo-bar",
1523       L"download",
1524 #if defined(OS_WIN)
1525       L"_Thumbs.db"
1526 #else
1527       L"Thumbs.db"
1528 #endif
1529     },
1530     {
1531       __LINE__,
1532       "http://www.hotmail.com",
1533       "filename=source.jpg",
1534       "",
1535       "",
1536       "application/x-javascript",
1537       L"download",
1538       L"source.jpg"
1539     },
1540     { // http://crbug.com/5772.
1541       __LINE__,
1542       "http://www.example.com/foo.tar.gz",
1543       "",
1544       "",
1545       "",
1546       "application/x-tar",
1547       L"download",
1548       L"foo.tar.gz"
1549     },
1550     { // http://crbug.com/52250.
1551       __LINE__,
1552       "http://www.example.com/foo.tgz",
1553       "",
1554       "",
1555       "",
1556       "application/x-tar",
1557       L"download",
1558       L"foo.tgz"
1559     },
1560     { // http://crbug.com/7337.
1561       __LINE__,
1562       "http://maged.lordaeron.org/blank.reg",
1563       "",
1564       "",
1565       "",
1566       "text/x-registry",
1567       L"download",
1568       L"blank.reg"
1569     },
1570     {
1571       __LINE__,
1572       "http://www.example.com/bar.tar",
1573       "",
1574       "",
1575       "",
1576       "application/x-tar",
1577       L"download",
1578       L"bar.tar"
1579     },
1580     {
1581       __LINE__,
1582       "http://www.example.com/bar.bogus",
1583       "",
1584       "",
1585       "",
1586       "application/x-tar",
1587       L"download",
1588       L"bar.bogus"
1589     },
1590     { // http://crbug.com/20337
1591       __LINE__,
1592       "http://www.example.com/.download.txt",
1593       "filename=.download.txt",
1594       "",
1595       "",
1596       "text/plain",
1597       L"-download",
1598       L"download.txt"
1599     },
1600     { // http://crbug.com/56855.
1601       __LINE__,
1602       "http://www.example.com/bar.sh",
1603       "",
1604       "",
1605       "",
1606       "application/x-sh",
1607       L"download",
1608       L"bar.sh"
1609     },
1610     { // http://crbug.com/61571
1611       __LINE__,
1612       "http://www.example.com/npdf.php?fn=foobar.pdf",
1613       "",
1614       "",
1615       "",
1616       "text/plain",
1617       L"download",
1618       L"npdf" TXT_EXT
1619     },
1620     { // Shouldn't overwrite C-D specified extension.
1621       __LINE__,
1622       "http://www.example.com/npdf.php?fn=foobar.pdf",
1623       "filename=foobar.jpg",
1624       "",
1625       "",
1626       "text/plain",
1627       L"download",
1628       L"foobar.jpg"
1629     },
1630     { // http://crbug.com/87719
1631       __LINE__,
1632       "http://www.example.com/image.aspx?id=blargh",
1633       "",
1634       "",
1635       "",
1636       "image/jpeg",
1637       L"download",
1638       L"image" JPEG_EXT
1639     },
1640 #if defined(OS_CHROMEOS)
1641     { // http://crosbug.com/26028
1642       __LINE__,
1643       "http://www.example.com/fooa%cc%88.txt",
1644       "",
1645       "",
1646       "",
1647       "image/jpeg",
1648       L"foo\xe4",
1649       L"foo\xe4.txt"
1650     },
1651 #endif
1652   };
1653
1654   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(selection_tests); ++i)
1655     RunGenerateFileNameTestCase(&selection_tests[i]);
1656
1657   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(generation_tests); ++i)
1658     RunGenerateFileNameTestCase(&generation_tests[i]);
1659
1660   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(generation_tests); ++i) {
1661     GenerateFilenameCase test_case = generation_tests[i];
1662     test_case.referrer_charset = "GBK";
1663     RunGenerateFileNameTestCase(&test_case);
1664   }
1665 }
1666
1667 }  // namespace net