Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / net / http / http_content_disposition_unittest.cc
blobade0d2930f9ad71179610581ace728f4a46b60b8
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
3 // found in the LICENSE file.
5 #include "net/http/http_content_disposition.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "testing/gtest/include/gtest/gtest.h"
10 namespace net {
12 namespace {
14 struct FileNameCDCase {
15 const char* header;
16 const char* referrer_charset;
17 const wchar_t* expected;
20 } // anonymous namespace
22 TEST(HttpContentDispositionTest, Filename) {
23 const FileNameCDCase tests[] = {
24 // Test various forms of C-D header fields emitted by web servers.
25 {"inline; filename=\"abcde.pdf\"", "", L"abcde.pdf"},
26 {"inline; name=\"abcde.pdf\"", "", L"abcde.pdf"},
27 {"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"},
30 {"filename=abcde.pdf", "", L"abcde.pdf"},
31 {"filename= abcde.pdf", "", L"abcde.pdf"},
32 {"filename =abcde.pdf", "", L"abcde.pdf"},
33 {"filename = abcde.pdf", "", L"abcde.pdf"},
34 {"filename\t=abcde.pdf", "", L"abcde.pdf"},
35 {"filename \t\t =abcde.pdf", "", L"abcde.pdf"},
36 {"name=abcde.pdf", "", L"abcde.pdf"},
37 {"inline; filename=\"abc%20de.pdf\"", "",
38 L"abc de.pdf"},
39 // Unbalanced quotation mark
40 {"filename=\"abcdef.pdf", "", L"abcdef.pdf"},
41 // Whitespaces are converted to a space.
42 {"inline; filename=\"abc \t\nde.pdf\"", "",
43 L"abc de.pdf"},
44 // %-escaped UTF-8
45 {"attachment; filename=\"%EC%98%88%EC%88%A0%20"
46 "%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 "abc.jpg\"", "", L"\U00010330\U00010331abc.jpg"},
49 {"attachment; filename=\"%EC%98%88%EC%88%A0 \n"
50 "%EC%98%88%EC%88%A0.jpg\"", "", L"\xc608\xc220 \xc608\xc220.jpg"},
51 // RFC 2047 with various charsets and Q/B encodings
52 {"attachment; filename=\"=?EUC-JP?Q?=B7=DD=BD="
53 "D13=2Epng?=\"", "", L"\x82b8\x8853" L"3.png"},
54 {"attachment; filename==?eUc-Kr?b?v7m8+iAzLnBuZw==?=",
55 "", L"\xc608\xc220 3.png"},
56 {"attachment; filename==?utf-8?Q?=E8=8A=B8=E8"
57 "=A1=93_3=2Epng?=", "", L"\x82b8\x8853 3.png"},
58 {"attachment; filename==?utf-8?Q?=F0=90=8C=B0"
59 "_3=2Epng?=", "", L"\U00010330 3.png"},
60 {"inline; filename=\"=?iso88591?Q?caf=e9_=2epng?=\"",
61 "", L"caf\x00e9 .png"},
62 // Space after an encoded word should be removed.
63 {"inline; filename=\"=?iso88591?Q?caf=E9_?= .png\"",
64 "", L"caf\x00e9 .png"},
65 // Two encoded words with different charsets (not very likely to be emitted
66 // by web servers in the wild). Spaces between them are removed.
67 {"inline; filename=\"=?euc-kr?b?v7m8+iAz?="
68 " =?ksc5601?q?=BF=B9=BC=FA=2Epng?=\"", "",
69 L"\xc608\xc220 3\xc608\xc220.png"},
70 {"attachment; filename=\"=?windows-1252?Q?caf=E9?="
71 " =?iso-8859-7?b?4eI=?= .png\"", "", L"caf\x00e9\x03b1\x03b2.png"},
72 // Non-ASCII string is passed through and treated as UTF-8 as long as
73 // it's valid as UTF-8 and regardless of |referrer_charset|.
74 {"attachment; filename=caf\xc3\xa9.png",
75 "iso-8859-1", L"caf\x00e9.png"},
76 {"attachment; filename=caf\xc3\xa9.png",
77 "", L"caf\x00e9.png"},
78 // Non-ASCII/Non-UTF-8 string. Fall back to the referrer charset.
79 {"attachment; filename=caf\xe5.png",
80 "windows-1253", L"caf\x03b5.png"},
81 #if 0
82 // Non-ASCII/Non-UTF-8 string. Fall back to the native codepage.
83 // TODO(jungshik): We need to set the OS default codepage
84 // to a specific value before testing. On Windows, we can use
85 // SetThreadLocale().
86 {"attachment; filename=\xb0\xa1\xb0\xa2.png",
87 "", L"\xac00\xac01.png"},
88 #endif
89 // Failure cases
90 // Invalid hex-digit "G"
91 {"attachment; filename==?iiso88591?Q?caf=EG?=", "",
92 L""},
93 // Incomplete RFC 2047 encoded-word (missing '='' at the end)
94 {"attachment; filename==?iso88591?Q?caf=E3?", "", L""},
95 // Extra character at the end of an encoded word
96 {"attachment; filename==?iso88591?Q?caf=E3?==",
97 "", L""},
98 // Extra token at the end of an encoded word
99 {"attachment; filename==?iso88591?Q?caf=E3?=?",
100 "", L""},
101 {"attachment; filename==?iso88591?Q?caf=E3?=?=",
102 "", L""},
103 // Incomplete hex-escaped chars
104 {"attachment; filename==?windows-1252?Q?=63=61=E?=",
105 "", L""},
106 {"attachment; filename=%EC%98%88%EC%88%A", "", L""},
107 // %-escaped non-UTF-8 encoding is an "error"
108 {"attachment; filename=%B7%DD%BD%D1.png", "", L""},
109 // Two RFC 2047 encoded words in a row without a space is an error.
110 {"attachment; filename==?windows-1252?Q?caf=E3?="
111 "=?iso-8859-7?b?4eIucG5nCg==?=", "", L""},
113 // RFC 5987 tests with Filename* : see http://tools.ietf.org/html/rfc5987
114 {"attachment; filename*=foo.html", "", L""},
115 {"attachment; filename*=foo'.html", "", L""},
116 {"attachment; filename*=''foo'.html", "", L""},
117 {"attachment; filename*=''foo.html'", "", L""},
118 {"attachment; filename*=''f\"oo\".html'", "", L""},
119 {"attachment; filename*=bogus_charset''foo.html'",
120 "", L""},
121 {"attachment; filename*='en'foo.html'", "", L""},
122 {"attachment; filename*=iso-8859-1'en'foo.html", "",
123 L"foo.html"},
124 {"attachment; filename*=utf-8'en'foo.html", "",
125 L"foo.html"},
126 // charset cannot be omitted.
127 {"attachment; filename*='es'f\xfa.html'", "", L""},
128 // Non-ASCII bytes are not allowed.
129 {"attachment; filename*=iso-8859-1'es'f\xfa.html", "",
130 L""},
131 {"attachment; filename*=utf-8'es'f\xce\xba.html", "",
132 L""},
133 // TODO(jshin): Space should be %-encoded, but currently, we allow
134 // spaces.
135 {"inline; filename*=iso88591''cafe foo.png", "",
136 L"cafe foo.png"},
138 // Filename* tests converted from Q-encoded tests above.
139 {"attachment; filename*=EUC-JP''%B7%DD%BD%D13%2Epng",
140 "", L"\x82b8\x8853" L"3.png"},
141 {"attachment; filename*=utf-8''"
142 "%E8%8A%B8%E8%A1%93%203%2Epng", "", L"\x82b8\x8853 3.png"},
143 {"attachment; filename*=utf-8''%F0%90%8C%B0 3.png", "",
144 L"\U00010330 3.png"},
145 {"inline; filename*=Euc-Kr'ko'%BF%B9%BC%FA%2Epng", "",
146 L"\xc608\xc220.png"},
147 {"attachment; filename*=windows-1252''caf%E9.png", "",
148 L"caf\x00e9.png"},
150 // Multiple filename, filename*, name parameters specified.
151 {"attachment; name=\"foo\"; filename=\"bar\"", "", L"bar"},
152 {"attachment; filename=\"bar\"; name=\"foo\"", "", L"bar"},
153 {"attachment; filename=\"bar\"; filename*=utf-8''baz", "", L"baz"},
155 // http://greenbytes.de/tech/tc2231/ filename* test cases.
156 // attwithisofn2231iso
157 {"attachment; filename*=iso-8859-1''foo-%E4.html", "",
158 L"foo-\xe4.html"},
159 // attwithfn2231utf8
160 {"attachment; filename*="
161 "UTF-8''foo-%c3%a4-%e2%82%ac.html", "", L"foo-\xe4-\x20ac.html"},
162 // attwithfn2231noc : no encoding specified but UTF-8 is used.
163 {"attachment; filename*=''foo-%c3%a4-%e2%82%ac.html",
164 "", L""},
165 // attwithfn2231utf8comp
166 {"attachment; filename*=UTF-8''foo-a%cc%88.html", "",
167 L"foo-\xe4.html"},
168 #ifdef ICU_SHOULD_FAIL_CONVERSION_ON_INVALID_CHARACTER
169 // This does not work because we treat ISO-8859-1 synonymous with
170 // Windows-1252 per HTML5. For HTTP, in theory, we're not
171 // supposed to.
172 // attwithfn2231utf8-bad
173 {"attachment; filename*="
174 "iso-8859-1''foo-%c3%a4-%e2%82%ac.html", "", L""},
175 #endif
176 // attwithfn2231ws1
177 {"attachment; filename *=UTF-8''foo-%c3%a4.html", "",
178 L""},
179 // attwithfn2231ws2
180 {"attachment; filename*= UTF-8''foo-%c3%a4.html", "",
181 L"foo-\xe4.html"},
182 // attwithfn2231ws3
183 {"attachment; filename* =UTF-8''foo-%c3%a4.html", "",
184 L"foo-\xe4.html"},
185 // attwithfn2231quot
186 {"attachment; filename*=\"UTF-8''foo-%c3%a4.html\"",
187 "", L""},
188 // attfnboth
189 {"attachment; filename=\"foo-ae.html\"; "
190 "filename*=UTF-8''foo-%c3%a4.html", "", L"foo-\xe4.html"},
191 // attfnboth2
192 {"attachment; filename*=UTF-8''foo-%c3%a4.html; "
193 "filename=\"foo-ae.html\"", "", L"foo-\xe4.html"},
194 // attnewandfn
195 {"attachment; foobar=x; filename=\"foo.html\"", "",
196 L"foo.html"},
198 for (size_t i = 0; i < arraysize(tests); ++i) {
199 HttpContentDisposition header(tests[i].header, tests[i].referrer_charset);
200 EXPECT_EQ(tests[i].expected,
201 base::UTF8ToWide(header.filename()))
202 << "Failed on input: " << tests[i].header;
206 // Test cases from http://greenbytes.de/tech/tc2231/
207 TEST(HttpContentDispositionTest, tc2231) {
208 const struct FileNameCDCase {
209 const char* header;
210 HttpContentDisposition::Type expected_type;
211 const wchar_t* expected_filename;
212 } tests[] = {
213 // http://greenbytes.de/tech/tc2231/#inlonly
214 {"inline", HttpContentDisposition::INLINE, L""},
215 // http://greenbytes.de/tech/tc2231/#inlonlyquoted
216 {"\"inline\"", HttpContentDisposition::INLINE, L""},
217 // http://greenbytes.de/tech/tc2231/#inlwithasciifilename
218 {"inline; filename=\"foo.html\"",
219 HttpContentDisposition::INLINE,
220 L"foo.html"},
221 // http://greenbytes.de/tech/tc2231/#inlwithfnattach
222 {"inline; filename=\"Not an attachment!\"",
223 HttpContentDisposition::INLINE,
224 L"Not an attachment!"},
225 // http://greenbytes.de/tech/tc2231/#inlwithasciifilenamepdf
226 {"inline; filename=\"foo.pdf\"",
227 HttpContentDisposition::INLINE,
228 L"foo.pdf"},
229 // http://greenbytes.de/tech/tc2231/#attonly
230 {"attachment", HttpContentDisposition::ATTACHMENT, L""},
231 // http://greenbytes.de/tech/tc2231/#attonlyquoted
232 {"\"attachment\"", HttpContentDisposition::INLINE, L""},
233 // http://greenbytes.de/tech/tc2231/#attonly403
234 // TODO(abarth): This isn't testable in this unit test.
235 // http://greenbytes.de/tech/tc2231/#attonlyucase
236 {"ATTACHMENT", HttpContentDisposition::ATTACHMENT, L""},
237 // http://greenbytes.de/tech/tc2231/#attwithasciifilename
238 {"attachment; filename=\"foo.html\"",
239 HttpContentDisposition::ATTACHMENT,
240 L"foo.html"},
241 // http://greenbytes.de/tech/tc2231/#attwithasciifnescapedchar
242 {"attachment; filename=\"f\\oo.html\"",
243 HttpContentDisposition::ATTACHMENT,
244 L"foo.html"},
245 // http://greenbytes.de/tech/tc2231/#attwithasciifnescapedquote
246 {"attachment; filename=\"\\\"quoting\\\" tested.html\"",
247 HttpContentDisposition::ATTACHMENT,
248 L"\"quoting\" tested.html"},
249 // http://greenbytes.de/tech/tc2231/#attwithquotedsemicolon
250 {"attachment; filename=\"Here's a semicolon;.html\"",
251 HttpContentDisposition::ATTACHMENT,
252 L"Here's a semicolon;.html"},
253 // http://greenbytes.de/tech/tc2231/#attwithfilenameandextparam
254 {"attachment; foo=\"bar\"; filename=\"foo.html\"",
255 HttpContentDisposition::ATTACHMENT,
256 L"foo.html"},
257 // http://greenbytes.de/tech/tc2231/#attwithfilenameandextparamescaped
258 {"attachment; foo=\"\\\"\\\\\";filename=\"foo.html\"",
259 HttpContentDisposition::ATTACHMENT,
260 L"foo.html"},
261 // http://greenbytes.de/tech/tc2231/#attwithasciifilenameucase
262 {"attachment; FILENAME=\"foo.html\"",
263 HttpContentDisposition::ATTACHMENT,
264 L"foo.html"},
265 // http://greenbytes.de/tech/tc2231/#attwithasciifilenamenq
266 {"attachment; filename=foo.html",
267 HttpContentDisposition::ATTACHMENT,
268 L"foo.html"},
269 // http://greenbytes.de/tech/tc2231/#attwithasciifilenamenqs
270 // Note: tc2231 says we should fail to parse this header.
271 {"attachment; filename=foo.html ;",
272 HttpContentDisposition::ATTACHMENT,
273 L"foo.html"},
274 // http://greenbytes.de/tech/tc2231/#attemptyparam
275 // Note: tc2231 says we should fail to parse this header.
276 {"attachment; ;filename=foo", HttpContentDisposition::ATTACHMENT, L"foo"},
277 // http://greenbytes.de/tech/tc2231/#attwithasciifilenamenqws
278 // Note: tc2231 says we should fail to parse this header.
279 {"attachment; filename=foo bar.html",
280 HttpContentDisposition::ATTACHMENT,
281 L"foo bar.html"},
282 // http://greenbytes.de/tech/tc2231/#attwithfntokensq
284 "attachment; filename='foo.bar'",
285 HttpContentDisposition::ATTACHMENT,
286 L"foo.bar" // Should be L"'foo.bar'"
288 #ifdef ICU_SHOULD_FAIL_CONVERSION_ON_INVALID_CHARACTER
289 // http://greenbytes.de/tech/tc2231/#attwithisofnplain
291 "attachment; filename=\"foo-\xE4html\"",
292 HttpContentDisposition::ATTACHMENT,
293 L"" // Should be L"foo-\xE4.html"
295 #endif
296 // http://greenbytes.de/tech/tc2231/#attwithutf8fnplain
297 // Note: We'll UTF-8 decode the file name, even though tc2231 says not to.
298 {"attachment; filename=\"foo-\xC3\xA4.html\"",
299 HttpContentDisposition::ATTACHMENT,
300 L"foo-\xE4.html"},
301 // http://greenbytes.de/tech/tc2231/#attwithfnrawpctenca
303 "attachment; filename=\"foo-%41.html\"",
304 HttpContentDisposition::ATTACHMENT,
305 L"foo-A.html" // Should be L"foo-%41.html"
307 // http://greenbytes.de/tech/tc2231/#attwithfnusingpct
308 {"attachment; filename=\"50%.html\"",
309 HttpContentDisposition::ATTACHMENT,
310 L"50%.html"},
311 // http://greenbytes.de/tech/tc2231/#attwithfnrawpctencaq
313 "attachment; filename=\"foo-%\\41.html\"",
314 HttpContentDisposition::ATTACHMENT,
315 L"foo-A.html" // Should be L"foo-%41.html"
317 // http://greenbytes.de/tech/tc2231/#attwithnamepct
319 "attachment; name=\"foo-%41.html\"",
320 HttpContentDisposition::ATTACHMENT,
321 L"foo-A.html" // Should be L"foo-%41.html"
323 #ifdef ICU_SHOULD_FAIL_CONVERSION_ON_INVALID_CHARACTER
324 // http://greenbytes.de/tech/tc2231/#attwithfilenamepctandiso
326 "attachment; filename=\"\xE4-%41.html\"",
327 HttpContentDisposition::ATTACHMENT,
328 L"" // Should be L"\xE4-%41.htm"
330 #endif
331 // http://greenbytes.de/tech/tc2231/#attwithfnrawpctenclong
333 "attachment; filename=\"foo-%c3%a4-%e2%82%ac.html\"",
334 HttpContentDisposition::ATTACHMENT,
335 L"foo-\xE4-\u20AC.html" // Should be L"foo-%c3%a4-%e2%82%ac.html"
337 // http://greenbytes.de/tech/tc2231/#attwithasciifilenamews1
338 {"attachment; filename =\"foo.html\"",
339 HttpContentDisposition::ATTACHMENT,
340 L"foo.html"},
341 // http://greenbytes.de/tech/tc2231/#attwith2filenames
342 // Note: tc2231 says we should fail to parse this header.
343 {"attachment; filename=\"foo.html\"; filename=\"bar.html\"",
344 HttpContentDisposition::ATTACHMENT,
345 L"foo.html"},
346 // http://greenbytes.de/tech/tc2231/#attfnbrokentoken
347 // Note: tc2231 says we should fail to parse this header.
348 {"attachment; filename=foo[1](2).html",
349 HttpContentDisposition::ATTACHMENT,
350 L"foo[1](2).html"},
351 #ifdef ICU_SHOULD_FAIL_CONVERSION_ON_INVALID_CHARACTER
352 // http://greenbytes.de/tech/tc2231/#attfnbrokentokeniso
353 // Note: tc2231 says we should fail to parse this header.
354 {"attachment; filename=foo-\xE4.html",
355 HttpContentDisposition::ATTACHMENT,
356 L""},
357 #endif
358 // http://greenbytes.de/tech/tc2231/#attfnbrokentokenutf
359 // Note: tc2231 says we should fail to parse this header.
360 {"attachment; filename=foo-\xC3\xA4.html",
361 HttpContentDisposition::ATTACHMENT,
362 L"foo-\xE4.html"},
363 // http://greenbytes.de/tech/tc2231/#attmissingdisposition
364 // Note: tc2231 says we should fail to parse this header.
365 {"filename=foo.html", HttpContentDisposition::INLINE, L"foo.html"},
366 // http://greenbytes.de/tech/tc2231/#attmissingdisposition2
367 // Note: tc2231 says we should fail to parse this header.
368 {"x=y; filename=foo.html", HttpContentDisposition::INLINE, L"foo.html"},
369 // http://greenbytes.de/tech/tc2231/#attmissingdisposition3
370 // Note: tc2231 says we should fail to parse this header.
372 "\"foo; filename=bar;baz\"; filename=qux",
373 HttpContentDisposition::INLINE,
374 L"" // Firefox gets qux
376 // http://greenbytes.de/tech/tc2231/#attmissingdisposition4
377 // Note: tc2231 says we should fail to parse this header.
378 {"filename=foo.html, filename=bar.html",
379 HttpContentDisposition::INLINE,
380 L"foo.html, filename=bar.html"},
381 // http://greenbytes.de/tech/tc2231/#emptydisposition
382 // Note: tc2231 says we should fail to parse this header.
383 {"; filename=foo.html", HttpContentDisposition::INLINE, L"foo.html"},
384 // http://greenbytes.de/tech/tc2231/#attandinline
385 // Note: tc2231 says we should fail to parse this header.
386 {"inline; attachment; filename=foo.html",
387 HttpContentDisposition::INLINE,
388 L""},
389 // http://greenbytes.de/tech/tc2231/#attandinline2
390 // Note: tc2231 says we should fail to parse this header.
391 {"attachment; inline; filename=foo.html",
392 HttpContentDisposition::ATTACHMENT,
393 L""},
394 // http://greenbytes.de/tech/tc2231/#attbrokenquotedfn
395 // Note: tc2231 says we should fail to parse this header.
396 {"attachment; filename=\"foo.html\".txt",
397 HttpContentDisposition::ATTACHMENT,
398 L"foo.html\".txt"},
399 // http://greenbytes.de/tech/tc2231/#attbrokenquotedfn2
400 // Note: tc2231 says we should fail to parse this header.
401 {"attachment; filename=\"bar",
402 HttpContentDisposition::ATTACHMENT,
403 L"bar"},
404 // http://greenbytes.de/tech/tc2231/#attbrokenquotedfn3
405 // Note: tc2231 says we should fail to parse this header.
406 {"attachment; filename=foo\"bar;baz\"qux",
407 HttpContentDisposition::ATTACHMENT,
408 L"foo\"bar;baz\"qux"},
409 // http://greenbytes.de/tech/tc2231/#attmultinstances
410 // Note: tc2231 says we should fail to parse this header.
411 {"attachment; filename=foo.html, attachment; filename=bar.html",
412 HttpContentDisposition::ATTACHMENT,
413 L"foo.html, attachment"},
414 // http://greenbytes.de/tech/tc2231/#attmissingdelim
415 {"attachment; foo=foo filename=bar",
416 HttpContentDisposition::ATTACHMENT,
417 L""},
418 // http://greenbytes.de/tech/tc2231/#attreversed
419 // Note: tc2231 says we should fail to parse this header.
420 {"filename=foo.html; attachment",
421 HttpContentDisposition::INLINE,
422 L"foo.html"},
423 // http://greenbytes.de/tech/tc2231/#attconfusedparam
424 {"attachment; xfilename=foo.html",
425 HttpContentDisposition::ATTACHMENT,
426 L""},
427 // http://greenbytes.de/tech/tc2231/#attabspath
428 {"attachment; filename=\"/foo.html\"",
429 HttpContentDisposition::ATTACHMENT,
430 L"/foo.html"},
431 // http://greenbytes.de/tech/tc2231/#attabspathwin
432 {"attachment; filename=\"\\\\foo.html\"",
433 HttpContentDisposition::ATTACHMENT,
434 L"\\foo.html"},
435 // http://greenbytes.de/tech/tc2231/#dispext
436 {"foobar", HttpContentDisposition::ATTACHMENT, L""},
437 // http://greenbytes.de/tech/tc2231/#dispextbadfn
438 {"attachment; example=\"filename=example.txt\"",
439 HttpContentDisposition::ATTACHMENT,
440 L""},
441 // http://greenbytes.de/tech/tc2231/#attnewandfn
442 {"attachment; foobar=x; filename=\"foo.html\"",
443 HttpContentDisposition::ATTACHMENT,
444 L"foo.html"},
445 // TODO(abarth): Add the filename* tests, but check
446 // HttpContentDispositionTest.Filename for overlap.
447 // TODO(abarth): http://greenbytes.de/tech/tc2231/#attrfc2047token
448 // TODO(abarth): http://greenbytes.de/tech/tc2231/#attrfc2047quoted
450 for (size_t i = 0; i < arraysize(tests); ++i) {
451 HttpContentDisposition header(tests[i].header, std::string());
452 EXPECT_EQ(tests[i].expected_type, header.type())
453 << "Failed on input: " << tests[i].header;
454 EXPECT_EQ(tests[i].expected_filename, base::UTF8ToWide(header.filename()))
455 << "Failed on input: " << tests[i].header;
459 TEST(HttpContentDispositionTest, ParseResult) {
460 const struct ParseResultTestCase {
461 const char* header;
462 int expected_flags;
463 } kTestCases[] = {
464 // Basic feature tests
465 { "", HttpContentDisposition::INVALID },
466 { "example=x", HttpContentDisposition::INVALID },
467 { "attachment; filename=", HttpContentDisposition::HAS_DISPOSITION_TYPE },
468 { "attachment; name=", HttpContentDisposition::HAS_DISPOSITION_TYPE },
469 { "attachment; filename*=", HttpContentDisposition::HAS_DISPOSITION_TYPE },
470 { "attachment; filename==?utf-8?Q?\?=",
471 HttpContentDisposition::HAS_DISPOSITION_TYPE },
472 { "filename=x", HttpContentDisposition::HAS_FILENAME },
473 { "example; filename=x",
474 HttpContentDisposition::HAS_DISPOSITION_TYPE |
475 HttpContentDisposition::HAS_UNKNOWN_DISPOSITION_TYPE |
476 HttpContentDisposition::HAS_FILENAME},
477 { "attachment; filename=x",
478 HttpContentDisposition::HAS_DISPOSITION_TYPE |
479 HttpContentDisposition::HAS_FILENAME },
480 { "attachment; filename=x; name=y",
481 HttpContentDisposition::HAS_DISPOSITION_TYPE |
482 HttpContentDisposition::HAS_FILENAME |
483 HttpContentDisposition::HAS_NAME },
484 { "attachment; name=y; filename*=utf-8''foo; name=x",
485 HttpContentDisposition::HAS_DISPOSITION_TYPE |
486 HttpContentDisposition::HAS_EXT_FILENAME |
487 HttpContentDisposition::HAS_NAME },
489 // Feature tests for 'filename' attribute.
490 { "filename=foo\xcc\x88",
491 HttpContentDisposition::HAS_FILENAME |
492 HttpContentDisposition::HAS_NON_ASCII_STRINGS },
493 { "filename=foo%cc%88",
494 HttpContentDisposition::HAS_FILENAME |
495 HttpContentDisposition::HAS_PERCENT_ENCODED_STRINGS },
496 { "filename==?utf-8?Q?foo?=",
497 HttpContentDisposition::HAS_FILENAME |
498 HttpContentDisposition::HAS_RFC2047_ENCODED_STRINGS },
499 { "filename=\"=?utf-8?Q?foo?=\"",
500 HttpContentDisposition::HAS_FILENAME |
501 HttpContentDisposition::HAS_RFC2047_ENCODED_STRINGS },
502 { "filename==?utf-8?Q?foo?", HttpContentDisposition::INVALID },
503 { "name=foo\xcc\x88",
504 HttpContentDisposition::HAS_NAME },
506 // Shouldn't set |has_non_ascii_strings| based on 'name' attribute.
507 { "filename=x; name=foo\xcc\x88",
508 HttpContentDisposition::HAS_FILENAME |
509 HttpContentDisposition::HAS_NAME },
510 { "filename=foo\xcc\x88 foo%cc%88 =?utf-8?Q?foo?=",
511 HttpContentDisposition::HAS_FILENAME |
512 HttpContentDisposition::HAS_NON_ASCII_STRINGS |
513 HttpContentDisposition::HAS_PERCENT_ENCODED_STRINGS |
514 HttpContentDisposition::HAS_RFC2047_ENCODED_STRINGS },
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?",
518 HttpContentDisposition::INVALID },
519 { "filename=foo\xcc\x88 foo%cc%88 =?utf-8?Q?foo?; name=x",
520 HttpContentDisposition::HAS_NAME },
523 for (size_t i = 0; i < arraysize(kTestCases); ++i) {
524 const ParseResultTestCase& test_case = kTestCases[i];
525 HttpContentDisposition content_disposition(test_case.header, "utf-8");
526 int result = content_disposition.parse_result_flags();
528 SCOPED_TRACE(testing::Message() << "Test case " << i
529 << " with header " << test_case.header);
530 EXPECT_EQ(test_case.expected_flags, result);
534 } // namespace net