OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "net/http/http_content_disposition.h" | 5 #include "net/http/http_content_disposition.h" |
6 | 6 |
7 #include "base/strings/utf_string_conversions.h" | 7 #include "base/strings/utf_string_conversions.h" |
8 #include "testing/gtest/include/gtest/gtest.h" | 8 #include "testing/gtest/include/gtest/gtest.h" |
9 | 9 |
10 namespace net { | 10 namespace net { |
11 | 11 |
12 namespace { | 12 namespace { |
13 | 13 |
14 struct FileNameCDCase { | 14 struct FileNameCDCase { |
15 const char* header; | 15 const char* header; |
16 const char* referrer_charset; | 16 const char* referrer_charset; |
17 const wchar_t* expected; | 17 const wchar_t* expected; |
18 }; | 18 }; |
19 | 19 |
20 } // anonymous namespace | 20 } // anonymous namespace |
21 | 21 |
22 TEST(HttpContentDispositionTest, Filename) { | 22 TEST(HttpContentDispositionTest, Filename) { |
23 const FileNameCDCase tests[] = { | 23 const FileNameCDCase tests[] = { |
24 // Test various forms of C-D header fields emitted by web servers. | 24 // Test various forms of C-D header fields emitted by web servers. |
25 {"inline; filename=\"abcde.pdf\"", "", L"abcde.pdf"}, | 25 {"inline; filename=\"abcde.pdf\"", "", L"abcde.pdf"}, |
26 {"inline; name=\"abcde.pdf\"", "", L"abcde.pdf"}, | |
27 {"attachment; filename=abcde.pdf", "", L"abcde.pdf"}, | 26 {"attachment; filename=abcde.pdf", "", L"abcde.pdf"}, |
28 {"attachment; name=abcde.pdf", "", L"abcde.pdf"}, | |
29 {"attachment; filename=abc,de.pdf", "", L"abc,de.pdf"}, | 27 {"attachment; filename=abc,de.pdf", "", L"abc,de.pdf"}, |
30 {"filename=abcde.pdf", "", L"abcde.pdf"}, | 28 {"filename=abcde.pdf", "", L"abcde.pdf"}, |
31 {"filename= abcde.pdf", "", L"abcde.pdf"}, | 29 {"filename= abcde.pdf", "", L"abcde.pdf"}, |
32 {"filename =abcde.pdf", "", L"abcde.pdf"}, | 30 {"filename =abcde.pdf", "", L"abcde.pdf"}, |
33 {"filename = abcde.pdf", "", L"abcde.pdf"}, | 31 {"filename = abcde.pdf", "", L"abcde.pdf"}, |
34 {"filename\t=abcde.pdf", "", L"abcde.pdf"}, | 32 {"filename\t=abcde.pdf", "", L"abcde.pdf"}, |
35 {"filename \t\t =abcde.pdf", "", L"abcde.pdf"}, | 33 {"filename \t\t =abcde.pdf", "", L"abcde.pdf"}, |
36 {"name=abcde.pdf", "", L"abcde.pdf"}, | |
37 {"inline; filename=\"abc%20de.pdf\"", "", | 34 {"inline; filename=\"abc%20de.pdf\"", "", |
38 L"abc de.pdf"}, | 35 L"abc de.pdf"}, |
| 36 // Name values are no longer synonyms for filename. |
| 37 {"inline; name=\"abcde.pdf\"", "", L""}, |
| 38 {"attachment; name=abcde.pdf", "", L""}, |
| 39 {"name=abcde.pdf", "", L""}, |
39 // Unbalanced quotation mark | 40 // Unbalanced quotation mark |
40 {"filename=\"abcdef.pdf", "", L"abcdef.pdf"}, | 41 {"filename=\"abcdef.pdf", "", L"abcdef.pdf"}, |
41 // Whitespaces are converted to a space. | 42 // Whitespaces are converted to a space. |
42 {"inline; filename=\"abc \t\nde.pdf\"", "", | 43 {"inline; filename=\"abc \t\nde.pdf\"", "", |
43 L"abc de.pdf"}, | 44 L"abc de.pdf"}, |
44 // %-escaped UTF-8 | 45 // %-escaped UTF-8 |
45 {"attachment; filename=\"%EC%98%88%EC%88%A0%20" | 46 {"attachment; filename=\"%EC%98%88%EC%88%A0%20" |
46 "%EC%98%88%EC%88%A0.jpg\"", "", L"\xc608\xc220 \xc608\xc220.jpg"}, | 47 "%EC%98%88%EC%88%A0.jpg\"", "", L"\xc608\xc220 \xc608\xc220.jpg"}, |
47 {"attachment; filename=\"%F0%90%8C%B0%F0%90%8C%B1" | 48 {"attachment; filename=\"%F0%90%8C%B0%F0%90%8C%B1" |
48 "abc.jpg\"", "", L"\U00010330\U00010331abc.jpg"}, | 49 "abc.jpg\"", "", L"\U00010330\U00010331abc.jpg"}, |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 {"attachment; filename=\"50%.html\"", | 309 {"attachment; filename=\"50%.html\"", |
309 HttpContentDisposition::ATTACHMENT, | 310 HttpContentDisposition::ATTACHMENT, |
310 L"50%.html"}, | 311 L"50%.html"}, |
311 // http://greenbytes.de/tech/tc2231/#attwithfnrawpctencaq | 312 // http://greenbytes.de/tech/tc2231/#attwithfnrawpctencaq |
312 { | 313 { |
313 "attachment; filename=\"foo-%\\41.html\"", | 314 "attachment; filename=\"foo-%\\41.html\"", |
314 HttpContentDisposition::ATTACHMENT, | 315 HttpContentDisposition::ATTACHMENT, |
315 L"foo-A.html" // Should be L"foo-%41.html" | 316 L"foo-A.html" // Should be L"foo-%41.html" |
316 }, | 317 }, |
317 // http://greenbytes.de/tech/tc2231/#attwithnamepct | 318 // http://greenbytes.de/tech/tc2231/#attwithnamepct |
| 319 // Value is skipped like other UAs. |
318 { | 320 { |
319 "attachment; name=\"foo-%41.html\"", | 321 "attachment; name=\"foo-%41.html\"", |
320 HttpContentDisposition::ATTACHMENT, | 322 HttpContentDisposition::ATTACHMENT, |
321 L"foo-A.html" // Should be L"foo-%41.html" | 323 L"" |
322 }, | 324 }, |
323 #ifdef ICU_SHOULD_FAIL_CONVERSION_ON_INVALID_CHARACTER | 325 #ifdef ICU_SHOULD_FAIL_CONVERSION_ON_INVALID_CHARACTER |
324 // http://greenbytes.de/tech/tc2231/#attwithfilenamepctandiso | 326 // http://greenbytes.de/tech/tc2231/#attwithfilenamepctandiso |
325 { | 327 { |
326 "attachment; filename=\"\xE4-%41.html\"", | 328 "attachment; filename=\"\xE4-%41.html\"", |
327 HttpContentDisposition::ATTACHMENT, | 329 HttpContentDisposition::ATTACHMENT, |
328 L"" // Should be L"\xE4-%41.htm" | 330 L"" // Should be L"\xE4-%41.htm" |
329 }, | 331 }, |
330 #endif | 332 #endif |
331 // http://greenbytes.de/tech/tc2231/#attwithfnrawpctenclong | 333 // http://greenbytes.de/tech/tc2231/#attwithfnrawpctenclong |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 { "filename=x", HttpContentDisposition::HAS_FILENAME }, | 474 { "filename=x", HttpContentDisposition::HAS_FILENAME }, |
473 { "example; filename=x", | 475 { "example; filename=x", |
474 HttpContentDisposition::HAS_DISPOSITION_TYPE | | 476 HttpContentDisposition::HAS_DISPOSITION_TYPE | |
475 HttpContentDisposition::HAS_UNKNOWN_DISPOSITION_TYPE | | 477 HttpContentDisposition::HAS_UNKNOWN_DISPOSITION_TYPE | |
476 HttpContentDisposition::HAS_FILENAME}, | 478 HttpContentDisposition::HAS_FILENAME}, |
477 { "attachment; filename=x", | 479 { "attachment; filename=x", |
478 HttpContentDisposition::HAS_DISPOSITION_TYPE | | 480 HttpContentDisposition::HAS_DISPOSITION_TYPE | |
479 HttpContentDisposition::HAS_FILENAME }, | 481 HttpContentDisposition::HAS_FILENAME }, |
480 { "attachment; filename=x; name=y", | 482 { "attachment; filename=x; name=y", |
481 HttpContentDisposition::HAS_DISPOSITION_TYPE | | 483 HttpContentDisposition::HAS_DISPOSITION_TYPE | |
482 HttpContentDisposition::HAS_FILENAME | | 484 HttpContentDisposition::HAS_FILENAME }, |
483 HttpContentDisposition::HAS_NAME }, | |
484 { "attachment; name=y; filename*=utf-8''foo; name=x", | 485 { "attachment; name=y; filename*=utf-8''foo; name=x", |
485 HttpContentDisposition::HAS_DISPOSITION_TYPE | | 486 HttpContentDisposition::HAS_DISPOSITION_TYPE | |
486 HttpContentDisposition::HAS_EXT_FILENAME | | 487 HttpContentDisposition::HAS_EXT_FILENAME }, |
487 HttpContentDisposition::HAS_NAME }, | |
488 | 488 |
489 // Feature tests for 'filename' attribute. | 489 // Feature tests for 'filename' attribute. |
490 { "filename=foo\xcc\x88", | 490 { "filename=foo\xcc\x88", |
491 HttpContentDisposition::HAS_FILENAME | | 491 HttpContentDisposition::HAS_FILENAME | |
492 HttpContentDisposition::HAS_NON_ASCII_STRINGS }, | 492 HttpContentDisposition::HAS_NON_ASCII_STRINGS }, |
493 { "filename=foo%cc%88", | 493 { "filename=foo%cc%88", |
494 HttpContentDisposition::HAS_FILENAME | | 494 HttpContentDisposition::HAS_FILENAME | |
495 HttpContentDisposition::HAS_PERCENT_ENCODED_STRINGS }, | 495 HttpContentDisposition::HAS_PERCENT_ENCODED_STRINGS }, |
496 { "filename==?utf-8?Q?foo?=", | 496 { "filename==?utf-8?Q?foo?=", |
497 HttpContentDisposition::HAS_FILENAME | | 497 HttpContentDisposition::HAS_FILENAME | |
498 HttpContentDisposition::HAS_RFC2047_ENCODED_STRINGS }, | 498 HttpContentDisposition::HAS_RFC2047_ENCODED_STRINGS }, |
499 { "filename=\"=?utf-8?Q?foo?=\"", | 499 { "filename=\"=?utf-8?Q?foo?=\"", |
500 HttpContentDisposition::HAS_FILENAME | | 500 HttpContentDisposition::HAS_FILENAME | |
501 HttpContentDisposition::HAS_RFC2047_ENCODED_STRINGS }, | 501 HttpContentDisposition::HAS_RFC2047_ENCODED_STRINGS }, |
502 { "filename==?utf-8?Q?foo?", HttpContentDisposition::INVALID }, | 502 { "filename==?utf-8?Q?foo?", HttpContentDisposition::INVALID }, |
503 { "name=foo\xcc\x88", | 503 |
504 HttpContentDisposition::HAS_NAME }, | 504 // Test 'name' isn't a synonym for 'filename'. |
| 505 { "name=foo\xcc\x88", HttpContentDisposition::INVALID }, |
505 | 506 |
506 // Shouldn't set |has_non_ascii_strings| based on 'name' attribute. | 507 // Shouldn't set |has_non_ascii_strings| based on 'name' attribute. |
507 { "filename=x; name=foo\xcc\x88", | 508 { "filename=x; name=foo\xcc\x88", |
508 HttpContentDisposition::HAS_FILENAME | | 509 HttpContentDisposition::HAS_FILENAME }, |
509 HttpContentDisposition::HAS_NAME }, | |
510 { "filename=foo\xcc\x88 foo%cc%88 =?utf-8?Q?foo?=", | 510 { "filename=foo\xcc\x88 foo%cc%88 =?utf-8?Q?foo?=", |
511 HttpContentDisposition::HAS_FILENAME | | 511 HttpContentDisposition::HAS_FILENAME | |
512 HttpContentDisposition::HAS_NON_ASCII_STRINGS | | 512 HttpContentDisposition::HAS_NON_ASCII_STRINGS | |
513 HttpContentDisposition::HAS_PERCENT_ENCODED_STRINGS | | 513 HttpContentDisposition::HAS_PERCENT_ENCODED_STRINGS | |
514 HttpContentDisposition::HAS_RFC2047_ENCODED_STRINGS }, | 514 HttpContentDisposition::HAS_RFC2047_ENCODED_STRINGS }, |
515 | 515 |
516 // If 'filename' attribute is invalid, should set any flags based on it. | 516 // If 'filename' attribute is invalid, should set any flags based on it. |
517 { "filename=foo\xcc\x88 foo%cc%88 =?utf-8?Q?foo?", | 517 { "filename=foo\xcc\x88 foo%cc%88 =?utf-8?Q?foo?", |
518 HttpContentDisposition::INVALID }, | 518 HttpContentDisposition::INVALID }, |
519 { "filename=foo\xcc\x88 foo%cc%88 =?utf-8?Q?foo?; name=x", | 519 { "filename=foo\xcc\x88 foo%cc%88 =?utf-8?Q?foo?; name=x", |
520 HttpContentDisposition::HAS_NAME }, | 520 HttpContentDisposition::INVALID }, |
521 }; | 521 }; |
522 | 522 |
523 for (size_t i = 0; i < arraysize(kTestCases); ++i) { | 523 for (size_t i = 0; i < arraysize(kTestCases); ++i) { |
524 const ParseResultTestCase& test_case = kTestCases[i]; | 524 const ParseResultTestCase& test_case = kTestCases[i]; |
525 HttpContentDisposition content_disposition(test_case.header, "utf-8"); | 525 HttpContentDisposition content_disposition(test_case.header, "utf-8"); |
526 int result = content_disposition.parse_result_flags(); | 526 int result = content_disposition.parse_result_flags(); |
527 | 527 |
528 SCOPED_TRACE(testing::Message() << "Test case " << i | 528 SCOPED_TRACE(testing::Message() << "Test case " << i |
529 << " with header " << test_case.header); | 529 << " with header " << test_case.header); |
530 EXPECT_EQ(test_case.expected_flags, result); | 530 EXPECT_EQ(test_case.expected_flags, result); |
531 } | 531 } |
532 } | 532 } |
533 | 533 |
534 } // namespace net | 534 } // namespace net |
OLD | NEW |