1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "gtest/gtest.h"
8 
9 #include "MimeType.h"
10 #include "nsString.h"
11 
12 using mozilla::UniquePtr;
13 
TEST(MimeType,EmptyString)14 TEST(MimeType, EmptyString)
15 {
16   const auto in = u""_ns;
17   UniquePtr<MimeType> parsed = MimeType::Parse(in);
18   ASSERT_FALSE(parsed)
19   << "Empty string";
20 }
21 
TEST(MimeType,JustWhitespace)22 TEST(MimeType, JustWhitespace)
23 {
24   const auto in = u" \t\r\n "_ns;
25   UniquePtr<MimeType> parsed = MimeType::Parse(in);
26   ASSERT_FALSE(parsed)
27   << "Just whitespace";
28 }
29 
TEST(MimeType,JustBackslash)30 TEST(MimeType, JustBackslash)
31 {
32   const auto in = u"\\"_ns;
33   UniquePtr<MimeType> parsed = MimeType::Parse(in);
34   ASSERT_FALSE(parsed)
35   << "Just backslash";
36 }
37 
TEST(MimeType,JustForwardslash)38 TEST(MimeType, JustForwardslash)
39 {
40   const auto in = u"/"_ns;
41   UniquePtr<MimeType> parsed = MimeType::Parse(in);
42   ASSERT_FALSE(parsed)
43   << "Just forward slash";
44 }
45 
TEST(MimeType,MissingType1)46 TEST(MimeType, MissingType1)
47 {
48   const auto in = u"/bogus"_ns;
49   UniquePtr<MimeType> parsed = MimeType::Parse(in);
50   ASSERT_FALSE(parsed)
51   << "Missing type #1";
52 }
53 
TEST(MimeType,MissingType2)54 TEST(MimeType, MissingType2)
55 {
56   const auto in = u" \r\n\t/bogus"_ns;
57   UniquePtr<MimeType> parsed = MimeType::Parse(in);
58   ASSERT_FALSE(parsed)
59   << "Missing type #2";
60 }
61 
TEST(MimeType,MissingSubtype1)62 TEST(MimeType, MissingSubtype1)
63 {
64   const auto in = u"bogus"_ns;
65   UniquePtr<MimeType> parsed = MimeType::Parse(in);
66   ASSERT_FALSE(parsed)
67   << "Missing subtype #1";
68 }
69 
TEST(MimeType,MissingSubType2)70 TEST(MimeType, MissingSubType2)
71 {
72   const auto in = u"bogus/"_ns;
73   UniquePtr<MimeType> parsed = MimeType::Parse(in);
74   ASSERT_FALSE(parsed)
75   << "Missing subtype #2";
76 }
77 
TEST(MimeType,MissingSubType3)78 TEST(MimeType, MissingSubType3)
79 {
80   const auto in = u"bogus;"_ns;
81   UniquePtr<MimeType> parsed = MimeType::Parse(in);
82   ASSERT_FALSE(parsed)
83   << "Missing subtype #3";
84 }
85 
TEST(MimeType,MissingSubType4)86 TEST(MimeType, MissingSubType4)
87 {
88   const auto in = u"bogus; \r\n\t"_ns;
89   UniquePtr<MimeType> parsed = MimeType::Parse(in);
90   ASSERT_FALSE(parsed)
91   << "Missing subtype #3";
92 }
93 
TEST(MimeType,ExtraForwardSlash)94 TEST(MimeType, ExtraForwardSlash)
95 {
96   const auto in = u"bogus/bogus/;"_ns;
97   UniquePtr<MimeType> parsed = MimeType::Parse(in);
98   ASSERT_FALSE(parsed)
99   << "Extra forward slash";
100 }
101 
TEST(MimeType,WhitespaceInType)102 TEST(MimeType, WhitespaceInType)
103 {
104   const auto in = u"t\re\nx\tt /html"_ns;
105   UniquePtr<MimeType> parsed = MimeType::Parse(in);
106   ASSERT_FALSE(parsed)
107   << "Type with whitespace";
108 }
109 
TEST(MimeType,WhitespaceInSubtype)110 TEST(MimeType, WhitespaceInSubtype)
111 {
112   const auto in = u"text/ h\rt\nm\tl"_ns;
113   UniquePtr<MimeType> parsed = MimeType::Parse(in);
114   ASSERT_FALSE(parsed)
115   << "Subtype with whitespace";
116 }
117 
TEST(MimeType,NonAlphanumericMediaType1)118 TEST(MimeType, NonAlphanumericMediaType1)
119 {
120   const auto in = u"</>"_ns;
121   UniquePtr<MimeType> parsed = MimeType::Parse(in);
122   ASSERT_FALSE(parsed)
123   << "Non-alphanumeric media type #1";
124 }
125 
TEST(MimeType,NonAlphanumericMediaType2)126 TEST(MimeType, NonAlphanumericMediaType2)
127 {
128   const auto in = u"(/)"_ns;
129   UniquePtr<MimeType> parsed = MimeType::Parse(in);
130   ASSERT_FALSE(parsed)
131   << "Non-alphanumeric media type #2";
132 }
133 
TEST(MimeType,NonAlphanumericMediaType3)134 TEST(MimeType, NonAlphanumericMediaType3)
135 {
136   const auto in = u"{/}"_ns;
137   UniquePtr<MimeType> parsed = MimeType::Parse(in);
138   ASSERT_FALSE(parsed)
139   << "Non-alphanumeric media type #3";
140 }
141 
TEST(MimeType,NonAlphanumericMediaType4)142 TEST(MimeType, NonAlphanumericMediaType4)
143 {
144   const auto in = u"\"/\""_ns;
145   UniquePtr<MimeType> parsed = MimeType::Parse(in);
146   ASSERT_FALSE(parsed)
147   << "Non-alphanumeric media type #4";
148 }
149 
TEST(MimeType,NonAlphanumericMediaType5)150 TEST(MimeType, NonAlphanumericMediaType5)
151 {
152   const auto in = u"\0/\0"_ns;
153   UniquePtr<MimeType> parsed = MimeType::Parse(in);
154   ASSERT_FALSE(parsed)
155   << "Non-alphanumeric media type #5";
156 }
157 
TEST(MimeType,NonAlphanumericMediaType6)158 TEST(MimeType, NonAlphanumericMediaType6)
159 {
160   const auto in = u"text/html(;doesnot=matter"_ns;
161   UniquePtr<MimeType> parsed = MimeType::Parse(in);
162   ASSERT_FALSE(parsed)
163   << "Non-alphanumeric media type #6";
164 }
165 
TEST(MimeType,NonLatin1MediaType1)166 TEST(MimeType, NonLatin1MediaType1)
167 {
168   const auto in = u"ÿ/ÿ"_ns;
169   UniquePtr<MimeType> parsed = MimeType::Parse(in);
170   ASSERT_FALSE(parsed)
171   << "Non-latin1 media type #1";
172 }
173 
TEST(MimeType,NonLatin1MediaType2)174 TEST(MimeType, NonLatin1MediaType2)
175 {
176   const auto in = u"\x0100/\x0100"_ns;
177   UniquePtr<MimeType> parsed = MimeType::Parse(in);
178   ASSERT_FALSE(parsed)
179   << "Non-latin1 media type #2";
180 }
181 
TEST(MimeType,MultipleParameters)182 TEST(MimeType, MultipleParameters)
183 {
184   const auto in = u"text/html;charset=gbk;no=1;charset_=gbk_;yes=2"_ns;
185   UniquePtr<MimeType> parsed = MimeType::Parse(in);
186   ASSERT_TRUE(parsed)
187   << "Parsing succeeded";
188   nsString out;
189   parsed->Serialize(out);
190   ASSERT_TRUE(out.Equals(u"text/html;charset=gbk;no=1;charset_=gbk_;yes=2"_ns))
191   << "Multiple parameters";
192 }
193 
TEST(MimeType,DuplicateParameter1)194 TEST(MimeType, DuplicateParameter1)
195 {
196   const auto in = u"text/html;charset=gbk;charset=windows-1255"_ns;
197   UniquePtr<MimeType> parsed = MimeType::Parse(in);
198   ASSERT_TRUE(parsed)
199   << "Parsing succeeded";
200   nsString out;
201   parsed->Serialize(out);
202   ASSERT_TRUE(out.Equals(u"text/html;charset=gbk"_ns))
203   << "Duplicate parameter #1";
204 }
205 
TEST(MimeType,DuplicateParameter2)206 TEST(MimeType, DuplicateParameter2)
207 {
208   const auto in = u"text/html;charset=();charset=GBK"_ns;
209   UniquePtr<MimeType> parsed = MimeType::Parse(in);
210   ASSERT_TRUE(parsed)
211   << "Parsing succeeded";
212   nsString out;
213   parsed->Serialize(out);
214   ASSERT_TRUE(out.Equals(u"text/html;charset=\"()\""_ns))
215   << "Duplicate parameter #2";
216 }
217 
TEST(MimeType,CString)218 TEST(MimeType, CString)
219 {
220   const auto in = "text/html;charset=();charset=GBK"_ns;
221   UniquePtr<CMimeType> parsed = CMimeType::Parse(in);
222   ASSERT_TRUE(parsed)
223   << "Parsing succeeded";
224   nsCString out;
225   parsed->Serialize(out);
226   ASSERT_TRUE(out.Equals("text/html;charset=\"()\""_ns))
227   << "Duplicate parameter #2";
228 }
229 
230 #ifdef _MSC_VER
231 #  pragma warning(push)
232 #  pragma warning(disable : 4819)
233 #endif
TEST(MimeType,NonAlphanumericParametersAreQuoted)234 TEST(MimeType, NonAlphanumericParametersAreQuoted)
235 {
236   const auto in = u"text/html;test=\x00FF\\;charset=gbk"_ns;
237   UniquePtr<MimeType> parsed = MimeType::Parse(in);
238   ASSERT_TRUE(parsed)
239   << "Parsing succeeded";
240   nsString out;
241   parsed->Serialize(out);
242   ASSERT_TRUE(out.Equals(u"text/html;test=\"\x00FF\\\\\";charset=gbk"_ns))
243   << "Non-alphanumeric parameters are quoted";
244 }
245 #ifdef _MSC_VER
246 #  pragma warning(pop)
247 #endif
248 
TEST(MimeType,ParameterQuotedIfHasLeadingWhitespace1)249 TEST(MimeType, ParameterQuotedIfHasLeadingWhitespace1)
250 {
251   const auto in = u"text/html;charset= g\\\"bk"_ns;
252   UniquePtr<MimeType> parsed = MimeType::Parse(in);
253   ASSERT_TRUE(parsed)
254   << "Parsing succeeded";
255   nsAutoString out;
256   parsed->Serialize(out);
257   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\" g\\\\\\\"bk\""))
258   << "Parameter is quoted if has leading whitespace #1";
259 }
260 
TEST(MimeType,ParameterQuotedIfHasLeadingWhitespace2)261 TEST(MimeType, ParameterQuotedIfHasLeadingWhitespace2)
262 {
263   const auto in = u"text/html;charset= \"g\\bk\""_ns;
264   UniquePtr<MimeType> parsed = MimeType::Parse(in);
265   ASSERT_TRUE(parsed)
266   << "Parsing succeeded";
267   nsAutoString out;
268   parsed->Serialize(out);
269   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\" \\\"g\\\\bk\\\"\""))
270   << "Parameter is quoted if has leading whitespace #2";
271 }
272 
TEST(MimeType,ParameterQuotedIfHasInternalWhitespace)273 TEST(MimeType, ParameterQuotedIfHasInternalWhitespace)
274 {
275   const auto in = u"text/html;charset=g \\b\"k"_ns;
276   UniquePtr<MimeType> parsed = MimeType::Parse(in);
277   ASSERT_TRUE(parsed)
278   << "Parsing succeeded";
279   nsAutoString out;
280   parsed->Serialize(out);
281   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\"g \\\\b\\\"k\""))
282   << "Parameter is quoted if has internal whitespace";
283 }
284 
TEST(MimeType,ImproperlyQuotedParameter1)285 TEST(MimeType, ImproperlyQuotedParameter1)
286 {
287   const auto in = u"x/x;test=\""_ns;
288   UniquePtr<MimeType> parsed = MimeType::Parse(in);
289   ASSERT_TRUE(parsed)
290   << "Parsing succeeded";
291   nsAutoString out;
292   parsed->Serialize(out);
293   ASSERT_TRUE(out.EqualsLiteral("x/x;test=\"\""))
294   << "Improperly-quoted parameter is handled properly #1";
295 }
296 
TEST(MimeType,ImproperlyQuotedParameter2)297 TEST(MimeType, ImproperlyQuotedParameter2)
298 {
299   const auto in = u"x/x;test=\"\\"_ns;
300   UniquePtr<MimeType> parsed = MimeType::Parse(in);
301   ASSERT_TRUE(parsed)
302   << "Parsing succeeded";
303   nsAutoString out;
304   parsed->Serialize(out);
305   ASSERT_TRUE(out.EqualsLiteral("x/x;test=\"\\\\\""))
306   << "Improperly-quoted parameter is handled properly #2";
307 }
308 
TEST(MimeType,NonLatin1ParameterIgnored)309 TEST(MimeType, NonLatin1ParameterIgnored)
310 {
311   const auto in = u"x/x;test=\xFFFD;x=x"_ns;
312   UniquePtr<MimeType> parsed = MimeType::Parse(in);
313   ASSERT_TRUE(parsed)
314   << "Parsing succeeded";
315   nsAutoString out;
316   parsed->Serialize(out);
317   ASSERT_TRUE(out.EqualsLiteral("x/x;x=x"))
318   << "Non latin-1 parameters are ignored";
319 }
320 
TEST(MimeType,ParameterIgnoredIfWhitespaceInName1)321 TEST(MimeType, ParameterIgnoredIfWhitespaceInName1)
322 {
323   const auto in = u"text/html;charset =gbk;charset=123"_ns;
324   UniquePtr<MimeType> parsed = MimeType::Parse(in);
325   ASSERT_TRUE(parsed)
326   << "Parsing succeeded";
327   nsAutoString out;
328   parsed->Serialize(out);
329   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=123"))
330   << "Parameter ignored if whitespace in name #1";
331 }
332 
TEST(MimeType,ParameterIgnoredIfWhitespaceInName2)333 TEST(MimeType, ParameterIgnoredIfWhitespaceInName2)
334 {
335   const auto in = u"text/html;cha rset =gbk;charset=123"_ns;
336   UniquePtr<MimeType> parsed = MimeType::Parse(in);
337   ASSERT_TRUE(parsed)
338   << "Parsing succeeded";
339   nsAutoString out;
340   parsed->Serialize(out);
341   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=123"))
342   << "Parameter ignored if whitespace in name #2";
343 }
344 
TEST(MimeType,WhitespaceTrimmed)345 TEST(MimeType, WhitespaceTrimmed)
346 {
347   const auto in = u"\n\r\t  text/plain\n\r\t  ;\n\r\t  charset=123\n\r\t "_ns;
348   UniquePtr<MimeType> parsed = MimeType::Parse(in);
349   ASSERT_TRUE(parsed)
350   << "Parsing succeeded";
351   nsAutoString out;
352   parsed->Serialize(out);
353   ASSERT_TRUE(out.EqualsLiteral("text/plain;charset=123"))
354   << "Whitespace appropriately ignored";
355 }
356 
TEST(MimeType,WhitespaceOnlyParameterIgnored)357 TEST(MimeType, WhitespaceOnlyParameterIgnored)
358 {
359   const auto in = u"x/x;x= \r\n\t"_ns;
360   UniquePtr<MimeType> parsed = MimeType::Parse(in);
361   ASSERT_TRUE(parsed)
362   << "Parsing succeeded";
363   nsAutoString out;
364   parsed->Serialize(out);
365   ASSERT_TRUE(out.EqualsLiteral("x/x"))
366   << "Whitespace-only parameter is ignored";
367 }
368 
TEST(MimeType,IncompleteParameterIgnored1)369 TEST(MimeType, IncompleteParameterIgnored1)
370 {
371   const auto in = u"x/x;test"_ns;
372   UniquePtr<MimeType> parsed = MimeType::Parse(in);
373   ASSERT_TRUE(parsed)
374   << "Parsing succeeded";
375   nsAutoString out;
376   parsed->Serialize(out);
377   ASSERT_TRUE(out.EqualsLiteral("x/x"))
378   << "Incomplete parameter is ignored #1";
379 }
380 
TEST(MimeType,IncompleteParameterIgnored2)381 TEST(MimeType, IncompleteParameterIgnored2)
382 {
383   const auto in = u"x/x;test="_ns;
384   UniquePtr<MimeType> parsed = MimeType::Parse(in);
385   ASSERT_TRUE(parsed)
386   << "Parsing succeeded";
387   nsAutoString out;
388   parsed->Serialize(out);
389   ASSERT_TRUE(out.EqualsLiteral("x/x"))
390   << "Incomplete parameter is ignored #2";
391 }
392 
TEST(MimeType,IncompleteParameterIgnored3)393 TEST(MimeType, IncompleteParameterIgnored3)
394 {
395   const auto in = u"x/x;test= \r\n\t"_ns;
396   UniquePtr<MimeType> parsed = MimeType::Parse(in);
397   ASSERT_TRUE(parsed)
398   << "Parsing succeeded";
399   nsAutoString out;
400   parsed->Serialize(out);
401   ASSERT_TRUE(out.EqualsLiteral("x/x"))
402   << "Incomplete parameter is ignored #3";
403 }
404 
TEST(MimeType,IncompleteParameterIgnored4)405 TEST(MimeType, IncompleteParameterIgnored4)
406 {
407   const auto in = u"text/html;test;charset=gbk"_ns;
408   UniquePtr<MimeType> parsed = MimeType::Parse(in);
409   ASSERT_TRUE(parsed)
410   << "Parsing succeeded";
411   nsAutoString out;
412   parsed->Serialize(out);
413   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk"))
414   << "Incomplete parameter is ignored #4";
415 }
416 
TEST(MimeType,IncompleteParameterIgnored5)417 TEST(MimeType, IncompleteParameterIgnored5)
418 {
419   const auto in = u"text/html;test=;charset=gbk"_ns;
420   UniquePtr<MimeType> parsed = MimeType::Parse(in);
421   ASSERT_TRUE(parsed)
422   << "Parsing succeeded";
423   nsAutoString out;
424   parsed->Serialize(out);
425   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk"))
426   << "Incomplete parameter is ignored #5";
427 }
428 
TEST(MimeType,EmptyParameterIgnored1)429 TEST(MimeType, EmptyParameterIgnored1)
430 {
431   const auto in = u"text/html ; ; charset=gbk"_ns;
432   UniquePtr<MimeType> parsed = MimeType::Parse(in);
433   ASSERT_TRUE(parsed)
434   << "Parsing succeeded";
435   nsAutoString out;
436   parsed->Serialize(out);
437   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk"))
438   << "Empty parameter ignored #1";
439 }
440 
TEST(MimeType,EmptyParameterIgnored2)441 TEST(MimeType, EmptyParameterIgnored2)
442 {
443   const auto in = u"text/html;;;;charset=gbk"_ns;
444   UniquePtr<MimeType> parsed = MimeType::Parse(in);
445   ASSERT_TRUE(parsed)
446   << "Parsing succeeded";
447   nsAutoString out;
448   parsed->Serialize(out);
449   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk"))
450   << "Empty parameter ignored #2";
451 }
452 
TEST(MimeType,InvalidParameterIgnored1)453 TEST(MimeType, InvalidParameterIgnored1)
454 {
455   const auto in = u"text/html;';charset=gbk"_ns;
456   UniquePtr<MimeType> parsed = MimeType::Parse(in);
457   ASSERT_TRUE(parsed)
458   << "Parsing succeeded";
459   nsAutoString out;
460   parsed->Serialize(out);
461   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk"))
462   << "Invalid parameter ignored #1";
463 }
464 
TEST(MimeType,InvalidParameterIgnored2)465 TEST(MimeType, InvalidParameterIgnored2)
466 {
467   const auto in = u"text/html;\";charset=gbk;=123; =321"_ns;
468   UniquePtr<MimeType> parsed = MimeType::Parse(in);
469   ASSERT_TRUE(parsed)
470   << "Parsing succeeded";
471   nsAutoString out;
472   parsed->Serialize(out);
473   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk"))
474   << "Invalid parameter ignored #2";
475 }
476 
TEST(MimeType,InvalidParameterIgnored3)477 TEST(MimeType, InvalidParameterIgnored3)
478 {
479   const auto in = u"text/html;charset= \"\u007F;charset=GBK"_ns;
480   UniquePtr<MimeType> parsed = MimeType::Parse(in);
481   ASSERT_TRUE(parsed)
482   << "Parsing succeeded";
483   nsAutoString out;
484   parsed->Serialize(out);
485   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=GBK"))
486   << "Invalid parameter ignored #3";
487 }
488 
TEST(MimeType,InvalidParameterIgnored4)489 TEST(MimeType, InvalidParameterIgnored4)
490 {
491   const auto in = nsLiteralString(
492       u"text/html;charset=\"\u007F;charset=foo\";charset=GBK;charset=");
493   UniquePtr<MimeType> parsed = MimeType::Parse(in);
494   ASSERT_TRUE(parsed)
495   << "Parsing succeeded";
496   nsAutoString out;
497   parsed->Serialize(out);
498   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=GBK"))
499   << "Invalid parameter ignored #4";
500 }
501 
TEST(MimeType,SingleQuotes1)502 TEST(MimeType, SingleQuotes1)
503 {
504   const auto in = u"text/html;charset='gbk'"_ns;
505   UniquePtr<MimeType> parsed = MimeType::Parse(in);
506   ASSERT_TRUE(parsed)
507   << "Parsing succeeded";
508   nsAutoString out;
509   parsed->Serialize(out);
510   ASSERT_TRUE(out.EqualsLiteral("text/html;charset='gbk'"))
511   << "Single quotes handled properly #1";
512 }
513 
TEST(MimeType,SingleQuotes2)514 TEST(MimeType, SingleQuotes2)
515 {
516   const auto in = u"text/html;charset='gbk"_ns;
517   UniquePtr<MimeType> parsed = MimeType::Parse(in);
518   ASSERT_TRUE(parsed)
519   << "Parsing succeeded";
520   nsAutoString out;
521   parsed->Serialize(out);
522   ASSERT_TRUE(out.EqualsLiteral("text/html;charset='gbk"))
523   << "Single quotes handled properly #2";
524 }
525 
TEST(MimeType,SingleQuotes3)526 TEST(MimeType, SingleQuotes3)
527 {
528   const auto in = u"text/html;charset=gbk'"_ns;
529   UniquePtr<MimeType> parsed = MimeType::Parse(in);
530   ASSERT_TRUE(parsed)
531   << "Parsing succeeded";
532   nsAutoString out;
533   parsed->Serialize(out);
534   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk'"))
535   << "Single quotes handled properly #3";
536 }
537 
TEST(MimeType,SingleQuotes4)538 TEST(MimeType, SingleQuotes4)
539 {
540   const auto in = u"text/html;charset=';charset=GBK"_ns;
541   UniquePtr<MimeType> parsed = MimeType::Parse(in);
542   ASSERT_TRUE(parsed)
543   << "Parsing succeeded";
544   nsAutoString out;
545   parsed->Serialize(out);
546   ASSERT_TRUE(out.EqualsLiteral("text/html;charset='"))
547   << "Single quotes handled properly #4";
548 }
549 
TEST(MimeType,SingleQuotes5)550 TEST(MimeType, SingleQuotes5)
551 {
552   const auto in = u"text/html;charset=''';charset=GBK"_ns;
553   UniquePtr<MimeType> parsed = MimeType::Parse(in);
554   ASSERT_TRUE(parsed)
555   << "Parsing succeeded";
556   nsAutoString out;
557   parsed->Serialize(out);
558   ASSERT_TRUE(out.EqualsLiteral("text/html;charset='''"))
559   << "Single quotes handled properly #5";
560 }
561 
TEST(MimeType,DoubleQuotes1)562 TEST(MimeType, DoubleQuotes1)
563 {
564   const auto in = u"text/html;charset=\"gbk\""_ns;
565   UniquePtr<MimeType> parsed = MimeType::Parse(in);
566   ASSERT_TRUE(parsed)
567   << "Parsing succeeded";
568   nsAutoString out;
569   parsed->Serialize(out);
570   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk"))
571   << "Double quotes handled properly #1";
572 }
573 
TEST(MimeType,DoubleQuotes2)574 TEST(MimeType, DoubleQuotes2)
575 {
576   const auto in = u"text/html;charset=\"gbk"_ns;
577   UniquePtr<MimeType> parsed = MimeType::Parse(in);
578   ASSERT_TRUE(parsed)
579   << "Parsing succeeded";
580   nsAutoString out;
581   parsed->Serialize(out);
582   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk"))
583   << "Double quotes handled properly #2";
584 }
585 
TEST(MimeType,DoubleQuotes3)586 TEST(MimeType, DoubleQuotes3)
587 {
588   const auto in = u"text/html;charset=gbk\""_ns;
589   UniquePtr<MimeType> parsed = MimeType::Parse(in);
590   ASSERT_TRUE(parsed)
591   << "Parsing succeeded";
592   nsAutoString out;
593   parsed->Serialize(out);
594   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\"gbk\\\"\""))
595   << "Double quotes handled properly #3";
596 }
597 
TEST(MimeType,DoubleQuotes4)598 TEST(MimeType, DoubleQuotes4)
599 {
600   const auto in = u"text/html;charset=\" gbk\""_ns;
601   UniquePtr<MimeType> parsed = MimeType::Parse(in);
602   ASSERT_TRUE(parsed)
603   << "Parsing succeeded";
604   nsAutoString out;
605   parsed->Serialize(out);
606   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\" gbk\""))
607   << "Double quotes handled properly #4";
608 }
609 
TEST(MimeType,DoubleQuotes5)610 TEST(MimeType, DoubleQuotes5)
611 {
612   const auto in = u"text/html;charset=\"gbk \""_ns;
613   UniquePtr<MimeType> parsed = MimeType::Parse(in);
614   ASSERT_TRUE(parsed)
615   << "Parsing succeeded";
616   nsAutoString out;
617   parsed->Serialize(out);
618   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\"gbk \""))
619   << "Double quotes handled properly #5";
620 }
621 
TEST(MimeType,DoubleQuotes6)622 TEST(MimeType, DoubleQuotes6)
623 {
624   const auto in = u"text/html;charset=\"\\ gbk\""_ns;
625   UniquePtr<MimeType> parsed = MimeType::Parse(in);
626   ASSERT_TRUE(parsed)
627   << "Parsing succeeded";
628   nsAutoString out;
629   parsed->Serialize(out);
630   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\" gbk\""))
631   << "Double quotes handled properly #6";
632 }
633 
TEST(MimeType,DoubleQuotes7)634 TEST(MimeType, DoubleQuotes7)
635 {
636   const auto in = u"text/html;charset=\"\\g\\b\\k\""_ns;
637   UniquePtr<MimeType> parsed = MimeType::Parse(in);
638   ASSERT_TRUE(parsed)
639   << "Parsing succeeded";
640   nsAutoString out;
641   parsed->Serialize(out);
642   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk"))
643   << "Double quotes handled properly #7";
644 }
645 
TEST(MimeType,DoubleQuotes8)646 TEST(MimeType, DoubleQuotes8)
647 {
648   const auto in = u"text/html;charset=\"gbk\"x"_ns;
649   UniquePtr<MimeType> parsed = MimeType::Parse(in);
650   ASSERT_TRUE(parsed)
651   << "Parsing succeeded";
652   nsAutoString out;
653   parsed->Serialize(out);
654   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk"))
655   << "Double quotes handled properly #8";
656 }
657 
TEST(MimeType,DoubleQuotes9)658 TEST(MimeType, DoubleQuotes9)
659 {
660   const auto in = u"text/html;charset=\"\";charset=GBK"_ns;
661   UniquePtr<MimeType> parsed = MimeType::Parse(in);
662   ASSERT_TRUE(parsed)
663   << "Parsing succeeded";
664   nsAutoString out;
665   parsed->Serialize(out);
666   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\"\""))
667   << "Double quotes handled properly #9";
668 }
669 
TEST(MimeType,DoubleQuotes10)670 TEST(MimeType, DoubleQuotes10)
671 {
672   const auto in = u"text/html;charset=\";charset=GBK"_ns;
673   UniquePtr<MimeType> parsed = MimeType::Parse(in);
674   ASSERT_TRUE(parsed)
675   << "Parsing succeeded";
676   nsAutoString out;
677   parsed->Serialize(out);
678   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\";charset=GBK\""))
679   << "Double quotes handled properly #10";
680 }
681 
TEST(MimeType,UnexpectedCodePoints)682 TEST(MimeType, UnexpectedCodePoints)
683 {
684   const auto in = u"text/html;charset={gbk}"_ns;
685   UniquePtr<MimeType> parsed = MimeType::Parse(in);
686   ASSERT_TRUE(parsed)
687   << "Parsing succeeded";
688   nsAutoString out;
689   parsed->Serialize(out);
690   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\"{gbk}\""))
691   << "Unexpected code points handled properly";
692 }
693 
TEST(MimeType,LongTypesSubtypesAccepted)694 TEST(MimeType, LongTypesSubtypesAccepted)
695 {
696   const auto in = nsLiteralString(
697       u"01234567890123456789012345678901234567890123456789012345678901234567890"
698       u"1"
699       "2345678901234567890123456789012345678901234567890123456789/"
700       "012345678901234567890123456789012345678901234567890123456789012345678901"
701       "2345678901234567890123456789012345678901234567890123456789");
702   UniquePtr<MimeType> parsed = MimeType::Parse(in);
703   ASSERT_TRUE(parsed)
704   << "Parsing succeeded";
705   nsAutoString out;
706   parsed->Serialize(out);
707   ASSERT_TRUE(out.Equals(in))
708   << "Long type/subtype accepted";
709 }
710 
TEST(MimeType,LongParametersAccepted)711 TEST(MimeType, LongParametersAccepted)
712 {
713   const auto in = nsLiteralString(
714       u"text/"
715       "html;"
716       "012345678901234567890123456789012345678901234567890123456789012345678901"
717       "2345678901234567890123456789012345678901234567890123456789=x;charset="
718       "gbk");
719   UniquePtr<MimeType> parsed = MimeType::Parse(in);
720   ASSERT_TRUE(parsed)
721   << "Parsing succeeded";
722   nsAutoString out;
723   parsed->Serialize(out);
724   ASSERT_TRUE(out.Equals(in))
725   << "Long parameters accepted";
726 }
727 
TEST(MimeType,AllValidCharactersAccepted1)728 TEST(MimeType, AllValidCharactersAccepted1)
729 {
730   const auto in = nsLiteralString(
731       u"x/x;x=\"\t "
732       u"!\\\"#$%&'()*+,-./"
733       u"0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`"
734       u"abcdefghijklmnopqrstuvwxyz{|}~"
735       u"\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008A"
736       u"\u008B\u008C\u008D\u008E\u008F\u0090\u0091\u0092\u0093\u0094\u0095"
737       u"\u0096\u0097\u0098\u0099\u009A\u009B\u009C\u009D\u009E\u009F\u00A0"
738       u"\u00A1\u00A2\u00A3\u00A4\u00A5\u00A6\u00A7\u00A8\u00A9\u00AA\u00AB"
739       u"\u00AC\u00AD\u00AE\u00AF\u00B0\u00B1\u00B2\u00B3\u00B4\u00B5\u00B6"
740       u"\u00B7\u00B8\u00B9\u00BA\u00BB\u00BC\u00BD\u00BE\u00BF\u00C0\u00C1"
741       u"\u00C2\u00C3\u00C4\u00C5\u00C6\u00C7\u00C8\u00C9\u00CA\u00CB\u00CC"
742       u"\u00CD\u00CE\u00CF\u00D0\u00D1\u00D2\u00D3\u00D4\u00D5\u00D6\u00D7"
743       u"\u00D8\u00D9\u00DA\u00DB\u00DC\u00DD\u00DE\u00DF\u00E0\u00E1\u00E2"
744       u"\u00E3\u00E4\u00E5\u00E6\u00E7\u00E8\u00E9\u00EA\u00EB\u00EC\u00ED"
745       u"\u00EE\u00EF\u00F0\u00F1\u00F2\u00F3\u00F4\u00F5\u00F6\u00F7\u00F8"
746       u"\u00F9\u00FA\u00FB\u00FC\u00FD\u00FE\u00FF\"");
747   UniquePtr<MimeType> parsed = MimeType::Parse(in);
748   ASSERT_TRUE(parsed)
749   << "Parsing succeeded";
750   nsAutoString out;
751   parsed->Serialize(out);
752   ASSERT_TRUE(out.Equals(in))
753   << "All valid characters accepted #1";
754 }
755 
TEST(MimeType,CaseNormalization1)756 TEST(MimeType, CaseNormalization1)
757 {
758   const auto in = u"TEXT/PLAIN;CHARSET=TEST"_ns;
759   UniquePtr<MimeType> parsed = MimeType::Parse(in);
760   ASSERT_TRUE(parsed)
761   << "Parsing succeeded";
762   nsAutoString out;
763   parsed->Serialize(out);
764   ASSERT_TRUE(out.EqualsLiteral("text/plain;charset=TEST"))
765   << "Case normalized properly #1";
766 }
767 
TEST(MimeType,CaseNormalization2)768 TEST(MimeType, CaseNormalization2)
769 {
770   const auto in = nsLiteralString(
771       u"!#$%&'*+-.^_`|~"
772       "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/"
773       "!#$%&'*+-.^_`|~"
774       "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz;!#$%&'*+-"
775       ".^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=!#$"
776       "%&'*+-.^_`|~"
777       "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
778   UniquePtr<MimeType> parsed = MimeType::Parse(in);
779   ASSERT_TRUE(parsed)
780   << "Parsing succeeded";
781   nsAutoString out;
782   parsed->Serialize(out);
783   ASSERT_TRUE(out.EqualsLiteral(
784       "!#$%&'*+-.^_`|~"
785       "0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/"
786       "!#$%&'*+-.^_`|~"
787       "0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz;!#$%&'*+-"
788       ".^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz=!#$"
789       "%&'*+-.^_`|~"
790       "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"))
791   << "Case normalized properly #2";
792 }
793 
TEST(MimeType,LegacyCommentSyntax1)794 TEST(MimeType, LegacyCommentSyntax1)
795 {
796   const auto in = u"text/html;charset=gbk("_ns;
797   UniquePtr<MimeType> parsed = MimeType::Parse(in);
798   ASSERT_TRUE(parsed)
799   << "Parsing succeeded";
800   nsAutoString out;
801   parsed->Serialize(out);
802   ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\"gbk(\""))
803   << "Legacy comment syntax #1";
804 }
805 
TEST(MimeType,LegacyCommentSyntax2)806 TEST(MimeType, LegacyCommentSyntax2)
807 {
808   const auto in = u"text/html;x=(;charset=gbk"_ns;
809   UniquePtr<MimeType> parsed = MimeType::Parse(in);
810   ASSERT_TRUE(parsed)
811   << "Parsing succeeded";
812   nsAutoString out;
813   parsed->Serialize(out);
814   ASSERT_TRUE(out.EqualsLiteral("text/html;x=\"(\";charset=gbk"))
815   << "Legacy comment syntax #2";
816 }
817