TestMimeType.cpp (31818B)
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 "MimeType.h" 8 #include "gtest/gtest.h" 9 #include "nsString.h" 10 11 TEST(MimeType, EmptyString) 12 { 13 const auto in = u""_ns; 14 RefPtr<MimeType> parsed = MimeType::Parse(in); 15 ASSERT_FALSE(parsed) 16 << "Empty string"; 17 } 18 19 TEST(MimeType, JustWhitespace) 20 { 21 const auto in = u" \t\r\n "_ns; 22 RefPtr<MimeType> parsed = MimeType::Parse(in); 23 ASSERT_FALSE(parsed) 24 << "Just whitespace"; 25 } 26 27 TEST(MimeType, JustBackslash) 28 { 29 const auto in = u"\\"_ns; 30 RefPtr<MimeType> parsed = MimeType::Parse(in); 31 ASSERT_FALSE(parsed) 32 << "Just backslash"; 33 } 34 35 TEST(MimeType, JustForwardslash) 36 { 37 const auto in = u"/"_ns; 38 RefPtr<MimeType> parsed = MimeType::Parse(in); 39 ASSERT_FALSE(parsed) 40 << "Just forward slash"; 41 } 42 43 TEST(MimeType, MissingType1) 44 { 45 const auto in = u"/bogus"_ns; 46 RefPtr<MimeType> parsed = MimeType::Parse(in); 47 ASSERT_FALSE(parsed) 48 << "Missing type #1"; 49 } 50 51 TEST(MimeType, MissingType2) 52 { 53 const auto in = u" \r\n\t/bogus"_ns; 54 RefPtr<MimeType> parsed = MimeType::Parse(in); 55 ASSERT_FALSE(parsed) 56 << "Missing type #2"; 57 } 58 59 TEST(MimeType, MissingSubtype1) 60 { 61 const auto in = u"bogus"_ns; 62 RefPtr<MimeType> parsed = MimeType::Parse(in); 63 ASSERT_FALSE(parsed) 64 << "Missing subtype #1"; 65 } 66 67 TEST(MimeType, MissingSubType2) 68 { 69 const auto in = u"bogus/"_ns; 70 RefPtr<MimeType> parsed = MimeType::Parse(in); 71 ASSERT_FALSE(parsed) 72 << "Missing subtype #2"; 73 } 74 75 TEST(MimeType, MissingSubType3) 76 { 77 const auto in = u"bogus;"_ns; 78 RefPtr<MimeType> parsed = MimeType::Parse(in); 79 ASSERT_FALSE(parsed) 80 << "Missing subtype #3"; 81 } 82 83 TEST(MimeType, MissingSubType4) 84 { 85 const auto in = u"bogus; \r\n\t"_ns; 86 RefPtr<MimeType> parsed = MimeType::Parse(in); 87 ASSERT_FALSE(parsed) 88 << "Missing subtype #3"; 89 } 90 91 TEST(MimeType, ExtraForwardSlash) 92 { 93 const auto in = u"bogus/bogus/;"_ns; 94 RefPtr<MimeType> parsed = MimeType::Parse(in); 95 ASSERT_FALSE(parsed) 96 << "Extra forward slash"; 97 } 98 99 TEST(MimeType, WhitespaceInType) 100 { 101 const auto in = u"t\re\nx\tt /html"_ns; 102 RefPtr<MimeType> parsed = MimeType::Parse(in); 103 ASSERT_FALSE(parsed) 104 << "Type with whitespace"; 105 } 106 107 TEST(MimeType, WhitespaceInSubtype) 108 { 109 const auto in = u"text/ h\rt\nm\tl"_ns; 110 RefPtr<MimeType> parsed = MimeType::Parse(in); 111 ASSERT_FALSE(parsed) 112 << "Subtype with whitespace"; 113 } 114 115 TEST(MimeType, NonAlphanumericMediaType1) 116 { 117 const auto in = u"</>"_ns; 118 RefPtr<MimeType> parsed = MimeType::Parse(in); 119 ASSERT_FALSE(parsed) 120 << "Non-alphanumeric media type #1"; 121 } 122 123 TEST(MimeType, NonAlphanumericMediaType2) 124 { 125 const auto in = u"(/)"_ns; 126 RefPtr<MimeType> parsed = MimeType::Parse(in); 127 ASSERT_FALSE(parsed) 128 << "Non-alphanumeric media type #2"; 129 } 130 131 TEST(MimeType, NonAlphanumericMediaType3) 132 { 133 const auto in = u"{/}"_ns; 134 RefPtr<MimeType> parsed = MimeType::Parse(in); 135 ASSERT_FALSE(parsed) 136 << "Non-alphanumeric media type #3"; 137 } 138 139 TEST(MimeType, NonAlphanumericMediaType4) 140 { 141 const auto in = u"\"/\""_ns; 142 RefPtr<MimeType> parsed = MimeType::Parse(in); 143 ASSERT_FALSE(parsed) 144 << "Non-alphanumeric media type #4"; 145 } 146 147 TEST(MimeType, NonAlphanumericMediaType5) 148 { 149 const auto in = u"\0/\0"_ns; 150 RefPtr<MimeType> parsed = MimeType::Parse(in); 151 ASSERT_FALSE(parsed) 152 << "Non-alphanumeric media type #5"; 153 } 154 155 TEST(MimeType, NonAlphanumericMediaType6) 156 { 157 const auto in = u"text/html(;doesnot=matter"_ns; 158 RefPtr<MimeType> parsed = MimeType::Parse(in); 159 ASSERT_FALSE(parsed) 160 << "Non-alphanumeric media type #6"; 161 } 162 163 TEST(MimeType, NonLatin1MediaType1) 164 { 165 const auto in = u"ÿ/ÿ"_ns; 166 RefPtr<MimeType> parsed = MimeType::Parse(in); 167 ASSERT_FALSE(parsed) 168 << "Non-latin1 media type #1"; 169 } 170 171 TEST(MimeType, NonLatin1MediaType2) 172 { 173 const auto in = u"\x0100/\x0100"_ns; 174 RefPtr<MimeType> parsed = MimeType::Parse(in); 175 ASSERT_FALSE(parsed) 176 << "Non-latin1 media type #2"; 177 } 178 179 TEST(MimeType, MultipleParameters) 180 { 181 const auto in = u"text/html;charset=gbk;no=1;charset_=gbk_;yes=2"_ns; 182 RefPtr<MimeType> parsed = MimeType::Parse(in); 183 ASSERT_TRUE(parsed) 184 << "Parsing succeeded"; 185 nsString out; 186 parsed->Serialize(out); 187 ASSERT_TRUE(out.Equals(u"text/html;charset=gbk;no=1;charset_=gbk_;yes=2"_ns)) 188 << "Multiple parameters"; 189 } 190 191 TEST(MimeType, DuplicateParameter1) 192 { 193 const auto in = u"text/html;charset=gbk;charset=windows-1255"_ns; 194 RefPtr<MimeType> parsed = MimeType::Parse(in); 195 ASSERT_TRUE(parsed) 196 << "Parsing succeeded"; 197 nsString out; 198 parsed->Serialize(out); 199 ASSERT_TRUE(out.Equals(u"text/html;charset=gbk"_ns)) 200 << "Duplicate parameter #1"; 201 } 202 203 TEST(MimeType, DuplicateParameter2) 204 { 205 const auto in = u"text/html;charset=();charset=GBK"_ns; 206 RefPtr<MimeType> parsed = MimeType::Parse(in); 207 ASSERT_TRUE(parsed) 208 << "Parsing succeeded"; 209 nsString out; 210 parsed->Serialize(out); 211 ASSERT_TRUE(out.Equals(u"text/html;charset=\"()\""_ns)) 212 << "Duplicate parameter #2"; 213 } 214 215 TEST(MimeType, CString) 216 { 217 const auto in = "text/html;charset=();charset=GBK"_ns; 218 RefPtr<CMimeType> parsed = CMimeType::Parse(in); 219 ASSERT_TRUE(parsed) 220 << "Parsing succeeded"; 221 nsCString out; 222 parsed->Serialize(out); 223 ASSERT_TRUE(out.Equals("text/html;charset=\"()\""_ns)) 224 << "Duplicate parameter #2"; 225 } 226 227 #ifdef _MSC_VER 228 # pragma warning(push) 229 # pragma warning(disable : 4819) 230 #endif 231 TEST(MimeType, NonAlphanumericParametersAreQuoted) 232 { 233 const auto in = u"text/html;test=\x00FF\\;charset=gbk"_ns; 234 RefPtr<MimeType> parsed = MimeType::Parse(in); 235 ASSERT_TRUE(parsed) 236 << "Parsing succeeded"; 237 nsString out; 238 parsed->Serialize(out); 239 ASSERT_TRUE(out.Equals(u"text/html;test=\"\x00FF\\\\\";charset=gbk"_ns)) 240 << "Non-alphanumeric parameters are quoted"; 241 } 242 #ifdef _MSC_VER 243 # pragma warning(pop) 244 #endif 245 246 TEST(MimeType, ParameterQuotedIfHasLeadingWhitespace1) 247 { 248 const auto in = u"text/html;charset= g\\\"bk"_ns; 249 RefPtr<MimeType> parsed = MimeType::Parse(in); 250 ASSERT_TRUE(parsed) 251 << "Parsing succeeded"; 252 nsAutoString out; 253 parsed->Serialize(out); 254 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\" g\\\\\\\"bk\"")) 255 << "Parameter is quoted if has leading whitespace #1"; 256 } 257 258 TEST(MimeType, ParameterQuotedIfHasLeadingWhitespace2) 259 { 260 const auto in = u"text/html;charset= \"g\\bk\""_ns; 261 RefPtr<MimeType> parsed = MimeType::Parse(in); 262 ASSERT_TRUE(parsed) 263 << "Parsing succeeded"; 264 nsAutoString out; 265 parsed->Serialize(out); 266 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\" \\\"g\\\\bk\\\"\"")) 267 << "Parameter is quoted if has leading whitespace #2"; 268 } 269 270 TEST(MimeType, ParameterQuotedIfHasInternalWhitespace) 271 { 272 const auto in = u"text/html;charset=g \\b\"k"_ns; 273 RefPtr<MimeType> parsed = MimeType::Parse(in); 274 ASSERT_TRUE(parsed) 275 << "Parsing succeeded"; 276 nsAutoString out; 277 parsed->Serialize(out); 278 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\"g \\\\b\\\"k\"")) 279 << "Parameter is quoted if has internal whitespace"; 280 } 281 282 TEST(MimeType, ImproperlyQuotedParameter1) 283 { 284 const auto in = u"x/x;test=\""_ns; 285 RefPtr<MimeType> parsed = MimeType::Parse(in); 286 ASSERT_TRUE(parsed) 287 << "Parsing succeeded"; 288 nsAutoString out; 289 parsed->Serialize(out); 290 ASSERT_TRUE(out.EqualsLiteral("x/x;test=\"\"")) 291 << "Improperly-quoted parameter is handled properly #1"; 292 } 293 294 TEST(MimeType, ImproperlyQuotedParameter2) 295 { 296 const auto in = u"x/x;test=\"\\"_ns; 297 RefPtr<MimeType> parsed = MimeType::Parse(in); 298 ASSERT_TRUE(parsed) 299 << "Parsing succeeded"; 300 nsAutoString out; 301 parsed->Serialize(out); 302 ASSERT_TRUE(out.EqualsLiteral("x/x;test=\"\\\\\"")) 303 << "Improperly-quoted parameter is handled properly #2"; 304 } 305 306 TEST(MimeType, NonLatin1ParameterIgnored) 307 { 308 const auto in = u"x/x;test=\xFFFD;x=x"_ns; 309 RefPtr<MimeType> parsed = MimeType::Parse(in); 310 ASSERT_TRUE(parsed) 311 << "Parsing succeeded"; 312 nsAutoString out; 313 parsed->Serialize(out); 314 ASSERT_TRUE(out.EqualsLiteral("x/x;x=x")) 315 << "Non latin-1 parameters are ignored"; 316 } 317 318 TEST(MimeType, ParameterIgnoredIfWhitespaceInName1) 319 { 320 const auto in = u"text/html;charset =gbk;charset=123"_ns; 321 RefPtr<MimeType> parsed = MimeType::Parse(in); 322 ASSERT_TRUE(parsed) 323 << "Parsing succeeded"; 324 nsAutoString out; 325 parsed->Serialize(out); 326 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=123")) 327 << "Parameter ignored if whitespace in name #1"; 328 } 329 330 TEST(MimeType, ParameterIgnoredIfWhitespaceInName2) 331 { 332 const auto in = u"text/html;cha rset =gbk;charset=123"_ns; 333 RefPtr<MimeType> parsed = MimeType::Parse(in); 334 ASSERT_TRUE(parsed) 335 << "Parsing succeeded"; 336 nsAutoString out; 337 parsed->Serialize(out); 338 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=123")) 339 << "Parameter ignored if whitespace in name #2"; 340 } 341 342 TEST(MimeType, WhitespaceTrimmed) 343 { 344 const auto in = u"\n\r\t text/plain\n\r\t ;\n\r\t charset=123\n\r\t "_ns; 345 RefPtr<MimeType> parsed = MimeType::Parse(in); 346 ASSERT_TRUE(parsed) 347 << "Parsing succeeded"; 348 nsAutoString out; 349 parsed->Serialize(out); 350 ASSERT_TRUE(out.EqualsLiteral("text/plain;charset=123")) 351 << "Whitespace appropriately ignored"; 352 } 353 354 TEST(MimeType, WhitespaceOnlyParameterIgnored) 355 { 356 const auto in = u"x/x;x= \r\n\t"_ns; 357 RefPtr<MimeType> parsed = MimeType::Parse(in); 358 ASSERT_TRUE(parsed) 359 << "Parsing succeeded"; 360 nsAutoString out; 361 parsed->Serialize(out); 362 ASSERT_TRUE(out.EqualsLiteral("x/x")) 363 << "Whitespace-only parameter is ignored"; 364 } 365 366 TEST(MimeType, IncompleteParameterIgnored1) 367 { 368 const auto in = u"x/x;test"_ns; 369 RefPtr<MimeType> parsed = MimeType::Parse(in); 370 ASSERT_TRUE(parsed) 371 << "Parsing succeeded"; 372 nsAutoString out; 373 parsed->Serialize(out); 374 ASSERT_TRUE(out.EqualsLiteral("x/x")) 375 << "Incomplete parameter is ignored #1"; 376 } 377 378 TEST(MimeType, IncompleteParameterIgnored2) 379 { 380 const auto in = u"x/x;test="_ns; 381 RefPtr<MimeType> parsed = MimeType::Parse(in); 382 ASSERT_TRUE(parsed) 383 << "Parsing succeeded"; 384 nsAutoString out; 385 parsed->Serialize(out); 386 ASSERT_TRUE(out.EqualsLiteral("x/x")) 387 << "Incomplete parameter is ignored #2"; 388 } 389 390 TEST(MimeType, IncompleteParameterIgnored3) 391 { 392 const auto in = u"x/x;test= \r\n\t"_ns; 393 RefPtr<MimeType> parsed = MimeType::Parse(in); 394 ASSERT_TRUE(parsed) 395 << "Parsing succeeded"; 396 nsAutoString out; 397 parsed->Serialize(out); 398 ASSERT_TRUE(out.EqualsLiteral("x/x")) 399 << "Incomplete parameter is ignored #3"; 400 } 401 402 TEST(MimeType, IncompleteParameterIgnored4) 403 { 404 const auto in = u"text/html;test;charset=gbk"_ns; 405 RefPtr<MimeType> parsed = MimeType::Parse(in); 406 ASSERT_TRUE(parsed) 407 << "Parsing succeeded"; 408 nsAutoString out; 409 parsed->Serialize(out); 410 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk")) 411 << "Incomplete parameter is ignored #4"; 412 } 413 414 TEST(MimeType, IncompleteParameterIgnored5) 415 { 416 const auto in = u"text/html;test=;charset=gbk"_ns; 417 RefPtr<MimeType> parsed = MimeType::Parse(in); 418 ASSERT_TRUE(parsed) 419 << "Parsing succeeded"; 420 nsAutoString out; 421 parsed->Serialize(out); 422 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk")) 423 << "Incomplete parameter is ignored #5"; 424 } 425 426 TEST(MimeType, EmptyParameterIgnored1) 427 { 428 const auto in = u"text/html ; ; charset=gbk"_ns; 429 RefPtr<MimeType> parsed = MimeType::Parse(in); 430 ASSERT_TRUE(parsed) 431 << "Parsing succeeded"; 432 nsAutoString out; 433 parsed->Serialize(out); 434 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk")) 435 << "Empty parameter ignored #1"; 436 } 437 438 TEST(MimeType, EmptyParameterIgnored2) 439 { 440 const auto in = u"text/html;;;;charset=gbk"_ns; 441 RefPtr<MimeType> parsed = MimeType::Parse(in); 442 ASSERT_TRUE(parsed) 443 << "Parsing succeeded"; 444 nsAutoString out; 445 parsed->Serialize(out); 446 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk")) 447 << "Empty parameter ignored #2"; 448 } 449 450 TEST(MimeType, InvalidParameterIgnored1) 451 { 452 const auto in = u"text/html;';charset=gbk"_ns; 453 RefPtr<MimeType> parsed = MimeType::Parse(in); 454 ASSERT_TRUE(parsed) 455 << "Parsing succeeded"; 456 nsAutoString out; 457 parsed->Serialize(out); 458 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk")) 459 << "Invalid parameter ignored #1"; 460 } 461 462 TEST(MimeType, InvalidParameterIgnored2) 463 { 464 const auto in = u"text/html;\";charset=gbk;=123; =321"_ns; 465 RefPtr<MimeType> parsed = MimeType::Parse(in); 466 ASSERT_TRUE(parsed) 467 << "Parsing succeeded"; 468 nsAutoString out; 469 parsed->Serialize(out); 470 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk")) 471 << "Invalid parameter ignored #2"; 472 } 473 474 TEST(MimeType, InvalidParameterIgnored3) 475 { 476 const auto in = u"text/html;charset= \"\u007F;charset=GBK"_ns; 477 RefPtr<MimeType> parsed = MimeType::Parse(in); 478 ASSERT_TRUE(parsed) 479 << "Parsing succeeded"; 480 nsAutoString out; 481 parsed->Serialize(out); 482 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=GBK")) 483 << "Invalid parameter ignored #3"; 484 } 485 486 TEST(MimeType, InvalidParameterIgnored4) 487 { 488 const auto in = nsLiteralString( 489 u"text/html;charset=\"\u007F;charset=foo\";charset=GBK;charset="); 490 RefPtr<MimeType> parsed = MimeType::Parse(in); 491 ASSERT_TRUE(parsed) 492 << "Parsing succeeded"; 493 nsAutoString out; 494 parsed->Serialize(out); 495 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=GBK")) 496 << "Invalid parameter ignored #4"; 497 } 498 499 TEST(MimeType, SingleQuotes1) 500 { 501 const auto in = u"text/html;charset='gbk'"_ns; 502 RefPtr<MimeType> parsed = MimeType::Parse(in); 503 ASSERT_TRUE(parsed) 504 << "Parsing succeeded"; 505 nsAutoString out; 506 parsed->Serialize(out); 507 ASSERT_TRUE(out.EqualsLiteral("text/html;charset='gbk'")) 508 << "Single quotes handled properly #1"; 509 } 510 511 TEST(MimeType, SingleQuotes2) 512 { 513 const auto in = u"text/html;charset='gbk"_ns; 514 RefPtr<MimeType> parsed = MimeType::Parse(in); 515 ASSERT_TRUE(parsed) 516 << "Parsing succeeded"; 517 nsAutoString out; 518 parsed->Serialize(out); 519 ASSERT_TRUE(out.EqualsLiteral("text/html;charset='gbk")) 520 << "Single quotes handled properly #2"; 521 } 522 523 TEST(MimeType, SingleQuotes3) 524 { 525 const auto in = u"text/html;charset=gbk'"_ns; 526 RefPtr<MimeType> parsed = MimeType::Parse(in); 527 ASSERT_TRUE(parsed) 528 << "Parsing succeeded"; 529 nsAutoString out; 530 parsed->Serialize(out); 531 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk'")) 532 << "Single quotes handled properly #3"; 533 } 534 535 TEST(MimeType, SingleQuotes4) 536 { 537 const auto in = u"text/html;charset=';charset=GBK"_ns; 538 RefPtr<MimeType> parsed = MimeType::Parse(in); 539 ASSERT_TRUE(parsed) 540 << "Parsing succeeded"; 541 nsAutoString out; 542 parsed->Serialize(out); 543 ASSERT_TRUE(out.EqualsLiteral("text/html;charset='")) 544 << "Single quotes handled properly #4"; 545 } 546 547 TEST(MimeType, SingleQuotes5) 548 { 549 const auto in = u"text/html;charset=''';charset=GBK"_ns; 550 RefPtr<MimeType> parsed = MimeType::Parse(in); 551 ASSERT_TRUE(parsed) 552 << "Parsing succeeded"; 553 nsAutoString out; 554 parsed->Serialize(out); 555 ASSERT_TRUE(out.EqualsLiteral("text/html;charset='''")) 556 << "Single quotes handled properly #5"; 557 } 558 559 TEST(MimeType, DoubleQuotes1) 560 { 561 const auto in = u"text/html;charset=\"gbk\""_ns; 562 RefPtr<MimeType> parsed = MimeType::Parse(in); 563 ASSERT_TRUE(parsed) 564 << "Parsing succeeded"; 565 nsAutoString out; 566 parsed->Serialize(out); 567 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk")) 568 << "Double quotes handled properly #1"; 569 } 570 571 TEST(MimeType, DoubleQuotes2) 572 { 573 const auto in = u"text/html;charset=\"gbk"_ns; 574 RefPtr<MimeType> parsed = MimeType::Parse(in); 575 ASSERT_TRUE(parsed) 576 << "Parsing succeeded"; 577 nsAutoString out; 578 parsed->Serialize(out); 579 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk")) 580 << "Double quotes handled properly #2"; 581 } 582 583 TEST(MimeType, DoubleQuotes3) 584 { 585 const auto in = u"text/html;charset=gbk\""_ns; 586 RefPtr<MimeType> parsed = MimeType::Parse(in); 587 ASSERT_TRUE(parsed) 588 << "Parsing succeeded"; 589 nsAutoString out; 590 parsed->Serialize(out); 591 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\"gbk\\\"\"")) 592 << "Double quotes handled properly #3"; 593 } 594 595 TEST(MimeType, DoubleQuotes4) 596 { 597 const auto in = u"text/html;charset=\" gbk\""_ns; 598 RefPtr<MimeType> parsed = MimeType::Parse(in); 599 ASSERT_TRUE(parsed) 600 << "Parsing succeeded"; 601 nsAutoString out; 602 parsed->Serialize(out); 603 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\" gbk\"")) 604 << "Double quotes handled properly #4"; 605 } 606 607 TEST(MimeType, DoubleQuotes5) 608 { 609 const auto in = u"text/html;charset=\"gbk \""_ns; 610 RefPtr<MimeType> parsed = MimeType::Parse(in); 611 ASSERT_TRUE(parsed) 612 << "Parsing succeeded"; 613 nsAutoString out; 614 parsed->Serialize(out); 615 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\"gbk \"")) 616 << "Double quotes handled properly #5"; 617 } 618 619 TEST(MimeType, DoubleQuotes6) 620 { 621 const auto in = u"text/html;charset=\"\\ gbk\""_ns; 622 RefPtr<MimeType> parsed = MimeType::Parse(in); 623 ASSERT_TRUE(parsed) 624 << "Parsing succeeded"; 625 nsAutoString out; 626 parsed->Serialize(out); 627 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\" gbk\"")) 628 << "Double quotes handled properly #6"; 629 } 630 631 TEST(MimeType, DoubleQuotes7) 632 { 633 const auto in = u"text/html;charset=\"\\g\\b\\k\""_ns; 634 RefPtr<MimeType> parsed = MimeType::Parse(in); 635 ASSERT_TRUE(parsed) 636 << "Parsing succeeded"; 637 nsAutoString out; 638 parsed->Serialize(out); 639 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk")) 640 << "Double quotes handled properly #7"; 641 } 642 643 TEST(MimeType, DoubleQuotes8) 644 { 645 const auto in = u"text/html;charset=\"gbk\"x"_ns; 646 RefPtr<MimeType> parsed = MimeType::Parse(in); 647 ASSERT_TRUE(parsed) 648 << "Parsing succeeded"; 649 nsAutoString out; 650 parsed->Serialize(out); 651 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=gbk")) 652 << "Double quotes handled properly #8"; 653 } 654 655 TEST(MimeType, DoubleQuotes9) 656 { 657 const auto in = u"text/html;charset=\"\";charset=GBK"_ns; 658 RefPtr<MimeType> parsed = MimeType::Parse(in); 659 ASSERT_TRUE(parsed) 660 << "Parsing succeeded"; 661 nsAutoString out; 662 parsed->Serialize(out); 663 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\"\"")) 664 << "Double quotes handled properly #9"; 665 } 666 667 TEST(MimeType, DoubleQuotes10) 668 { 669 const auto in = u"text/html;charset=\";charset=GBK"_ns; 670 RefPtr<MimeType> parsed = MimeType::Parse(in); 671 ASSERT_TRUE(parsed) 672 << "Parsing succeeded"; 673 nsAutoString out; 674 parsed->Serialize(out); 675 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\";charset=GBK\"")) 676 << "Double quotes handled properly #10"; 677 } 678 679 TEST(MimeType, UnexpectedCodePoints) 680 { 681 const auto in = u"text/html;charset={gbk}"_ns; 682 RefPtr<MimeType> parsed = MimeType::Parse(in); 683 ASSERT_TRUE(parsed) 684 << "Parsing succeeded"; 685 nsAutoString out; 686 parsed->Serialize(out); 687 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\"{gbk}\"")) 688 << "Unexpected code points handled properly"; 689 } 690 691 TEST(MimeType, LongTypesSubtypesAccepted) 692 { 693 const auto in = nsLiteralString( 694 u"01234567890123456789012345678901234567890123456789012345678901234567890" 695 u"1" 696 "2345678901234567890123456789012345678901234567890123456789/" 697 "012345678901234567890123456789012345678901234567890123456789012345678901" 698 "2345678901234567890123456789012345678901234567890123456789"); 699 RefPtr<MimeType> parsed = MimeType::Parse(in); 700 ASSERT_TRUE(parsed) 701 << "Parsing succeeded"; 702 nsAutoString out; 703 parsed->Serialize(out); 704 ASSERT_TRUE(out.Equals(in)) 705 << "Long type/subtype accepted"; 706 } 707 708 TEST(MimeType, LongParametersAccepted) 709 { 710 const auto in = nsLiteralString( 711 u"text/" 712 "html;" 713 "012345678901234567890123456789012345678901234567890123456789012345678901" 714 "2345678901234567890123456789012345678901234567890123456789=x;charset=" 715 "gbk"); 716 RefPtr<MimeType> parsed = MimeType::Parse(in); 717 ASSERT_TRUE(parsed) 718 << "Parsing succeeded"; 719 nsAutoString out; 720 parsed->Serialize(out); 721 ASSERT_TRUE(out.Equals(in)) 722 << "Long parameters accepted"; 723 } 724 725 TEST(MimeType, AllValidCharactersAccepted1) 726 { 727 const auto in = nsLiteralString( 728 u"x/x;x=\"\t " 729 u"!\\\"#$%&'()*+,-./" 730 u"0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`" 731 u"abcdefghijklmnopqrstuvwxyz{|}~" 732 u"\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008A" 733 u"\u008B\u008C\u008D\u008E\u008F\u0090\u0091\u0092\u0093\u0094\u0095" 734 u"\u0096\u0097\u0098\u0099\u009A\u009B\u009C\u009D\u009E\u009F\u00A0" 735 u"\u00A1\u00A2\u00A3\u00A4\u00A5\u00A6\u00A7\u00A8\u00A9\u00AA\u00AB" 736 u"\u00AC\u00AD\u00AE\u00AF\u00B0\u00B1\u00B2\u00B3\u00B4\u00B5\u00B6" 737 u"\u00B7\u00B8\u00B9\u00BA\u00BB\u00BC\u00BD\u00BE\u00BF\u00C0\u00C1" 738 u"\u00C2\u00C3\u00C4\u00C5\u00C6\u00C7\u00C8\u00C9\u00CA\u00CB\u00CC" 739 u"\u00CD\u00CE\u00CF\u00D0\u00D1\u00D2\u00D3\u00D4\u00D5\u00D6\u00D7" 740 u"\u00D8\u00D9\u00DA\u00DB\u00DC\u00DD\u00DE\u00DF\u00E0\u00E1\u00E2" 741 u"\u00E3\u00E4\u00E5\u00E6\u00E7\u00E8\u00E9\u00EA\u00EB\u00EC\u00ED" 742 u"\u00EE\u00EF\u00F0\u00F1\u00F2\u00F3\u00F4\u00F5\u00F6\u00F7\u00F8" 743 u"\u00F9\u00FA\u00FB\u00FC\u00FD\u00FE\u00FF\""); 744 RefPtr<MimeType> parsed = MimeType::Parse(in); 745 ASSERT_TRUE(parsed) 746 << "Parsing succeeded"; 747 nsAutoString out; 748 parsed->Serialize(out); 749 ASSERT_TRUE(out.Equals(in)) 750 << "All valid characters accepted #1"; 751 } 752 753 TEST(MimeType, CaseNormalization1) 754 { 755 const auto in = u"TEXT/PLAIN;CHARSET=TEST"_ns; 756 RefPtr<MimeType> parsed = MimeType::Parse(in); 757 ASSERT_TRUE(parsed) 758 << "Parsing succeeded"; 759 nsAutoString out; 760 parsed->Serialize(out); 761 ASSERT_TRUE(out.EqualsLiteral("text/plain;charset=TEST")) 762 << "Case normalized properly #1"; 763 } 764 765 TEST(MimeType, CaseNormalization2) 766 { 767 const auto in = nsLiteralString( 768 u"!#$%&'*+-.^_`|~" 769 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/" 770 "!#$%&'*+-.^_`|~" 771 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz;!#$%&'*+-" 772 ".^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=!#$" 773 "%&'*+-.^_`|~" 774 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); 775 RefPtr<MimeType> parsed = MimeType::Parse(in); 776 ASSERT_TRUE(parsed) 777 << "Parsing succeeded"; 778 nsAutoString out; 779 parsed->Serialize(out); 780 ASSERT_TRUE(out.EqualsLiteral( 781 "!#$%&'*+-.^_`|~" 782 "0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/" 783 "!#$%&'*+-.^_`|~" 784 "0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz;!#$%&'*+-" 785 ".^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz=!#$" 786 "%&'*+-.^_`|~" 787 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")) 788 << "Case normalized properly #2"; 789 } 790 791 TEST(MimeType, LegacyCommentSyntax1) 792 { 793 const auto in = u"text/html;charset=gbk("_ns; 794 RefPtr<MimeType> parsed = MimeType::Parse(in); 795 ASSERT_TRUE(parsed) 796 << "Parsing succeeded"; 797 nsAutoString out; 798 parsed->Serialize(out); 799 ASSERT_TRUE(out.EqualsLiteral("text/html;charset=\"gbk(\"")) 800 << "Legacy comment syntax #1"; 801 } 802 803 TEST(MimeType, LegacyCommentSyntax2) 804 { 805 const auto in = u"text/html;x=(;charset=gbk"_ns; 806 RefPtr<MimeType> parsed = MimeType::Parse(in); 807 ASSERT_TRUE(parsed) 808 << "Parsing succeeded"; 809 nsAutoString out; 810 parsed->Serialize(out); 811 ASSERT_TRUE(out.EqualsLiteral("text/html;x=\"(\";charset=gbk")) 812 << "Legacy comment syntax #2"; 813 } 814 815 TEST(MimeTypeParsing, contentTypes1) 816 { 817 const nsAutoCString val(",text/plain"); 818 nsCString contentType; 819 nsCString contentCharset; 820 821 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 822 823 ASSERT_FALSE(parsed); 824 ASSERT_TRUE(contentType.EqualsLiteral("")); 825 ASSERT_TRUE(contentCharset.EqualsLiteral("")); 826 } 827 828 TEST(MimeTypeParsing, contentTypes2) 829 { 830 const nsAutoCString val("text/plain,"); 831 nsCString contentType; 832 nsCString contentCharset; 833 834 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 835 836 ASSERT_TRUE(parsed); 837 ASSERT_TRUE(contentType.EqualsLiteral("text/plain")); 838 ASSERT_TRUE(contentCharset.EqualsLiteral("")); 839 } 840 841 TEST(MimeTypeParsing, contentTypes3) 842 { 843 const nsAutoCString val("text/html,text/plain"); 844 nsCString contentType; 845 nsCString contentCharset; 846 847 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 848 849 ASSERT_TRUE(parsed); 850 ASSERT_TRUE(contentType.EqualsLiteral("text/plain")); 851 ASSERT_TRUE(contentCharset.EqualsLiteral("")); 852 } 853 854 TEST(MimeTypeParsing, contentTypes4) 855 { 856 const nsAutoCString val("text/plain;charset=gbk,text/html"); 857 nsCString contentType; 858 nsCString contentCharset; 859 860 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 861 862 ASSERT_TRUE(parsed); 863 ASSERT_TRUE(contentType.EqualsLiteral("text/html")); 864 ASSERT_TRUE(contentCharset.EqualsLiteral("")); 865 } 866 867 TEST(MimeTypeParsing, contentTypes5) 868 { 869 const nsAutoCString val( 870 "text/plain;charset=gbk,text/html;charset=windows-1254"); 871 nsCString contentType; 872 nsCString contentCharset; 873 874 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 875 876 ASSERT_TRUE(parsed); 877 ASSERT_TRUE(contentType.EqualsLiteral("text/html")); 878 ASSERT_TRUE(contentCharset.EqualsLiteral("windows-1254")); 879 } 880 881 TEST(MimeTypeParsing, contentTypes6) 882 { 883 const nsAutoCString val("text/plain;charset=gbk,text/plain"); 884 nsCString contentType; 885 nsCString contentCharset; 886 887 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 888 889 ASSERT_TRUE(parsed); 890 ASSERT_TRUE(contentType.EqualsLiteral("text/plain")); 891 ASSERT_TRUE(contentCharset.EqualsLiteral("gbk")); 892 } 893 894 TEST(MimeTypeParsing, contentTypes7) 895 { 896 const nsAutoCString val( 897 "text/plain;charset=gbk,text/plain;charset=windows-1252"); 898 nsCString contentType; 899 nsCString contentCharset; 900 901 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 902 903 ASSERT_TRUE(parsed); 904 ASSERT_TRUE(contentType.EqualsLiteral("text/plain")); 905 ASSERT_TRUE(contentCharset.EqualsLiteral("windows-1252")); 906 } 907 908 TEST(MimeTypeParsing, contentTypes8) 909 { 910 const nsAutoCString val("text/html;charset=gbk,text/html;x=\",text/plain"); 911 nsCString contentType; 912 nsCString contentCharset; 913 914 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 915 916 ASSERT_TRUE(parsed); 917 ASSERT_TRUE(contentType.EqualsLiteral("text/html")); 918 ASSERT_TRUE(contentCharset.EqualsLiteral("gbk")); 919 } 920 921 TEST(MimeTypeParsing, contentTypes9) 922 { 923 const nsAutoCString val("text/plain;charset=gbk;x=foo,text/plain"); 924 nsCString contentType; 925 nsCString contentCharset; 926 927 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 928 929 ASSERT_TRUE(parsed); 930 ASSERT_TRUE(contentType.EqualsLiteral("text/plain")); 931 ASSERT_TRUE(contentCharset.EqualsLiteral("gbk")); 932 } 933 934 TEST(MimeTypeParsing, contentTypes10) 935 { 936 const nsAutoCString val("text/html;charset=gbk,text/plain,text/html"); 937 nsCString contentType; 938 nsCString contentCharset; 939 940 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 941 942 ASSERT_TRUE(parsed); 943 ASSERT_TRUE(contentType.EqualsLiteral("text/html")); 944 ASSERT_TRUE(contentCharset.EqualsLiteral("")); 945 } 946 947 TEST(MimeTypeParsing, contentTypes11) 948 { 949 const nsAutoCString val("text/plain,*/*"); 950 nsCString contentType; 951 nsCString contentCharset; 952 953 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 954 955 ASSERT_TRUE(parsed); 956 ASSERT_TRUE(contentType.EqualsLiteral("text/plain")); 957 ASSERT_TRUE(contentCharset.EqualsLiteral("")); 958 } 959 960 TEST(MimeTypeParsing, contentTypes12) 961 { 962 const nsAutoCString val("text/html,*/*"); 963 nsCString contentType; 964 nsCString contentCharset; 965 966 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 967 968 ASSERT_TRUE(parsed); 969 ASSERT_TRUE(contentType.EqualsLiteral("text/html")); 970 ASSERT_TRUE(contentCharset.EqualsLiteral("")); 971 } 972 973 TEST(MimeTypeParsing, contentTypes13) 974 { 975 const nsAutoCString val("*/*,text/html"); 976 nsCString contentType; 977 nsCString contentCharset; 978 979 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 980 981 ASSERT_TRUE(parsed); 982 ASSERT_TRUE(contentType.EqualsLiteral("text/html")); 983 ASSERT_TRUE(contentCharset.EqualsLiteral("")); 984 } 985 986 TEST(MimeTypeParsing, contentTypes14) 987 { 988 const nsAutoCString val("text/plain,*/*;charset=gbk"); 989 nsCString contentType; 990 nsCString contentCharset; 991 992 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 993 994 ASSERT_TRUE(parsed); 995 ASSERT_TRUE(contentType.EqualsLiteral("text/plain")); 996 ASSERT_TRUE(contentCharset.EqualsLiteral("")); 997 } 998 999 TEST(MimeTypeParsing, contentTypes15) 1000 { 1001 const nsAutoCString val("text/html,*/*;charset=gbk"); 1002 nsCString contentType; 1003 nsCString contentCharset; 1004 1005 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 1006 1007 ASSERT_TRUE(parsed); 1008 ASSERT_TRUE(contentType.EqualsLiteral("text/html")); 1009 ASSERT_TRUE(contentCharset.EqualsLiteral("")); 1010 } 1011 1012 TEST(MimeTypeParsing, contentTypes16) 1013 { 1014 const nsAutoCString val("text/html;x=\",text/plain"); 1015 nsCString contentType; 1016 nsCString contentCharset; 1017 1018 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 1019 1020 ASSERT_TRUE(parsed); 1021 ASSERT_TRUE(contentType.EqualsLiteral("text/html")); 1022 ASSERT_TRUE(contentCharset.EqualsLiteral("")); 1023 } 1024 1025 TEST(MimeTypeParsing, contentTypes17) 1026 { 1027 const nsAutoCString val("text/html;\",text/plain"); 1028 nsCString contentType; 1029 nsCString contentCharset; 1030 1031 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 1032 1033 ASSERT_TRUE(parsed); 1034 ASSERT_TRUE(contentType.EqualsLiteral("text/html")); 1035 ASSERT_TRUE(contentCharset.EqualsLiteral("")); 1036 } 1037 1038 TEST(MimeTypeParsing, contentTypes18) 1039 { 1040 const nsAutoCString val("text/html;\",\\\",text/plain"); 1041 nsCString contentType; 1042 nsCString contentCharset; 1043 1044 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 1045 1046 ASSERT_TRUE(parsed); 1047 ASSERT_TRUE(contentType.EqualsLiteral("text/html")); 1048 ASSERT_TRUE(contentCharset.EqualsLiteral("")); 1049 } 1050 1051 TEST(MimeTypeParsing, contentTypes19) 1052 { 1053 const nsAutoCString val("text/html;\",\\\",text/plain,\";charset=GBK"); 1054 nsCString contentType; 1055 nsCString contentCharset; 1056 1057 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 1058 1059 ASSERT_TRUE(parsed); 1060 ASSERT_TRUE(contentType.EqualsLiteral("text/html")); 1061 ASSERT_TRUE(contentCharset.EqualsLiteral("GBK")); 1062 } 1063 1064 TEST(MimeTypeParsing, contentTypes20) 1065 { 1066 const nsAutoCString val("text/html;\",\",text/plain"); 1067 nsCString contentType; 1068 nsCString contentCharset; 1069 1070 bool parsed = CMimeType::Parse(val, contentType, contentCharset); 1071 1072 ASSERT_TRUE(parsed); 1073 ASSERT_TRUE(contentType.EqualsLiteral("text/plain")); 1074 ASSERT_TRUE(contentCharset.EqualsLiteral("")); 1075 } 1076 1077 TEST(MimeTypeParsing, subTypeJson) 1078 { 1079 const nsAutoCString val("text/json"); 1080 RefPtr<CMimeType> parsed = CMimeType::Parse(val); 1081 ASSERT_TRUE(parsed); 1082 nsCString subtype; 1083 parsed->GetSubtype(subtype); 1084 ASSERT_TRUE(subtype.EqualsLiteral("json")); 1085 } 1086 1087 // U+002F(/) is not a valid HTTP token code point 1088 // https://mimesniff.spec.whatwg.org/#http-token-code-point 1089 TEST(MimeTypeParsing, invalidSubtype1) 1090 { 1091 const nsAutoCString val("text/json/"); 1092 RefPtr<CMimeType> parsed = CMimeType::Parse(val); 1093 ASSERT_TRUE(!parsed); 1094 } 1095 1096 TEST(MimeTypeParsing, invalidSubtype2) 1097 { 1098 const nsAutoCString val("text/json/bad"); 1099 RefPtr<CMimeType> parsed = CMimeType::Parse(val); 1100 ASSERT_TRUE(!parsed); 1101 } 1102 1103 TEST(MimeTypeParsing, countParameters0) 1104 { 1105 constexpr nsLiteralCString val("text/plain"); 1106 RefPtr<CMimeType> parsed = CMimeType::Parse(val); 1107 ASSERT_TRUE(parsed); 1108 ASSERT_TRUE(parsed->GetParameterCount() == 0); 1109 } 1110 1111 TEST(MimeTypeParsing, countParameters1) 1112 { 1113 constexpr nsLiteralCString val("video/webm; codecs=\"vp09.00.10.08, opus\""); 1114 RefPtr<CMimeType> parsed = CMimeType::Parse(val); 1115 ASSERT_TRUE(parsed); 1116 ASSERT_TRUE(parsed->GetParameterCount() == 1); 1117 } 1118 1119 TEST(MimeTypeParsing, countParameters2) 1120 { 1121 constexpr nsLiteralCString val( 1122 "video/mp4; codecs=\"avc1.64001f\"; profile=high"); 1123 RefPtr<CMimeType> parsed = CMimeType::Parse(val); 1124 ASSERT_TRUE(parsed); 1125 ASSERT_TRUE(parsed->GetParameterCount() == 2); 1126 } 1127 1128 TEST(MimeTypeParsing, countParameters3) 1129 { 1130 constexpr nsLiteralCString val( 1131 "video/mp4; codecs=\"a,b\"; FrameRate=60; BITRATE=100000"); 1132 RefPtr<CMimeType> parsed = CMimeType::Parse(val); 1133 ASSERT_TRUE(parsed); 1134 ASSERT_TRUE(parsed->GetParameterCount() == 3); 1135 }