nsHtml5Tokenizer.h (160149B)
1 /* 2 * Copyright (c) 2005-2007 Henri Sivonen 3 * Copyright (c) 2007-2017 Mozilla Foundation 4 * Portions of comments Copyright 2004-2010 Apple Computer, Inc., Mozilla 5 * Foundation, and Opera Software ASA. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 * DEALINGS IN THE SOFTWARE. 24 */ 25 26 /* 27 * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT. 28 * Please edit Tokenizer.java instead and regenerate. 29 */ 30 31 #ifndef nsHtml5Tokenizer_h 32 #define nsHtml5Tokenizer_h 33 34 #include "jArray.h" 35 #include "nsAHtml5TreeBuilderState.h" 36 #include "nsAtom.h" 37 #include "nsGkAtoms.h" 38 #include "nsHtml5ArrayCopy.h" 39 #include "nsHtml5AtomTable.h" 40 #include "nsHtml5DocumentMode.h" 41 #include "nsHtml5Highlighter.h" 42 #include "nsHtml5Macros.h" 43 #include "nsHtml5NamedCharacters.h" 44 #include "nsHtml5NamedCharactersAccel.h" 45 #include "nsHtml5String.h" 46 #include "nsHtml5TreeBuilder.h" 47 #include "nsIContent.h" 48 #include "nsTraceRefcnt.h" 49 #include "mozilla/htmlaccel/htmlaccelEnabled.h" 50 51 class nsHtml5StreamParser; 52 53 class nsHtml5AttributeName; 54 class nsHtml5ElementName; 55 class nsHtml5TreeBuilder; 56 class nsHtml5UTF16Buffer; 57 class nsHtml5StateSnapshot; 58 class nsHtml5Portability; 59 60 class nsHtml5Tokenizer { 61 private: 62 static const int32_t DATA_AND_RCDATA_MASK = ~1; 63 64 public: 65 static const int32_t DATA = 0; 66 67 static const int32_t RCDATA = 1; 68 69 static const int32_t SCRIPT_DATA = 2; 70 71 static const int32_t RAWTEXT = 3; 72 73 static const int32_t SCRIPT_DATA_ESCAPED = 4; 74 75 static const int32_t ATTRIBUTE_VALUE_DOUBLE_QUOTED = 5; 76 77 static const int32_t ATTRIBUTE_VALUE_SINGLE_QUOTED = 6; 78 79 static const int32_t ATTRIBUTE_VALUE_UNQUOTED = 7; 80 81 static const int32_t PLAINTEXT = 8; 82 83 static const int32_t TAG_OPEN = 9; 84 85 static const int32_t CLOSE_TAG_OPEN = 10; 86 87 static const int32_t TAG_NAME = 11; 88 89 static const int32_t BEFORE_ATTRIBUTE_NAME = 12; 90 91 static const int32_t ATTRIBUTE_NAME = 13; 92 93 static const int32_t AFTER_ATTRIBUTE_NAME = 14; 94 95 static const int32_t BEFORE_ATTRIBUTE_VALUE = 15; 96 97 static const int32_t AFTER_ATTRIBUTE_VALUE_QUOTED = 16; 98 99 static const int32_t BOGUS_COMMENT = 17; 100 101 static const int32_t MARKUP_DECLARATION_OPEN = 18; 102 103 static const int32_t DOCTYPE = 19; 104 105 static const int32_t BEFORE_DOCTYPE_NAME = 20; 106 107 static const int32_t DOCTYPE_NAME = 21; 108 109 static const int32_t AFTER_DOCTYPE_NAME = 22; 110 111 static const int32_t BEFORE_DOCTYPE_PUBLIC_IDENTIFIER = 23; 112 113 static const int32_t DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED = 24; 114 115 static const int32_t DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED = 25; 116 117 static const int32_t AFTER_DOCTYPE_PUBLIC_IDENTIFIER = 26; 118 119 static const int32_t BEFORE_DOCTYPE_SYSTEM_IDENTIFIER = 27; 120 121 static const int32_t DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED = 28; 122 123 static const int32_t DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED = 29; 124 125 static const int32_t AFTER_DOCTYPE_SYSTEM_IDENTIFIER = 30; 126 127 static const int32_t BOGUS_DOCTYPE = 31; 128 129 static const int32_t COMMENT_START = 32; 130 131 static const int32_t COMMENT_START_DASH = 33; 132 133 static const int32_t COMMENT = 34; 134 135 static const int32_t COMMENT_END_DASH = 35; 136 137 static const int32_t COMMENT_END = 36; 138 139 static const int32_t COMMENT_END_BANG = 37; 140 141 static const int32_t NON_DATA_END_TAG_NAME = 38; 142 143 static const int32_t MARKUP_DECLARATION_HYPHEN = 39; 144 145 static const int32_t MARKUP_DECLARATION_OCTYPE = 40; 146 147 static const int32_t DOCTYPE_UBLIC = 41; 148 149 static const int32_t DOCTYPE_YSTEM = 42; 150 151 static const int32_t AFTER_DOCTYPE_PUBLIC_KEYWORD = 43; 152 153 static const int32_t BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS = 44; 154 155 static const int32_t AFTER_DOCTYPE_SYSTEM_KEYWORD = 45; 156 157 static const int32_t CONSUME_CHARACTER_REFERENCE = 46; 158 159 static const int32_t CONSUME_NCR = 47; 160 161 static const int32_t CHARACTER_REFERENCE_TAIL = 48; 162 163 static const int32_t HEX_NCR_LOOP = 49; 164 165 static const int32_t DECIMAL_NRC_LOOP = 50; 166 167 static const int32_t HANDLE_NCR_VALUE = 51; 168 169 static const int32_t HANDLE_NCR_VALUE_RECONSUME = 52; 170 171 static const int32_t CHARACTER_REFERENCE_HILO_LOOKUP = 53; 172 173 static const int32_t SELF_CLOSING_START_TAG = 54; 174 175 static const int32_t CDATA_START = 55; 176 177 static const int32_t CDATA_SECTION = 56; 178 179 static const int32_t CDATA_RSQB = 57; 180 181 static const int32_t CDATA_RSQB_RSQB = 58; 182 183 static const int32_t SCRIPT_DATA_LESS_THAN_SIGN = 59; 184 185 static const int32_t SCRIPT_DATA_ESCAPE_START = 60; 186 187 static const int32_t SCRIPT_DATA_ESCAPE_START_DASH = 61; 188 189 static const int32_t SCRIPT_DATA_ESCAPED_DASH = 62; 190 191 static const int32_t SCRIPT_DATA_ESCAPED_DASH_DASH = 63; 192 193 static const int32_t BOGUS_COMMENT_HYPHEN = 64; 194 195 static const int32_t RAWTEXT_RCDATA_LESS_THAN_SIGN = 65; 196 197 static const int32_t SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN = 66; 198 199 static const int32_t SCRIPT_DATA_DOUBLE_ESCAPE_START = 67; 200 201 static const int32_t SCRIPT_DATA_DOUBLE_ESCAPED = 68; 202 203 static const int32_t SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN = 69; 204 205 static const int32_t SCRIPT_DATA_DOUBLE_ESCAPED_DASH = 70; 206 207 static const int32_t SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH = 71; 208 209 static const int32_t SCRIPT_DATA_DOUBLE_ESCAPE_END = 72; 210 211 static const int32_t PROCESSING_INSTRUCTION = 73; 212 213 static const int32_t PROCESSING_INSTRUCTION_QUESTION_MARK = 74; 214 215 static const int32_t COMMENT_LESSTHAN = 76; 216 217 static const int32_t COMMENT_LESSTHAN_BANG = 77; 218 219 static const int32_t COMMENT_LESSTHAN_BANG_DASH = 78; 220 221 static const int32_t COMMENT_LESSTHAN_BANG_DASH_DASH = 79; 222 223 private: 224 static const int32_t LEAD_OFFSET = (0xD800 - (0x10000 >> 10)); 225 226 static char16_t LT_GT[]; 227 static char16_t LT_SOLIDUS[]; 228 static char16_t RSQB_RSQB[]; 229 static char16_t REPLACEMENT_CHARACTER[]; 230 static char16_t LF[]; 231 static char16_t CDATA_LSQB[]; 232 static char16_t OCTYPE[]; 233 static char16_t UBLIC[]; 234 static char16_t YSTEM[]; 235 static staticJArray<char16_t, int32_t> TITLE_ARR; 236 static staticJArray<char16_t, int32_t> SCRIPT_ARR; 237 static staticJArray<char16_t, int32_t> STYLE_ARR; 238 static staticJArray<char16_t, int32_t> PLAINTEXT_ARR; 239 static staticJArray<char16_t, int32_t> XMP_ARR; 240 static staticJArray<char16_t, int32_t> TEXTAREA_ARR; 241 static staticJArray<char16_t, int32_t> IFRAME_ARR; 242 static staticJArray<char16_t, int32_t> NOEMBED_ARR; 243 static staticJArray<char16_t, int32_t> NOSCRIPT_ARR; 244 static staticJArray<char16_t, int32_t> NOFRAMES_ARR; 245 246 protected: 247 nsHtml5TreeBuilder* tokenHandler; 248 nsHtml5StreamParser* encodingDeclarationHandler; 249 bool lastCR; 250 int32_t stateSave; 251 252 private: 253 int32_t returnStateSave; 254 255 protected: 256 int32_t index; 257 258 private: 259 bool forceQuirks; 260 char16_t additional; 261 int32_t entCol; 262 int32_t firstCharKey; 263 int32_t lo; 264 int32_t hi; 265 int32_t candidate; 266 int32_t charRefBufMark; 267 268 protected: 269 int32_t value; 270 271 private: 272 bool seenDigits; 273 bool suspendAfterCurrentNonTextToken; 274 275 protected: 276 int32_t cstart; 277 278 private: 279 nsHtml5String publicId; 280 nsHtml5String systemId; 281 autoJArray<char16_t, int32_t> strBuf; 282 int32_t strBufLen; 283 autoJArray<char16_t, int32_t> charRefBuf; 284 int32_t charRefBufLen; 285 autoJArray<char16_t, int32_t> bmpChar; 286 autoJArray<char16_t, int32_t> astralChar; 287 288 protected: 289 nsHtml5ElementName* endTagExpectation; 290 291 private: 292 jArray<char16_t, int32_t> endTagExpectationAsArray; 293 294 protected: 295 bool endTag; 296 297 private: 298 bool containsHyphen; 299 nsHtml5ElementName* tagName; 300 nsHtml5ElementName* nonInternedTagName; 301 302 protected: 303 nsHtml5AttributeName* attributeName; 304 305 private: 306 nsHtml5AttributeName* nonInternedAttributeName; 307 RefPtr<nsAtom> doctypeName; 308 nsHtml5String publicIdentifier; 309 nsHtml5String systemIdentifier; 310 nsHtml5HtmlAttributes* attributes; 311 bool newAttributesEachTime; 312 bool shouldSuspend; 313 bool keepBuffer; 314 315 protected: 316 bool confident; 317 318 private: 319 int32_t line; 320 int32_t attributeLine; 321 nsHtml5AtomTable* interner; 322 bool viewingXmlSource; 323 324 public: 325 nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler, bool viewingXmlSource); 326 void setInterner(nsHtml5AtomTable* interner); 327 void initLocation(nsHtml5String newPublicId, nsHtml5String newSystemId); 328 bool isViewingXmlSource(); 329 void setKeepBuffer(bool keepBuffer); 330 bool dropBufferIfLongerThan(int32_t length); 331 void setState(int32_t specialTokenizerState); 332 void setStateAndEndTagExpectation(int32_t specialTokenizerState, 333 nsHtml5ElementName* endTagExpectation); 334 335 private: 336 void endTagExpectationToArray(); 337 338 public: 339 void setLineNumber(int32_t line); 340 inline int32_t getLineNumber() { return line; } 341 342 inline nsHtml5HtmlAttributes* emptyAttributes() { 343 return nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES; 344 } 345 346 private: 347 void appendCharRefBuf(char16_t c); 348 void emitOrAppendCharRefBuf(int32_t returnState); 349 inline void clearStrBufAfterUse() { strBufLen = 0; } 350 351 inline void clearStrBufBeforeUse() { 352 MOZ_ASSERT(!strBufLen, "strBufLen not reset after previous use!"); 353 strBufLen = 0; 354 } 355 356 inline void clearStrBufAfterOneHyphen() { 357 MOZ_ASSERT(strBufLen == 1, "strBufLen length not one!"); 358 MOZ_ASSERT(strBuf[0] == '-', "strBuf does not start with a hyphen!"); 359 strBufLen = 0; 360 } 361 362 inline void appendStrBuf(char16_t c) { 363 if (MOZ_UNLIKELY(strBufLen == strBuf.length)) { 364 EnsureBufferSpaceShouldNeverHappen(1); 365 } 366 strBuf[strBufLen++] = c; 367 } 368 369 protected: 370 inline nsHtml5String strBufToString() { 371 nsHtml5String digitAtom = TryAtomizeForSingleDigit(); 372 if (digitAtom) { 373 return digitAtom; 374 } 375 bool maybeAtomize = false; 376 if (!newAttributesEachTime) { 377 if (attributeName == nsHtml5AttributeName::ATTR_CLASS || 378 attributeName == nsHtml5AttributeName::ATTR_TYPE) { 379 maybeAtomize = true; 380 } 381 } 382 nsHtml5String str = nsHtml5Portability::newStringFromBuffer( 383 strBuf, 0, strBufLen, tokenHandler, maybeAtomize); 384 clearStrBufAfterUse(); 385 return str; 386 } 387 388 private: 389 inline void strBufToDoctypeName() { 390 doctypeName = 391 nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen, interner); 392 clearStrBufAfterUse(); 393 } 394 395 inline void emitStrBuf() { 396 if (strBufLen > 0) { 397 tokenHandler->characters(strBuf, 0, strBufLen); 398 clearStrBufAfterUse(); 399 } 400 } 401 402 inline void appendSecondHyphenToBogusComment() { appendStrBuf('-'); } 403 404 inline void adjustDoubleHyphenAndAppendToStrBufAndErr( 405 char16_t c, bool reportedConsecutiveHyphens) { 406 appendStrBuf(c); 407 } 408 409 inline void appendStrBuf(char16_t* buffer, int32_t offset, int32_t length) { 410 int32_t newLen = strBufLen + length; 411 if (MOZ_UNLIKELY(strBuf.length < newLen)) { 412 EnsureBufferSpaceShouldNeverHappen(length); 413 } 414 nsHtml5ArrayCopy::arraycopy(buffer, offset, strBuf, strBufLen, length); 415 strBufLen = newLen; 416 } 417 418 inline void appendCharRefBufToStrBuf() { 419 appendStrBuf(charRefBuf, 0, charRefBufLen); 420 charRefBufLen = 0; 421 } 422 423 void emitComment(int32_t provisionalHyphens, int32_t pos); 424 425 protected: 426 void flushChars(char16_t* buf, int32_t pos); 427 428 private: 429 void strBufToElementNameString(); 430 int32_t emitCurrentTagToken(bool selfClosing, int32_t pos); 431 void attributeNameComplete(); 432 void addAttributeWithoutValue(); 433 void addAttributeWithValue(); 434 435 public: 436 void start(); 437 bool tokenizeBuffer(nsHtml5UTF16Buffer* buffer); 438 439 private: 440 template <class P> 441 inline int32_t stateLoop(int32_t state, char16_t c, int32_t pos, 442 char16_t* buf, bool reconsume, int32_t returnState, 443 int32_t endPos) { 444 bool reportedConsecutiveHyphens = false; 445 stateloop: 446 for (;;) { 447 switch (state) { 448 case DATA: { 449 for (;;) { 450 if (reconsume) { 451 reconsume = false; 452 } else { 453 ++pos; 454 pos += P::accelerateAdvancementData(this, buf, pos, endPos); 455 if (pos == endPos) { 456 NS_HTML5_BREAK(stateloop); 457 } 458 c = P::checkChar(this, buf, pos); 459 } 460 switch (c) { 461 case '&': { 462 flushChars(buf, pos); 463 MOZ_ASSERT(!charRefBufLen, 464 "charRefBufLen not reset after previous use!"); 465 appendCharRefBuf(c); 466 setAdditionalAndRememberAmpersandLocation('\0'); 467 returnState = state; 468 state = 469 P::transition(mViewSource.get(), 470 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE, 471 reconsume, pos); 472 NS_HTML5_CONTINUE(stateloop); 473 } 474 case '<': { 475 flushChars(buf, pos); 476 state = 477 P::transition(mViewSource.get(), nsHtml5Tokenizer::TAG_OPEN, 478 reconsume, pos); 479 NS_HTML5_BREAK(dataloop); 480 } 481 case '\0': { 482 maybeEmitReplacementCharacter(buf, pos); 483 continue; 484 } 485 case '\r': { 486 emitCarriageReturn<P>(buf, pos); 487 NS_HTML5_BREAK(stateloop); 488 } 489 case '\n': { 490 P::silentLineFeed(this); 491 [[fallthrough]]; 492 } 493 default: { 494 continue; 495 } 496 } 497 } 498 dataloop_end:; 499 [[fallthrough]]; 500 } 501 case TAG_OPEN: { 502 for (;;) { 503 if (++pos == endPos) { 504 NS_HTML5_BREAK(stateloop); 505 } 506 c = P::checkChar(this, buf, pos); 507 if (c >= 'A' && c <= 'Z') { 508 endTag = false; 509 clearStrBufBeforeUse(); 510 appendStrBuf((char16_t)(c + 0x20)); 511 containsHyphen = false; 512 state = P::transition(mViewSource.get(), 513 nsHtml5Tokenizer::TAG_NAME, reconsume, pos); 514 NS_HTML5_BREAK(tagopenloop); 515 } else if (c >= 'a' && c <= 'z') { 516 endTag = false; 517 clearStrBufBeforeUse(); 518 appendStrBuf(c); 519 containsHyphen = false; 520 state = P::transition(mViewSource.get(), 521 nsHtml5Tokenizer::TAG_NAME, reconsume, pos); 522 NS_HTML5_BREAK(tagopenloop); 523 } 524 switch (c) { 525 case '!': { 526 state = P::transition(mViewSource.get(), 527 nsHtml5Tokenizer::MARKUP_DECLARATION_OPEN, 528 reconsume, pos); 529 NS_HTML5_CONTINUE(stateloop); 530 } 531 case '/': { 532 state = P::transition(mViewSource.get(), 533 nsHtml5Tokenizer::CLOSE_TAG_OPEN, 534 reconsume, pos); 535 NS_HTML5_CONTINUE(stateloop); 536 } 537 case '\?': { 538 if (viewingXmlSource) { 539 state = P::transition( 540 mViewSource.get(), 541 nsHtml5Tokenizer::PROCESSING_INSTRUCTION, reconsume, pos); 542 NS_HTML5_CONTINUE(stateloop); 543 } 544 if (P::reportErrors) { 545 errProcessingInstruction(); 546 } 547 clearStrBufBeforeUse(); 548 appendStrBuf(c); 549 state = P::transition(mViewSource.get(), 550 nsHtml5Tokenizer::BOGUS_COMMENT, 551 reconsume, pos); 552 NS_HTML5_CONTINUE(stateloop); 553 } 554 case '>': { 555 if (P::reportErrors) { 556 errLtGt(); 557 } 558 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 2); 559 cstart = pos + 1; 560 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 561 reconsume, pos); 562 NS_HTML5_CONTINUE(stateloop); 563 } 564 default: { 565 if (P::reportErrors) { 566 errBadCharAfterLt(c); 567 } 568 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1); 569 cstart = pos; 570 reconsume = true; 571 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 572 reconsume, pos); 573 NS_HTML5_CONTINUE(stateloop); 574 } 575 } 576 } 577 tagopenloop_end:; 578 [[fallthrough]]; 579 } 580 case TAG_NAME: { 581 for (;;) { 582 if (++pos == endPos) { 583 NS_HTML5_BREAK(stateloop); 584 } 585 c = P::checkChar(this, buf, pos); 586 switch (c) { 587 case '\r': { 588 P::silentCarriageReturn(this); 589 strBufToElementNameString(); 590 state = P::transition(mViewSource.get(), 591 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME, 592 reconsume, pos); 593 NS_HTML5_BREAK(stateloop); 594 } 595 case '\n': { 596 P::silentLineFeed(this); 597 [[fallthrough]]; 598 } 599 case ' ': 600 case '\t': 601 case '\f': { 602 strBufToElementNameString(); 603 state = P::transition(mViewSource.get(), 604 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME, 605 reconsume, pos); 606 NS_HTML5_BREAK(tagnameloop); 607 } 608 case '/': { 609 strBufToElementNameString(); 610 state = P::transition(mViewSource.get(), 611 nsHtml5Tokenizer::SELF_CLOSING_START_TAG, 612 reconsume, pos); 613 NS_HTML5_CONTINUE(stateloop); 614 } 615 case '>': { 616 strBufToElementNameString(); 617 state = P::transition(mViewSource.get(), 618 emitCurrentTagToken(false, pos), 619 reconsume, pos); 620 if (shouldSuspend) { 621 NS_HTML5_BREAK(stateloop); 622 } 623 NS_HTML5_CONTINUE(stateloop); 624 } 625 case '\0': { 626 c = 0xfffd; 627 [[fallthrough]]; 628 } 629 default: { 630 if (c >= 'A' && c <= 'Z') { 631 c += 0x20; 632 } else if (c == '-') { 633 containsHyphen = true; 634 } 635 appendStrBuf(c); 636 continue; 637 } 638 } 639 } 640 tagnameloop_end:; 641 [[fallthrough]]; 642 } 643 case BEFORE_ATTRIBUTE_NAME: { 644 for (;;) { 645 if (reconsume) { 646 reconsume = false; 647 } else { 648 if (++pos == endPos) { 649 NS_HTML5_BREAK(stateloop); 650 } 651 c = P::checkChar(this, buf, pos); 652 } 653 switch (c) { 654 case '\r': { 655 P::silentCarriageReturn(this); 656 NS_HTML5_BREAK(stateloop); 657 } 658 case '\n': { 659 P::silentLineFeed(this); 660 [[fallthrough]]; 661 } 662 case ' ': 663 case '\t': 664 case '\f': { 665 continue; 666 } 667 case '/': { 668 state = P::transition(mViewSource.get(), 669 nsHtml5Tokenizer::SELF_CLOSING_START_TAG, 670 reconsume, pos); 671 NS_HTML5_CONTINUE(stateloop); 672 } 673 case '>': { 674 state = P::transition(mViewSource.get(), 675 emitCurrentTagToken(false, pos), 676 reconsume, pos); 677 if (shouldSuspend) { 678 NS_HTML5_BREAK(stateloop); 679 } 680 NS_HTML5_CONTINUE(stateloop); 681 } 682 case '\0': { 683 c = 0xfffd; 684 [[fallthrough]]; 685 } 686 case '\"': 687 case '\'': 688 case '<': 689 case '=': { 690 if (P::reportErrors) { 691 errBadCharBeforeAttributeNameOrNull(c); 692 } 693 [[fallthrough]]; 694 } 695 default: { 696 if (c >= 'A' && c <= 'Z') { 697 c += 0x20; 698 } 699 attributeLine = line; 700 clearStrBufBeforeUse(); 701 appendStrBuf(c); 702 state = P::transition(mViewSource.get(), 703 nsHtml5Tokenizer::ATTRIBUTE_NAME, 704 reconsume, pos); 705 NS_HTML5_BREAK(beforeattributenameloop); 706 } 707 } 708 } 709 beforeattributenameloop_end:; 710 [[fallthrough]]; 711 } 712 case ATTRIBUTE_NAME: { 713 for (;;) { 714 if (++pos == endPos) { 715 NS_HTML5_BREAK(stateloop); 716 } 717 c = P::checkChar(this, buf, pos); 718 switch (c) { 719 case '\r': { 720 P::silentCarriageReturn(this); 721 attributeNameComplete(); 722 state = P::transition(mViewSource.get(), 723 nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME, 724 reconsume, pos); 725 NS_HTML5_BREAK(stateloop); 726 } 727 case '\n': { 728 P::silentLineFeed(this); 729 [[fallthrough]]; 730 } 731 case ' ': 732 case '\t': 733 case '\f': { 734 attributeNameComplete(); 735 state = P::transition(mViewSource.get(), 736 nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME, 737 reconsume, pos); 738 NS_HTML5_CONTINUE(stateloop); 739 } 740 case '/': { 741 attributeNameComplete(); 742 addAttributeWithoutValue(); 743 state = P::transition(mViewSource.get(), 744 nsHtml5Tokenizer::SELF_CLOSING_START_TAG, 745 reconsume, pos); 746 NS_HTML5_CONTINUE(stateloop); 747 } 748 case '=': { 749 attributeNameComplete(); 750 state = P::transition(mViewSource.get(), 751 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE, 752 reconsume, pos); 753 NS_HTML5_BREAK(attributenameloop); 754 } 755 case '>': { 756 attributeNameComplete(); 757 addAttributeWithoutValue(); 758 state = P::transition(mViewSource.get(), 759 emitCurrentTagToken(false, pos), 760 reconsume, pos); 761 if (shouldSuspend) { 762 NS_HTML5_BREAK(stateloop); 763 } 764 NS_HTML5_CONTINUE(stateloop); 765 } 766 case '\0': { 767 c = 0xfffd; 768 [[fallthrough]]; 769 } 770 case '\"': 771 case '\'': 772 case '<': { 773 if (P::reportErrors) { 774 errQuoteOrLtInAttributeNameOrNull(c); 775 } 776 [[fallthrough]]; 777 } 778 default: { 779 if (c >= 'A' && c <= 'Z') { 780 c += 0x20; 781 } 782 appendStrBuf(c); 783 continue; 784 } 785 } 786 } 787 attributenameloop_end:; 788 [[fallthrough]]; 789 } 790 case BEFORE_ATTRIBUTE_VALUE: { 791 for (;;) { 792 if (++pos == endPos) { 793 NS_HTML5_BREAK(stateloop); 794 } 795 c = P::checkChar(this, buf, pos); 796 switch (c) { 797 case '\r': { 798 P::silentCarriageReturn(this); 799 NS_HTML5_BREAK(stateloop); 800 } 801 case '\n': { 802 P::silentLineFeed(this); 803 [[fallthrough]]; 804 } 805 case ' ': 806 case '\t': 807 case '\f': { 808 continue; 809 } 810 case '\"': { 811 attributeLine = line; 812 clearStrBufBeforeUse(); 813 state = P::transition( 814 mViewSource.get(), 815 nsHtml5Tokenizer::ATTRIBUTE_VALUE_DOUBLE_QUOTED, reconsume, 816 pos); 817 NS_HTML5_BREAK(beforeattributevalueloop); 818 } 819 case '&': { 820 attributeLine = line; 821 clearStrBufBeforeUse(); 822 reconsume = true; 823 state = P::transition( 824 mViewSource.get(), 825 nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED, reconsume, pos); 826 827 NS_HTML5_CONTINUE(stateloop); 828 } 829 case '\'': { 830 attributeLine = line; 831 clearStrBufBeforeUse(); 832 state = P::transition( 833 mViewSource.get(), 834 nsHtml5Tokenizer::ATTRIBUTE_VALUE_SINGLE_QUOTED, reconsume, 835 pos); 836 NS_HTML5_CONTINUE(stateloop); 837 } 838 case '>': { 839 if (P::reportErrors) { 840 errAttributeValueMissing(); 841 } 842 addAttributeWithoutValue(); 843 state = P::transition(mViewSource.get(), 844 emitCurrentTagToken(false, pos), 845 reconsume, pos); 846 if (shouldSuspend) { 847 NS_HTML5_BREAK(stateloop); 848 } 849 NS_HTML5_CONTINUE(stateloop); 850 } 851 case '\0': { 852 c = 0xfffd; 853 [[fallthrough]]; 854 } 855 case '<': 856 case '=': 857 case '`': { 858 if (P::reportErrors) { 859 errLtOrEqualsOrGraveInUnquotedAttributeOrNull(c); 860 } 861 [[fallthrough]]; 862 } 863 default: { 864 attributeLine = line; 865 clearStrBufBeforeUse(); 866 appendStrBuf(c); 867 state = P::transition( 868 mViewSource.get(), 869 nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED, reconsume, pos); 870 871 NS_HTML5_CONTINUE(stateloop); 872 } 873 } 874 } 875 beforeattributevalueloop_end:; 876 [[fallthrough]]; 877 } 878 case ATTRIBUTE_VALUE_DOUBLE_QUOTED: { 879 for (;;) { 880 if (reconsume) { 881 reconsume = false; 882 } else { 883 ++pos; 884 pos += P::accelerateAdvancementAttributeValueDoubleQuoted( 885 this, buf, pos, endPos); 886 if (pos == endPos) { 887 NS_HTML5_BREAK(stateloop); 888 } 889 c = P::checkChar(this, buf, pos); 890 } 891 switch (c) { 892 case '\"': { 893 addAttributeWithValue(); 894 state = P::transition( 895 mViewSource.get(), 896 nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED, reconsume, 897 pos); 898 NS_HTML5_BREAK(attributevaluedoublequotedloop); 899 } 900 case '&': { 901 MOZ_ASSERT(!charRefBufLen, 902 "charRefBufLen not reset after previous use!"); 903 appendCharRefBuf(c); 904 setAdditionalAndRememberAmpersandLocation('\"'); 905 returnState = state; 906 state = 907 P::transition(mViewSource.get(), 908 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE, 909 reconsume, pos); 910 NS_HTML5_CONTINUE(stateloop); 911 } 912 case '\r': { 913 appendStrBufCarriageReturn<P>(); 914 NS_HTML5_BREAK(stateloop); 915 } 916 case '\n': { 917 appendStrBufLineFeed<P>(); 918 continue; 919 } 920 case '\0': { 921 c = 0xfffd; 922 [[fallthrough]]; 923 } 924 default: { 925 appendStrBuf(c); 926 continue; 927 } 928 } 929 } 930 attributevaluedoublequotedloop_end:; 931 [[fallthrough]]; 932 } 933 case AFTER_ATTRIBUTE_VALUE_QUOTED: { 934 for (;;) { 935 if (++pos == endPos) { 936 NS_HTML5_BREAK(stateloop); 937 } 938 c = P::checkChar(this, buf, pos); 939 switch (c) { 940 case '\r': { 941 P::silentCarriageReturn(this); 942 state = P::transition(mViewSource.get(), 943 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME, 944 reconsume, pos); 945 NS_HTML5_BREAK(stateloop); 946 } 947 case '\n': { 948 P::silentLineFeed(this); 949 [[fallthrough]]; 950 } 951 case ' ': 952 case '\t': 953 case '\f': { 954 state = P::transition(mViewSource.get(), 955 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME, 956 reconsume, pos); 957 NS_HTML5_CONTINUE(stateloop); 958 } 959 case '/': { 960 state = P::transition(mViewSource.get(), 961 nsHtml5Tokenizer::SELF_CLOSING_START_TAG, 962 reconsume, pos); 963 NS_HTML5_BREAK(afterattributevaluequotedloop); 964 } 965 case '>': { 966 state = P::transition(mViewSource.get(), 967 emitCurrentTagToken(false, pos), 968 reconsume, pos); 969 if (shouldSuspend) { 970 NS_HTML5_BREAK(stateloop); 971 } 972 NS_HTML5_CONTINUE(stateloop); 973 } 974 default: { 975 if (P::reportErrors) { 976 errNoSpaceBetweenAttributes(); 977 } 978 reconsume = true; 979 state = P::transition(mViewSource.get(), 980 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME, 981 reconsume, pos); 982 NS_HTML5_CONTINUE(stateloop); 983 } 984 } 985 } 986 afterattributevaluequotedloop_end:; 987 [[fallthrough]]; 988 } 989 case SELF_CLOSING_START_TAG: { 990 if (++pos == endPos) { 991 NS_HTML5_BREAK(stateloop); 992 } 993 c = P::checkChar(this, buf, pos); 994 switch (c) { 995 case '>': { 996 state = 997 P::transition(mViewSource.get(), 998 emitCurrentTagToken(true, pos), reconsume, pos); 999 if (shouldSuspend) { 1000 NS_HTML5_BREAK(stateloop); 1001 } 1002 NS_HTML5_CONTINUE(stateloop); 1003 } 1004 default: { 1005 if (P::reportErrors) { 1006 errSlashNotFollowedByGt(); 1007 } 1008 reconsume = true; 1009 state = P::transition(mViewSource.get(), 1010 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME, 1011 reconsume, pos); 1012 NS_HTML5_CONTINUE(stateloop); 1013 } 1014 } 1015 } 1016 case ATTRIBUTE_VALUE_UNQUOTED: { 1017 for (;;) { 1018 if (reconsume) { 1019 reconsume = false; 1020 } else { 1021 if (++pos == endPos) { 1022 NS_HTML5_BREAK(stateloop); 1023 } 1024 c = P::checkChar(this, buf, pos); 1025 } 1026 switch (c) { 1027 case '\r': { 1028 P::silentCarriageReturn(this); 1029 addAttributeWithValue(); 1030 state = P::transition(mViewSource.get(), 1031 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME, 1032 reconsume, pos); 1033 NS_HTML5_BREAK(stateloop); 1034 } 1035 case '\n': { 1036 P::silentLineFeed(this); 1037 [[fallthrough]]; 1038 } 1039 case ' ': 1040 case '\t': 1041 case '\f': { 1042 addAttributeWithValue(); 1043 state = P::transition(mViewSource.get(), 1044 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME, 1045 reconsume, pos); 1046 NS_HTML5_CONTINUE(stateloop); 1047 } 1048 case '&': { 1049 MOZ_ASSERT(!charRefBufLen, 1050 "charRefBufLen not reset after previous use!"); 1051 appendCharRefBuf(c); 1052 setAdditionalAndRememberAmpersandLocation('>'); 1053 returnState = state; 1054 state = 1055 P::transition(mViewSource.get(), 1056 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE, 1057 reconsume, pos); 1058 NS_HTML5_CONTINUE(stateloop); 1059 } 1060 case '>': { 1061 addAttributeWithValue(); 1062 state = P::transition(mViewSource.get(), 1063 emitCurrentTagToken(false, pos), 1064 reconsume, pos); 1065 if (shouldSuspend) { 1066 NS_HTML5_BREAK(stateloop); 1067 } 1068 NS_HTML5_CONTINUE(stateloop); 1069 } 1070 case '\0': { 1071 c = 0xfffd; 1072 [[fallthrough]]; 1073 } 1074 case '<': 1075 case '\"': 1076 case '\'': 1077 case '=': 1078 case '`': { 1079 if (P::reportErrors) { 1080 errUnquotedAttributeValOrNull(c); 1081 } 1082 [[fallthrough]]; 1083 } 1084 default: { 1085 appendStrBuf(c); 1086 continue; 1087 } 1088 } 1089 } 1090 } 1091 case AFTER_ATTRIBUTE_NAME: { 1092 for (;;) { 1093 if (++pos == endPos) { 1094 NS_HTML5_BREAK(stateloop); 1095 } 1096 c = P::checkChar(this, buf, pos); 1097 switch (c) { 1098 case '\r': { 1099 P::silentCarriageReturn(this); 1100 NS_HTML5_BREAK(stateloop); 1101 } 1102 case '\n': { 1103 P::silentLineFeed(this); 1104 [[fallthrough]]; 1105 } 1106 case ' ': 1107 case '\t': 1108 case '\f': { 1109 continue; 1110 } 1111 case '/': { 1112 addAttributeWithoutValue(); 1113 state = P::transition(mViewSource.get(), 1114 nsHtml5Tokenizer::SELF_CLOSING_START_TAG, 1115 reconsume, pos); 1116 NS_HTML5_CONTINUE(stateloop); 1117 } 1118 case '=': { 1119 state = P::transition(mViewSource.get(), 1120 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE, 1121 reconsume, pos); 1122 NS_HTML5_CONTINUE(stateloop); 1123 } 1124 case '>': { 1125 addAttributeWithoutValue(); 1126 state = P::transition(mViewSource.get(), 1127 emitCurrentTagToken(false, pos), 1128 reconsume, pos); 1129 if (shouldSuspend) { 1130 NS_HTML5_BREAK(stateloop); 1131 } 1132 NS_HTML5_CONTINUE(stateloop); 1133 } 1134 case '\0': { 1135 c = 0xfffd; 1136 [[fallthrough]]; 1137 } 1138 case '\"': 1139 case '\'': 1140 case '<': { 1141 if (P::reportErrors) { 1142 errQuoteOrLtInAttributeNameOrNull(c); 1143 } 1144 [[fallthrough]]; 1145 } 1146 default: { 1147 addAttributeWithoutValue(); 1148 if (c >= 'A' && c <= 'Z') { 1149 c += 0x20; 1150 } 1151 clearStrBufBeforeUse(); 1152 appendStrBuf(c); 1153 state = P::transition(mViewSource.get(), 1154 nsHtml5Tokenizer::ATTRIBUTE_NAME, 1155 reconsume, pos); 1156 NS_HTML5_CONTINUE(stateloop); 1157 } 1158 } 1159 } 1160 } 1161 case MARKUP_DECLARATION_OPEN: { 1162 for (;;) { 1163 if (++pos == endPos) { 1164 NS_HTML5_BREAK(stateloop); 1165 } 1166 c = P::checkChar(this, buf, pos); 1167 switch (c) { 1168 case '-': { 1169 clearStrBufBeforeUse(); 1170 appendStrBuf(c); 1171 state = 1172 P::transition(mViewSource.get(), 1173 nsHtml5Tokenizer::MARKUP_DECLARATION_HYPHEN, 1174 reconsume, pos); 1175 NS_HTML5_BREAK(markupdeclarationopenloop); 1176 } 1177 case 'd': 1178 case 'D': { 1179 clearStrBufBeforeUse(); 1180 appendStrBuf(c); 1181 index = 0; 1182 state = 1183 P::transition(mViewSource.get(), 1184 nsHtml5Tokenizer::MARKUP_DECLARATION_OCTYPE, 1185 reconsume, pos); 1186 NS_HTML5_CONTINUE(stateloop); 1187 } 1188 case '[': { 1189 if (tokenHandler->cdataSectionAllowed()) { 1190 clearStrBufBeforeUse(); 1191 appendStrBuf(c); 1192 index = 0; 1193 state = P::transition(mViewSource.get(), 1194 nsHtml5Tokenizer::CDATA_START, 1195 reconsume, pos); 1196 NS_HTML5_CONTINUE(stateloop); 1197 } 1198 [[fallthrough]]; 1199 } 1200 default: { 1201 if (P::reportErrors) { 1202 errBogusComment(); 1203 } 1204 clearStrBufBeforeUse(); 1205 reconsume = true; 1206 state = P::transition(mViewSource.get(), 1207 nsHtml5Tokenizer::BOGUS_COMMENT, 1208 reconsume, pos); 1209 NS_HTML5_CONTINUE(stateloop); 1210 } 1211 } 1212 } 1213 markupdeclarationopenloop_end:; 1214 [[fallthrough]]; 1215 } 1216 case MARKUP_DECLARATION_HYPHEN: { 1217 for (;;) { 1218 if (++pos == endPos) { 1219 NS_HTML5_BREAK(stateloop); 1220 } 1221 c = P::checkChar(this, buf, pos); 1222 switch (c) { 1223 case '-': { 1224 clearStrBufAfterOneHyphen(); 1225 state = P::transition(mViewSource.get(), 1226 nsHtml5Tokenizer::COMMENT_START, 1227 reconsume, pos); 1228 NS_HTML5_BREAK(markupdeclarationhyphenloop); 1229 } 1230 default: { 1231 if (P::reportErrors) { 1232 errBogusComment(); 1233 } 1234 reconsume = true; 1235 state = P::transition(mViewSource.get(), 1236 nsHtml5Tokenizer::BOGUS_COMMENT, 1237 reconsume, pos); 1238 NS_HTML5_CONTINUE(stateloop); 1239 } 1240 } 1241 } 1242 markupdeclarationhyphenloop_end:; 1243 [[fallthrough]]; 1244 } 1245 case COMMENT_START: { 1246 reportedConsecutiveHyphens = false; 1247 for (;;) { 1248 if (++pos == endPos) { 1249 NS_HTML5_BREAK(stateloop); 1250 } 1251 c = P::checkChar(this, buf, pos); 1252 switch (c) { 1253 case '-': { 1254 appendStrBuf(c); 1255 state = P::transition(mViewSource.get(), 1256 nsHtml5Tokenizer::COMMENT_START_DASH, 1257 reconsume, pos); 1258 NS_HTML5_CONTINUE(stateloop); 1259 } 1260 case '>': { 1261 if (P::reportErrors) { 1262 errPrematureEndOfComment(); 1263 } 1264 emitComment(0, pos); 1265 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 1266 reconsume, pos); 1267 if (shouldSuspend) { 1268 NS_HTML5_BREAK(stateloop); 1269 } 1270 NS_HTML5_CONTINUE(stateloop); 1271 } 1272 case '<': { 1273 appendStrBuf(c); 1274 state = P::transition(mViewSource.get(), 1275 nsHtml5Tokenizer::COMMENT_LESSTHAN, 1276 reconsume, pos); 1277 NS_HTML5_CONTINUE(stateloop); 1278 } 1279 case '\r': { 1280 appendStrBufCarriageReturn<P>(); 1281 state = 1282 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1283 reconsume, pos); 1284 NS_HTML5_BREAK(stateloop); 1285 } 1286 case '\n': { 1287 appendStrBufLineFeed<P>(); 1288 state = 1289 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1290 reconsume, pos); 1291 NS_HTML5_BREAK(commentstartloop); 1292 } 1293 case '\0': { 1294 c = 0xfffd; 1295 [[fallthrough]]; 1296 } 1297 default: { 1298 appendStrBuf(c); 1299 state = 1300 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1301 reconsume, pos); 1302 NS_HTML5_BREAK(commentstartloop); 1303 } 1304 } 1305 } 1306 commentstartloop_end:; 1307 [[fallthrough]]; 1308 } 1309 case COMMENT: { 1310 for (;;) { 1311 ++pos; 1312 pos += P::accelerateAdvancementComment(this, buf, pos, endPos); 1313 if (pos == endPos) { 1314 NS_HTML5_BREAK(stateloop); 1315 } 1316 c = P::checkChar(this, buf, pos); 1317 switch (c) { 1318 case '-': { 1319 appendStrBuf(c); 1320 state = P::transition(mViewSource.get(), 1321 nsHtml5Tokenizer::COMMENT_END_DASH, 1322 reconsume, pos); 1323 NS_HTML5_BREAK(commentloop); 1324 } 1325 case '<': { 1326 appendStrBuf(c); 1327 state = P::transition(mViewSource.get(), 1328 nsHtml5Tokenizer::COMMENT_LESSTHAN, 1329 reconsume, pos); 1330 NS_HTML5_CONTINUE(stateloop); 1331 } 1332 case '\r': { 1333 appendStrBufCarriageReturn<P>(); 1334 NS_HTML5_BREAK(stateloop); 1335 } 1336 case '\n': { 1337 appendStrBufLineFeed<P>(); 1338 continue; 1339 } 1340 case '\0': { 1341 c = 0xfffd; 1342 [[fallthrough]]; 1343 } 1344 default: { 1345 appendStrBuf(c); 1346 continue; 1347 } 1348 } 1349 } 1350 commentloop_end:; 1351 [[fallthrough]]; 1352 } 1353 case COMMENT_END_DASH: { 1354 for (;;) { 1355 if (++pos == endPos) { 1356 NS_HTML5_BREAK(stateloop); 1357 } 1358 c = P::checkChar(this, buf, pos); 1359 switch (c) { 1360 case '-': { 1361 appendStrBuf(c); 1362 state = P::transition(mViewSource.get(), 1363 nsHtml5Tokenizer::COMMENT_END, reconsume, 1364 pos); 1365 NS_HTML5_BREAK(commentenddashloop); 1366 } 1367 case '<': { 1368 appendStrBuf(c); 1369 state = P::transition(mViewSource.get(), 1370 nsHtml5Tokenizer::COMMENT_LESSTHAN, 1371 reconsume, pos); 1372 NS_HTML5_CONTINUE(stateloop); 1373 } 1374 case '\r': { 1375 appendStrBufCarriageReturn<P>(); 1376 state = 1377 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1378 reconsume, pos); 1379 NS_HTML5_BREAK(stateloop); 1380 } 1381 case '\n': { 1382 appendStrBufLineFeed<P>(); 1383 state = 1384 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1385 reconsume, pos); 1386 NS_HTML5_CONTINUE(stateloop); 1387 } 1388 case '\0': { 1389 c = 0xfffd; 1390 [[fallthrough]]; 1391 } 1392 default: { 1393 appendStrBuf(c); 1394 state = 1395 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1396 reconsume, pos); 1397 NS_HTML5_CONTINUE(stateloop); 1398 } 1399 } 1400 } 1401 commentenddashloop_end:; 1402 [[fallthrough]]; 1403 } 1404 case COMMENT_END: { 1405 for (;;) { 1406 if (++pos == endPos) { 1407 NS_HTML5_BREAK(stateloop); 1408 } 1409 c = P::checkChar(this, buf, pos); 1410 switch (c) { 1411 case '>': { 1412 emitComment(2, pos); 1413 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 1414 reconsume, pos); 1415 if (shouldSuspend) { 1416 NS_HTML5_BREAK(stateloop); 1417 } 1418 NS_HTML5_CONTINUE(stateloop); 1419 } 1420 case '-': { 1421 adjustDoubleHyphenAndAppendToStrBufAndErr( 1422 c, reportedConsecutiveHyphens); 1423 reportedConsecutiveHyphens = true; 1424 continue; 1425 } 1426 case '<': { 1427 appendStrBuf(c); 1428 state = P::transition(mViewSource.get(), 1429 nsHtml5Tokenizer::COMMENT_LESSTHAN, 1430 reconsume, pos); 1431 NS_HTML5_CONTINUE(stateloop); 1432 } 1433 case '\r': { 1434 adjustDoubleHyphenAndAppendToStrBufCarriageReturn<P>(); 1435 state = 1436 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1437 reconsume, pos); 1438 NS_HTML5_BREAK(stateloop); 1439 } 1440 case '\n': { 1441 adjustDoubleHyphenAndAppendToStrBufLineFeed<P>(); 1442 state = 1443 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1444 reconsume, pos); 1445 NS_HTML5_CONTINUE(stateloop); 1446 } 1447 case '!': { 1448 appendStrBuf(c); 1449 state = P::transition(mViewSource.get(), 1450 nsHtml5Tokenizer::COMMENT_END_BANG, 1451 reconsume, pos); 1452 NS_HTML5_BREAK(commentendloop); 1453 } 1454 case '\0': { 1455 c = 0xfffd; 1456 [[fallthrough]]; 1457 } 1458 default: { 1459 adjustDoubleHyphenAndAppendToStrBufAndErr( 1460 c, reportedConsecutiveHyphens); 1461 reportedConsecutiveHyphens = true; 1462 state = 1463 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1464 reconsume, pos); 1465 NS_HTML5_CONTINUE(stateloop); 1466 } 1467 } 1468 } 1469 commentendloop_end:; 1470 [[fallthrough]]; 1471 } 1472 case COMMENT_END_BANG: { 1473 for (;;) { 1474 if (++pos == endPos) { 1475 NS_HTML5_BREAK(stateloop); 1476 } 1477 c = P::checkChar(this, buf, pos); 1478 switch (c) { 1479 case '>': { 1480 emitComment(3, pos); 1481 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 1482 reconsume, pos); 1483 if (shouldSuspend) { 1484 NS_HTML5_BREAK(stateloop); 1485 } 1486 NS_HTML5_CONTINUE(stateloop); 1487 } 1488 case '-': { 1489 appendStrBuf(c); 1490 state = P::transition(mViewSource.get(), 1491 nsHtml5Tokenizer::COMMENT_END_DASH, 1492 reconsume, pos); 1493 NS_HTML5_CONTINUE(stateloop); 1494 } 1495 case '\r': { 1496 appendStrBufCarriageReturn<P>(); 1497 state = 1498 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1499 reconsume, pos); 1500 NS_HTML5_BREAK(stateloop); 1501 } 1502 case '\n': { 1503 appendStrBufLineFeed<P>(); 1504 state = 1505 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1506 reconsume, pos); 1507 NS_HTML5_CONTINUE(stateloop); 1508 } 1509 case '\0': { 1510 c = 0xfffd; 1511 [[fallthrough]]; 1512 } 1513 default: { 1514 appendStrBuf(c); 1515 state = 1516 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1517 reconsume, pos); 1518 NS_HTML5_CONTINUE(stateloop); 1519 } 1520 } 1521 } 1522 } 1523 case COMMENT_LESSTHAN: { 1524 for (;;) { 1525 if (++pos == endPos) { 1526 NS_HTML5_BREAK(stateloop); 1527 } 1528 c = P::checkChar(this, buf, pos); 1529 switch (c) { 1530 case '!': { 1531 appendStrBuf(c); 1532 state = P::transition(mViewSource.get(), 1533 nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG, 1534 reconsume, pos); 1535 NS_HTML5_BREAK(commentlessthanloop); 1536 } 1537 case '<': { 1538 appendStrBuf(c); 1539 continue; 1540 } 1541 case '-': { 1542 appendStrBuf(c); 1543 state = P::transition(mViewSource.get(), 1544 nsHtml5Tokenizer::COMMENT_END_DASH, 1545 reconsume, pos); 1546 NS_HTML5_CONTINUE(stateloop); 1547 } 1548 case '\r': { 1549 appendStrBufCarriageReturn<P>(); 1550 state = 1551 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1552 reconsume, pos); 1553 NS_HTML5_BREAK(stateloop); 1554 } 1555 case '\n': { 1556 appendStrBufLineFeed<P>(); 1557 state = 1558 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1559 reconsume, pos); 1560 NS_HTML5_CONTINUE(stateloop); 1561 } 1562 case '\0': { 1563 c = 0xfffd; 1564 [[fallthrough]]; 1565 } 1566 default: { 1567 appendStrBuf(c); 1568 state = 1569 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1570 reconsume, pos); 1571 NS_HTML5_CONTINUE(stateloop); 1572 } 1573 } 1574 } 1575 commentlessthanloop_end:; 1576 [[fallthrough]]; 1577 } 1578 case COMMENT_LESSTHAN_BANG: { 1579 for (;;) { 1580 if (++pos == endPos) { 1581 NS_HTML5_BREAK(stateloop); 1582 } 1583 c = P::checkChar(this, buf, pos); 1584 switch (c) { 1585 case '-': { 1586 appendStrBuf(c); 1587 state = 1588 P::transition(mViewSource.get(), 1589 nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG_DASH, 1590 reconsume, pos); 1591 NS_HTML5_BREAK(commentlessthanbangloop); 1592 } 1593 case '<': { 1594 appendStrBuf(c); 1595 state = P::transition(mViewSource.get(), 1596 nsHtml5Tokenizer::COMMENT_LESSTHAN, 1597 reconsume, pos); 1598 NS_HTML5_CONTINUE(stateloop); 1599 } 1600 case '\r': { 1601 appendStrBufCarriageReturn<P>(); 1602 state = 1603 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1604 reconsume, pos); 1605 NS_HTML5_BREAK(stateloop); 1606 } 1607 case '\n': { 1608 appendStrBufLineFeed<P>(); 1609 state = 1610 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1611 reconsume, pos); 1612 NS_HTML5_CONTINUE(stateloop); 1613 } 1614 case '\0': { 1615 c = 0xfffd; 1616 [[fallthrough]]; 1617 } 1618 default: { 1619 appendStrBuf(c); 1620 state = 1621 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT, 1622 reconsume, pos); 1623 NS_HTML5_CONTINUE(stateloop); 1624 } 1625 } 1626 } 1627 commentlessthanbangloop_end:; 1628 [[fallthrough]]; 1629 } 1630 case COMMENT_LESSTHAN_BANG_DASH: { 1631 if (++pos == endPos) { 1632 NS_HTML5_BREAK(stateloop); 1633 } 1634 c = P::checkChar(this, buf, pos); 1635 switch (c) { 1636 case '-': { 1637 appendStrBuf(c); 1638 state = P::transition( 1639 mViewSource.get(), 1640 nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG_DASH_DASH, reconsume, 1641 pos); 1642 break; 1643 } 1644 case '<': { 1645 appendStrBuf(c); 1646 state = P::transition(mViewSource.get(), 1647 nsHtml5Tokenizer::COMMENT_LESSTHAN, 1648 reconsume, pos); 1649 NS_HTML5_CONTINUE(stateloop); 1650 } 1651 case '\r': { 1652 appendStrBufCarriageReturn<P>(); 1653 state = P::transition(mViewSource.get(), 1654 nsHtml5Tokenizer::COMMENT, reconsume, pos); 1655 NS_HTML5_BREAK(stateloop); 1656 } 1657 case '\n': { 1658 appendStrBufLineFeed<P>(); 1659 state = P::transition(mViewSource.get(), 1660 nsHtml5Tokenizer::COMMENT, reconsume, pos); 1661 NS_HTML5_CONTINUE(stateloop); 1662 } 1663 case '\0': { 1664 c = 0xfffd; 1665 [[fallthrough]]; 1666 } 1667 default: { 1668 appendStrBuf(c); 1669 state = P::transition(mViewSource.get(), 1670 nsHtml5Tokenizer::COMMENT, reconsume, pos); 1671 NS_HTML5_CONTINUE(stateloop); 1672 } 1673 } 1674 [[fallthrough]]; 1675 } 1676 case COMMENT_LESSTHAN_BANG_DASH_DASH: { 1677 if (++pos == endPos) { 1678 NS_HTML5_BREAK(stateloop); 1679 } 1680 c = P::checkChar(this, buf, pos); 1681 switch (c) { 1682 case '>': { 1683 appendStrBuf(c); 1684 emitComment(3, pos); 1685 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 1686 reconsume, pos); 1687 if (shouldSuspend) { 1688 NS_HTML5_BREAK(stateloop); 1689 } 1690 NS_HTML5_CONTINUE(stateloop); 1691 } 1692 case '-': { 1693 if (P::reportErrors) { 1694 errNestedComment(); 1695 } 1696 adjustDoubleHyphenAndAppendToStrBufAndErr( 1697 c, reportedConsecutiveHyphens); 1698 reportedConsecutiveHyphens = true; 1699 state = 1700 P::transition(mViewSource.get(), 1701 nsHtml5Tokenizer::COMMENT_END, reconsume, pos); 1702 NS_HTML5_CONTINUE(stateloop); 1703 } 1704 case '\r': { 1705 c = '\n'; 1706 P::silentCarriageReturn(this); 1707 if (P::reportErrors) { 1708 errNestedComment(); 1709 } 1710 adjustDoubleHyphenAndAppendToStrBufAndErr( 1711 c, reportedConsecutiveHyphens); 1712 reportedConsecutiveHyphens = true; 1713 state = P::transition(mViewSource.get(), 1714 nsHtml5Tokenizer::COMMENT, reconsume, pos); 1715 NS_HTML5_BREAK(stateloop); 1716 } 1717 case '\n': { 1718 P::silentLineFeed(this); 1719 if (P::reportErrors) { 1720 errNestedComment(); 1721 } 1722 adjustDoubleHyphenAndAppendToStrBufAndErr( 1723 c, reportedConsecutiveHyphens); 1724 reportedConsecutiveHyphens = true; 1725 state = P::transition(mViewSource.get(), 1726 nsHtml5Tokenizer::COMMENT, reconsume, pos); 1727 NS_HTML5_CONTINUE(stateloop); 1728 } 1729 case '!': { 1730 if (P::reportErrors) { 1731 errNestedComment(); 1732 } 1733 adjustDoubleHyphenAndAppendToStrBufAndErr( 1734 c, reportedConsecutiveHyphens); 1735 reportedConsecutiveHyphens = true; 1736 state = P::transition(mViewSource.get(), 1737 nsHtml5Tokenizer::COMMENT_END_BANG, 1738 reconsume, pos); 1739 NS_HTML5_CONTINUE(stateloop); 1740 } 1741 case '\0': { 1742 c = 0xfffd; 1743 [[fallthrough]]; 1744 } 1745 default: { 1746 if (P::reportErrors) { 1747 errNestedComment(); 1748 } 1749 adjustDoubleHyphenAndAppendToStrBufAndErr( 1750 c, reportedConsecutiveHyphens); 1751 reportedConsecutiveHyphens = true; 1752 state = P::transition(mViewSource.get(), 1753 nsHtml5Tokenizer::COMMENT, reconsume, pos); 1754 NS_HTML5_CONTINUE(stateloop); 1755 } 1756 } 1757 } 1758 case COMMENT_START_DASH: { 1759 if (++pos == endPos) { 1760 NS_HTML5_BREAK(stateloop); 1761 } 1762 c = P::checkChar(this, buf, pos); 1763 switch (c) { 1764 case '-': { 1765 appendStrBuf(c); 1766 state = 1767 P::transition(mViewSource.get(), 1768 nsHtml5Tokenizer::COMMENT_END, reconsume, pos); 1769 NS_HTML5_CONTINUE(stateloop); 1770 } 1771 case '>': { 1772 if (P::reportErrors) { 1773 errPrematureEndOfComment(); 1774 } 1775 emitComment(1, pos); 1776 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 1777 reconsume, pos); 1778 if (shouldSuspend) { 1779 NS_HTML5_BREAK(stateloop); 1780 } 1781 NS_HTML5_CONTINUE(stateloop); 1782 } 1783 case '<': { 1784 appendStrBuf(c); 1785 state = P::transition(mViewSource.get(), 1786 nsHtml5Tokenizer::COMMENT_LESSTHAN, 1787 reconsume, pos); 1788 NS_HTML5_CONTINUE(stateloop); 1789 } 1790 case '\r': { 1791 appendStrBufCarriageReturn<P>(); 1792 state = P::transition(mViewSource.get(), 1793 nsHtml5Tokenizer::COMMENT, reconsume, pos); 1794 NS_HTML5_BREAK(stateloop); 1795 } 1796 case '\n': { 1797 appendStrBufLineFeed<P>(); 1798 state = P::transition(mViewSource.get(), 1799 nsHtml5Tokenizer::COMMENT, reconsume, pos); 1800 NS_HTML5_CONTINUE(stateloop); 1801 } 1802 case '\0': { 1803 c = 0xfffd; 1804 [[fallthrough]]; 1805 } 1806 default: { 1807 appendStrBuf(c); 1808 state = P::transition(mViewSource.get(), 1809 nsHtml5Tokenizer::COMMENT, reconsume, pos); 1810 NS_HTML5_CONTINUE(stateloop); 1811 } 1812 } 1813 } 1814 case CDATA_START: { 1815 for (;;) { 1816 if (++pos == endPos) { 1817 NS_HTML5_BREAK(stateloop); 1818 } 1819 c = P::checkChar(this, buf, pos); 1820 if (index < 6) { 1821 if (c == nsHtml5Tokenizer::CDATA_LSQB[index]) { 1822 appendStrBuf(c); 1823 } else { 1824 if (P::reportErrors) { 1825 errBogusComment(); 1826 } 1827 reconsume = true; 1828 state = P::transition(mViewSource.get(), 1829 nsHtml5Tokenizer::BOGUS_COMMENT, 1830 reconsume, pos); 1831 NS_HTML5_CONTINUE(stateloop); 1832 } 1833 index++; 1834 continue; 1835 } else { 1836 clearStrBufAfterUse(); 1837 cstart = pos; 1838 reconsume = true; 1839 state = P::transition(mViewSource.get(), 1840 nsHtml5Tokenizer::CDATA_SECTION, reconsume, 1841 pos); 1842 break; 1843 } 1844 } 1845 [[fallthrough]]; 1846 } 1847 case CDATA_SECTION: { 1848 for (;;) { 1849 if (reconsume) { 1850 reconsume = false; 1851 } else { 1852 ++pos; 1853 pos += 1854 P::accelerateAdvancementCdataSection(this, buf, pos, endPos); 1855 if (pos == endPos) { 1856 NS_HTML5_BREAK(stateloop); 1857 } 1858 c = P::checkChar(this, buf, pos); 1859 } 1860 switch (c) { 1861 case ']': { 1862 flushChars(buf, pos); 1863 state = 1864 P::transition(mViewSource.get(), 1865 nsHtml5Tokenizer::CDATA_RSQB, reconsume, pos); 1866 NS_HTML5_BREAK(cdatasectionloop); 1867 } 1868 case '\0': { 1869 maybeEmitReplacementCharacter(buf, pos); 1870 continue; 1871 } 1872 case '\r': { 1873 emitCarriageReturn<P>(buf, pos); 1874 NS_HTML5_BREAK(stateloop); 1875 } 1876 case '\n': { 1877 P::silentLineFeed(this); 1878 [[fallthrough]]; 1879 } 1880 default: { 1881 continue; 1882 } 1883 } 1884 } 1885 cdatasectionloop_end:; 1886 [[fallthrough]]; 1887 } 1888 case CDATA_RSQB: { 1889 if (++pos == endPos) { 1890 NS_HTML5_BREAK(stateloop); 1891 } 1892 c = P::checkChar(this, buf, pos); 1893 switch (c) { 1894 case ']': { 1895 state = P::transition(mViewSource.get(), 1896 nsHtml5Tokenizer::CDATA_RSQB_RSQB, 1897 reconsume, pos); 1898 break; 1899 } 1900 default: { 1901 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1); 1902 cstart = pos; 1903 reconsume = true; 1904 state = P::transition(mViewSource.get(), 1905 nsHtml5Tokenizer::CDATA_SECTION, reconsume, 1906 pos); 1907 NS_HTML5_CONTINUE(stateloop); 1908 } 1909 } 1910 [[fallthrough]]; 1911 } 1912 case CDATA_RSQB_RSQB: { 1913 for (;;) { 1914 if (++pos == endPos) { 1915 NS_HTML5_BREAK(stateloop); 1916 } 1917 c = P::checkChar(this, buf, pos); 1918 switch (c) { 1919 case ']': { 1920 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1); 1921 continue; 1922 } 1923 case '>': { 1924 cstart = pos + 1; 1925 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 1926 reconsume, pos); 1927 suspendIfRequestedAfterCurrentNonTextToken(); 1928 if (shouldSuspend) { 1929 NS_HTML5_BREAK(stateloop); 1930 } 1931 NS_HTML5_CONTINUE(stateloop); 1932 } 1933 default: { 1934 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 2); 1935 cstart = pos; 1936 reconsume = true; 1937 state = P::transition(mViewSource.get(), 1938 nsHtml5Tokenizer::CDATA_SECTION, 1939 reconsume, pos); 1940 NS_HTML5_CONTINUE(stateloop); 1941 } 1942 } 1943 } 1944 } 1945 case ATTRIBUTE_VALUE_SINGLE_QUOTED: { 1946 for (;;) { 1947 if (reconsume) { 1948 reconsume = false; 1949 } else { 1950 ++pos; 1951 pos += P::accelerateAdvancementAttributeValueSingleQuoted( 1952 this, buf, pos, endPos); 1953 if (pos == endPos) { 1954 NS_HTML5_BREAK(stateloop); 1955 } 1956 c = P::checkChar(this, buf, pos); 1957 } 1958 switch (c) { 1959 case '\'': { 1960 addAttributeWithValue(); 1961 state = P::transition( 1962 mViewSource.get(), 1963 nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED, reconsume, 1964 pos); 1965 NS_HTML5_CONTINUE(stateloop); 1966 } 1967 case '&': { 1968 MOZ_ASSERT(!charRefBufLen, 1969 "charRefBufLen not reset after previous use!"); 1970 appendCharRefBuf(c); 1971 setAdditionalAndRememberAmpersandLocation('\''); 1972 returnState = state; 1973 state = 1974 P::transition(mViewSource.get(), 1975 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE, 1976 reconsume, pos); 1977 NS_HTML5_BREAK(attributevaluesinglequotedloop); 1978 } 1979 case '\r': { 1980 appendStrBufCarriageReturn<P>(); 1981 NS_HTML5_BREAK(stateloop); 1982 } 1983 case '\n': { 1984 appendStrBufLineFeed<P>(); 1985 continue; 1986 } 1987 case '\0': { 1988 c = 0xfffd; 1989 [[fallthrough]]; 1990 } 1991 default: { 1992 appendStrBuf(c); 1993 continue; 1994 } 1995 } 1996 } 1997 attributevaluesinglequotedloop_end:; 1998 [[fallthrough]]; 1999 } 2000 case CONSUME_CHARACTER_REFERENCE: { 2001 if (++pos == endPos) { 2002 NS_HTML5_BREAK(stateloop); 2003 } 2004 c = P::checkChar(this, buf, pos); 2005 switch (c) { 2006 case ' ': 2007 case '\t': 2008 case '\n': 2009 case '\r': 2010 case '\f': 2011 case '<': 2012 case '&': 2013 case '\0': 2014 case ';': { 2015 emitOrAppendCharRefBuf(returnState); 2016 if (!(returnState & DATA_AND_RCDATA_MASK)) { 2017 cstart = pos; 2018 } 2019 reconsume = true; 2020 state = 2021 P::transition(mViewSource.get(), returnState, reconsume, pos); 2022 NS_HTML5_CONTINUE(stateloop); 2023 } 2024 case '#': { 2025 appendCharRefBuf('#'); 2026 state = 2027 P::transition(mViewSource.get(), 2028 nsHtml5Tokenizer::CONSUME_NCR, reconsume, pos); 2029 NS_HTML5_CONTINUE(stateloop); 2030 } 2031 default: { 2032 if (c == additional) { 2033 emitOrAppendCharRefBuf(returnState); 2034 reconsume = true; 2035 state = P::transition(mViewSource.get(), returnState, reconsume, 2036 pos); 2037 NS_HTML5_CONTINUE(stateloop); 2038 } 2039 if (c >= 'a' && c <= 'z') { 2040 firstCharKey = c - 'a' + 26; 2041 } else if (c >= 'A' && c <= 'Z') { 2042 firstCharKey = c - 'A'; 2043 } else { 2044 if (c == ';') { 2045 if (P::reportErrors) { 2046 errNoNamedCharacterMatch(); 2047 } 2048 } 2049 emitOrAppendCharRefBuf(returnState); 2050 if (!(returnState & DATA_AND_RCDATA_MASK)) { 2051 cstart = pos; 2052 } 2053 reconsume = true; 2054 state = P::transition(mViewSource.get(), returnState, reconsume, 2055 pos); 2056 NS_HTML5_CONTINUE(stateloop); 2057 } 2058 appendCharRefBuf(c); 2059 state = P::transition( 2060 mViewSource.get(), 2061 nsHtml5Tokenizer::CHARACTER_REFERENCE_HILO_LOOKUP, reconsume, 2062 pos); 2063 break; 2064 } 2065 } 2066 [[fallthrough]]; 2067 } 2068 case CHARACTER_REFERENCE_HILO_LOOKUP: { 2069 { 2070 if (++pos == endPos) { 2071 NS_HTML5_BREAK(stateloop); 2072 } 2073 c = P::checkChar(this, buf, pos); 2074 int32_t hilo = 0; 2075 if (c <= 'z') { 2076 const int32_t* row = nsHtml5NamedCharactersAccel::HILO_ACCEL[c]; 2077 if (row) { 2078 hilo = row[firstCharKey]; 2079 } 2080 } 2081 if (!hilo) { 2082 if (c == ';') { 2083 if (P::reportErrors) { 2084 errNoNamedCharacterMatch(); 2085 } 2086 } 2087 emitOrAppendCharRefBuf(returnState); 2088 if (!(returnState & DATA_AND_RCDATA_MASK)) { 2089 cstart = pos; 2090 } 2091 reconsume = true; 2092 state = 2093 P::transition(mViewSource.get(), returnState, reconsume, pos); 2094 NS_HTML5_CONTINUE(stateloop); 2095 } 2096 appendCharRefBuf(c); 2097 lo = hilo & 0xFFFF; 2098 hi = hilo >> 16; 2099 entCol = -1; 2100 candidate = -1; 2101 charRefBufMark = 0; 2102 state = P::transition(mViewSource.get(), 2103 nsHtml5Tokenizer::CHARACTER_REFERENCE_TAIL, 2104 reconsume, pos); 2105 } 2106 [[fallthrough]]; 2107 } 2108 case CHARACTER_REFERENCE_TAIL: { 2109 for (;;) { 2110 if (++pos == endPos) { 2111 NS_HTML5_BREAK(stateloop); 2112 } 2113 c = P::checkChar(this, buf, pos); 2114 entCol++; 2115 for (;;) { 2116 if (hi < lo) { 2117 NS_HTML5_BREAK(outer); 2118 } 2119 if (entCol == nsHtml5NamedCharacters::NAMES[lo].length()) { 2120 candidate = lo; 2121 charRefBufMark = charRefBufLen; 2122 lo++; 2123 } else if (entCol > nsHtml5NamedCharacters::NAMES[lo].length()) { 2124 NS_HTML5_BREAK(outer); 2125 } else if (c > nsHtml5NamedCharacters::NAMES[lo].charAt(entCol)) { 2126 lo++; 2127 } else { 2128 NS_HTML5_BREAK(loloop); 2129 } 2130 } 2131 loloop_end:; 2132 for (;;) { 2133 if (hi < lo) { 2134 NS_HTML5_BREAK(outer); 2135 } 2136 if (entCol == nsHtml5NamedCharacters::NAMES[hi].length()) { 2137 NS_HTML5_BREAK(hiloop); 2138 } 2139 if (entCol > nsHtml5NamedCharacters::NAMES[hi].length()) { 2140 NS_HTML5_BREAK(outer); 2141 } else if (c < nsHtml5NamedCharacters::NAMES[hi].charAt(entCol)) { 2142 hi--; 2143 } else { 2144 NS_HTML5_BREAK(hiloop); 2145 } 2146 } 2147 hiloop_end:; 2148 if (c == ';') { 2149 if (entCol + 1 == nsHtml5NamedCharacters::NAMES[lo].length()) { 2150 candidate = lo; 2151 charRefBufMark = charRefBufLen; 2152 } 2153 NS_HTML5_BREAK(outer); 2154 } 2155 if (hi < lo) { 2156 NS_HTML5_BREAK(outer); 2157 } 2158 appendCharRefBuf(c); 2159 continue; 2160 } 2161 outer_end:; 2162 if (candidate == -1) { 2163 if (c == ';') { 2164 if (P::reportErrors) { 2165 errNoNamedCharacterMatch(); 2166 } 2167 } 2168 emitOrAppendCharRefBuf(returnState); 2169 if (!(returnState & DATA_AND_RCDATA_MASK)) { 2170 cstart = pos; 2171 } 2172 reconsume = true; 2173 state = 2174 P::transition(mViewSource.get(), returnState, reconsume, pos); 2175 NS_HTML5_CONTINUE(stateloop); 2176 } else { 2177 const nsHtml5CharacterName& candidateName = 2178 nsHtml5NamedCharacters::NAMES[candidate]; 2179 if (!candidateName.length() || 2180 candidateName.charAt(candidateName.length() - 1) != ';') { 2181 if ((returnState & DATA_AND_RCDATA_MASK)) { 2182 char16_t ch; 2183 if (charRefBufMark == charRefBufLen) { 2184 ch = c; 2185 } else { 2186 ch = charRefBuf[charRefBufMark]; 2187 } 2188 if (ch == '=' || (ch >= '0' && ch <= '9') || 2189 (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) { 2190 if (c == ';') { 2191 if (P::reportErrors) { 2192 errNoNamedCharacterMatch(); 2193 } 2194 } 2195 appendCharRefBufToStrBuf(); 2196 reconsume = true; 2197 state = P::transition(mViewSource.get(), returnState, 2198 reconsume, pos); 2199 NS_HTML5_CONTINUE(stateloop); 2200 } 2201 } 2202 if ((returnState & DATA_AND_RCDATA_MASK)) { 2203 if (P::reportErrors) { 2204 errUnescapedAmpersandInterpretedAsCharacterReference(); 2205 } 2206 } else { 2207 if (P::reportErrors) { 2208 errNotSemicolonTerminated(); 2209 } 2210 } 2211 } 2212 P::completedNamedCharacterReference(mViewSource.get()); 2213 const char16_t* val = nsHtml5NamedCharacters::VALUES[candidate]; 2214 if (!val[1]) { 2215 emitOrAppendOne(val, returnState); 2216 } else { 2217 emitOrAppendTwo(val, returnState); 2218 } 2219 if (charRefBufMark < charRefBufLen) { 2220 if ((returnState & DATA_AND_RCDATA_MASK)) { 2221 appendStrBuf(charRefBuf, charRefBufMark, 2222 charRefBufLen - charRefBufMark); 2223 } else { 2224 tokenHandler->characters(charRefBuf, charRefBufMark, 2225 charRefBufLen - charRefBufMark); 2226 } 2227 } 2228 bool earlyBreak = (c == ';' && charRefBufMark == charRefBufLen); 2229 charRefBufLen = 0; 2230 if (!(returnState & DATA_AND_RCDATA_MASK)) { 2231 cstart = earlyBreak ? pos + 1 : pos; 2232 } 2233 reconsume = !earlyBreak; 2234 state = 2235 P::transition(mViewSource.get(), returnState, reconsume, pos); 2236 NS_HTML5_CONTINUE(stateloop); 2237 } 2238 } 2239 case CONSUME_NCR: { 2240 if (++pos == endPos) { 2241 NS_HTML5_BREAK(stateloop); 2242 } 2243 c = P::checkChar(this, buf, pos); 2244 value = 0; 2245 seenDigits = false; 2246 switch (c) { 2247 case 'x': 2248 case 'X': { 2249 appendCharRefBuf(c); 2250 state = 2251 P::transition(mViewSource.get(), 2252 nsHtml5Tokenizer::HEX_NCR_LOOP, reconsume, pos); 2253 NS_HTML5_CONTINUE(stateloop); 2254 } 2255 default: { 2256 reconsume = true; 2257 state = P::transition(mViewSource.get(), 2258 nsHtml5Tokenizer::DECIMAL_NRC_LOOP, 2259 reconsume, pos); 2260 break; 2261 } 2262 } 2263 [[fallthrough]]; 2264 } 2265 case DECIMAL_NRC_LOOP: { 2266 for (;;) { 2267 if (reconsume) { 2268 reconsume = false; 2269 } else { 2270 if (++pos == endPos) { 2271 NS_HTML5_BREAK(stateloop); 2272 } 2273 c = P::checkChar(this, buf, pos); 2274 } 2275 MOZ_ASSERT(value >= 0, "value must not become negative."); 2276 if (c >= '0' && c <= '9') { 2277 seenDigits = true; 2278 if (value <= 0x10FFFF) { 2279 value *= 10; 2280 value += c - '0'; 2281 } 2282 continue; 2283 } else if (c == ';') { 2284 if (seenDigits) { 2285 if (!(returnState & DATA_AND_RCDATA_MASK)) { 2286 cstart = pos + 1; 2287 } 2288 state = P::transition(mViewSource.get(), 2289 nsHtml5Tokenizer::HANDLE_NCR_VALUE, 2290 reconsume, pos); 2291 NS_HTML5_BREAK(decimalloop); 2292 } else { 2293 if (P::reportErrors) { 2294 errNoDigitsInNCR(); 2295 } 2296 appendCharRefBuf(';'); 2297 emitOrAppendCharRefBuf(returnState); 2298 if (!(returnState & DATA_AND_RCDATA_MASK)) { 2299 cstart = pos + 1; 2300 } 2301 state = P::transition(mViewSource.get(), returnState, reconsume, 2302 pos); 2303 NS_HTML5_CONTINUE(stateloop); 2304 } 2305 } else { 2306 if (!seenDigits) { 2307 if (P::reportErrors) { 2308 errNoDigitsInNCR(); 2309 } 2310 emitOrAppendCharRefBuf(returnState); 2311 if (!(returnState & DATA_AND_RCDATA_MASK)) { 2312 cstart = pos; 2313 } 2314 reconsume = true; 2315 state = P::transition(mViewSource.get(), returnState, reconsume, 2316 pos); 2317 NS_HTML5_CONTINUE(stateloop); 2318 } else { 2319 if (P::reportErrors) { 2320 errCharRefLacksSemicolon(); 2321 } 2322 if (!(returnState & DATA_AND_RCDATA_MASK)) { 2323 cstart = pos; 2324 } 2325 reconsume = true; 2326 state = P::transition(mViewSource.get(), 2327 nsHtml5Tokenizer::HANDLE_NCR_VALUE, 2328 reconsume, pos); 2329 NS_HTML5_BREAK(decimalloop); 2330 } 2331 } 2332 } 2333 decimalloop_end:; 2334 [[fallthrough]]; 2335 } 2336 case HANDLE_NCR_VALUE: { 2337 charRefBufLen = 0; 2338 handleNcrValue(returnState); 2339 state = P::transition(mViewSource.get(), returnState, reconsume, pos); 2340 NS_HTML5_CONTINUE(stateloop); 2341 } 2342 case HEX_NCR_LOOP: { 2343 for (;;) { 2344 if (++pos == endPos) { 2345 NS_HTML5_BREAK(stateloop); 2346 } 2347 c = P::checkChar(this, buf, pos); 2348 MOZ_ASSERT(value >= 0, "value must not become negative."); 2349 if (c >= '0' && c <= '9') { 2350 seenDigits = true; 2351 if (value <= 0x10FFFF) { 2352 value *= 16; 2353 value += c - '0'; 2354 } 2355 continue; 2356 } else if (c >= 'A' && c <= 'F') { 2357 seenDigits = true; 2358 if (value <= 0x10FFFF) { 2359 value *= 16; 2360 value += c - 'A' + 10; 2361 } 2362 continue; 2363 } else if (c >= 'a' && c <= 'f') { 2364 seenDigits = true; 2365 if (value <= 0x10FFFF) { 2366 value *= 16; 2367 value += c - 'a' + 10; 2368 } 2369 continue; 2370 } else if (c == ';') { 2371 if (seenDigits) { 2372 if (!(returnState & DATA_AND_RCDATA_MASK)) { 2373 cstart = pos + 1; 2374 } 2375 state = P::transition(mViewSource.get(), 2376 nsHtml5Tokenizer::HANDLE_NCR_VALUE, 2377 reconsume, pos); 2378 NS_HTML5_CONTINUE(stateloop); 2379 } else { 2380 if (P::reportErrors) { 2381 errNoDigitsInNCR(); 2382 } 2383 appendCharRefBuf(';'); 2384 emitOrAppendCharRefBuf(returnState); 2385 if (!(returnState & DATA_AND_RCDATA_MASK)) { 2386 cstart = pos + 1; 2387 } 2388 state = P::transition(mViewSource.get(), returnState, reconsume, 2389 pos); 2390 NS_HTML5_CONTINUE(stateloop); 2391 } 2392 } else { 2393 if (!seenDigits) { 2394 if (P::reportErrors) { 2395 errNoDigitsInNCR(); 2396 } 2397 emitOrAppendCharRefBuf(returnState); 2398 if (!(returnState & DATA_AND_RCDATA_MASK)) { 2399 cstart = pos; 2400 } 2401 reconsume = true; 2402 state = P::transition(mViewSource.get(), returnState, reconsume, 2403 pos); 2404 NS_HTML5_CONTINUE(stateloop); 2405 } else { 2406 if (P::reportErrors) { 2407 errCharRefLacksSemicolon(); 2408 } 2409 if (!(returnState & DATA_AND_RCDATA_MASK)) { 2410 cstart = pos; 2411 } 2412 reconsume = true; 2413 state = P::transition(mViewSource.get(), 2414 nsHtml5Tokenizer::HANDLE_NCR_VALUE, 2415 reconsume, pos); 2416 NS_HTML5_CONTINUE(stateloop); 2417 } 2418 } 2419 } 2420 } 2421 case PLAINTEXT: { 2422 for (;;) { 2423 if (reconsume) { 2424 reconsume = false; 2425 } else { 2426 ++pos; 2427 pos += P::accelerateAdvancementPlaintext(this, buf, pos, endPos); 2428 if (pos == endPos) { 2429 NS_HTML5_BREAK(stateloop); 2430 } 2431 c = P::checkChar(this, buf, pos); 2432 } 2433 switch (c) { 2434 case '\0': { 2435 emitPlaintextReplacementCharacter(buf, pos); 2436 continue; 2437 } 2438 case '\r': { 2439 emitCarriageReturn<P>(buf, pos); 2440 NS_HTML5_BREAK(stateloop); 2441 } 2442 case '\n': { 2443 P::silentLineFeed(this); 2444 [[fallthrough]]; 2445 } 2446 default: { 2447 continue; 2448 } 2449 } 2450 } 2451 } 2452 case CLOSE_TAG_OPEN: { 2453 if (++pos == endPos) { 2454 NS_HTML5_BREAK(stateloop); 2455 } 2456 c = P::checkChar(this, buf, pos); 2457 switch (c) { 2458 case '>': { 2459 if (P::reportErrors) { 2460 errLtSlashGt(); 2461 } 2462 cstart = pos + 1; 2463 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 2464 reconsume, pos); 2465 NS_HTML5_CONTINUE(stateloop); 2466 } 2467 case '\r': { 2468 P::silentCarriageReturn(this); 2469 if (P::reportErrors) { 2470 errGarbageAfterLtSlash(); 2471 } 2472 clearStrBufBeforeUse(); 2473 appendStrBuf('\n'); 2474 state = P::transition(mViewSource.get(), 2475 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume, 2476 pos); 2477 NS_HTML5_BREAK(stateloop); 2478 } 2479 case '\n': { 2480 P::silentLineFeed(this); 2481 if (P::reportErrors) { 2482 errGarbageAfterLtSlash(); 2483 } 2484 clearStrBufBeforeUse(); 2485 appendStrBuf(c); 2486 state = P::transition(mViewSource.get(), 2487 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume, 2488 pos); 2489 NS_HTML5_CONTINUE(stateloop); 2490 } 2491 case '\0': { 2492 c = 0xfffd; 2493 [[fallthrough]]; 2494 } 2495 default: { 2496 if (c >= 'A' && c <= 'Z') { 2497 c += 0x20; 2498 } 2499 if (c >= 'a' && c <= 'z') { 2500 endTag = true; 2501 clearStrBufBeforeUse(); 2502 appendStrBuf(c); 2503 containsHyphen = false; 2504 state = 2505 P::transition(mViewSource.get(), nsHtml5Tokenizer::TAG_NAME, 2506 reconsume, pos); 2507 NS_HTML5_CONTINUE(stateloop); 2508 } else { 2509 if (P::reportErrors) { 2510 errGarbageAfterLtSlash(); 2511 } 2512 clearStrBufBeforeUse(); 2513 appendStrBuf(c); 2514 state = P::transition(mViewSource.get(), 2515 nsHtml5Tokenizer::BOGUS_COMMENT, 2516 reconsume, pos); 2517 NS_HTML5_CONTINUE(stateloop); 2518 } 2519 } 2520 } 2521 } 2522 case RCDATA: { 2523 for (;;) { 2524 if (reconsume) { 2525 reconsume = false; 2526 } else { 2527 ++pos; 2528 pos += P::accelerateAdvancementData(this, buf, pos, endPos); 2529 if (pos == endPos) { 2530 NS_HTML5_BREAK(stateloop); 2531 } 2532 c = P::checkChar(this, buf, pos); 2533 } 2534 switch (c) { 2535 case '&': { 2536 flushChars(buf, pos); 2537 MOZ_ASSERT(!charRefBufLen, 2538 "charRefBufLen not reset after previous use!"); 2539 appendCharRefBuf(c); 2540 setAdditionalAndRememberAmpersandLocation('\0'); 2541 returnState = state; 2542 state = 2543 P::transition(mViewSource.get(), 2544 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE, 2545 reconsume, pos); 2546 NS_HTML5_CONTINUE(stateloop); 2547 } 2548 case '<': { 2549 flushChars(buf, pos); 2550 returnState = state; 2551 state = P::transition( 2552 mViewSource.get(), 2553 nsHtml5Tokenizer::RAWTEXT_RCDATA_LESS_THAN_SIGN, reconsume, 2554 pos); 2555 NS_HTML5_CONTINUE(stateloop); 2556 } 2557 case '\0': { 2558 emitReplacementCharacter(buf, pos); 2559 continue; 2560 } 2561 case '\r': { 2562 emitCarriageReturn<P>(buf, pos); 2563 NS_HTML5_BREAK(stateloop); 2564 } 2565 case '\n': { 2566 P::silentLineFeed(this); 2567 [[fallthrough]]; 2568 } 2569 default: { 2570 continue; 2571 } 2572 } 2573 } 2574 } 2575 case RAWTEXT: { 2576 for (;;) { 2577 if (reconsume) { 2578 reconsume = false; 2579 } else { 2580 ++pos; 2581 pos += P::accelerateAdvancementRawtext(this, buf, pos, endPos); 2582 if (pos == endPos) { 2583 NS_HTML5_BREAK(stateloop); 2584 } 2585 c = P::checkChar(this, buf, pos); 2586 } 2587 switch (c) { 2588 case '<': { 2589 flushChars(buf, pos); 2590 returnState = state; 2591 state = P::transition( 2592 mViewSource.get(), 2593 nsHtml5Tokenizer::RAWTEXT_RCDATA_LESS_THAN_SIGN, reconsume, 2594 pos); 2595 NS_HTML5_BREAK(rawtextloop); 2596 } 2597 case '\0': { 2598 emitReplacementCharacter(buf, pos); 2599 continue; 2600 } 2601 case '\r': { 2602 emitCarriageReturn<P>(buf, pos); 2603 NS_HTML5_BREAK(stateloop); 2604 } 2605 case '\n': { 2606 P::silentLineFeed(this); 2607 [[fallthrough]]; 2608 } 2609 default: { 2610 continue; 2611 } 2612 } 2613 } 2614 rawtextloop_end:; 2615 [[fallthrough]]; 2616 } 2617 case RAWTEXT_RCDATA_LESS_THAN_SIGN: { 2618 for (;;) { 2619 if (++pos == endPos) { 2620 NS_HTML5_BREAK(stateloop); 2621 } 2622 c = P::checkChar(this, buf, pos); 2623 switch (c) { 2624 case '/': { 2625 index = 0; 2626 clearStrBufBeforeUse(); 2627 state = P::transition(mViewSource.get(), 2628 nsHtml5Tokenizer::NON_DATA_END_TAG_NAME, 2629 reconsume, pos); 2630 NS_HTML5_BREAK(rawtextrcdatalessthansignloop); 2631 } 2632 default: { 2633 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1); 2634 cstart = pos; 2635 reconsume = true; 2636 state = P::transition(mViewSource.get(), returnState, reconsume, 2637 pos); 2638 NS_HTML5_CONTINUE(stateloop); 2639 } 2640 } 2641 } 2642 rawtextrcdatalessthansignloop_end:; 2643 [[fallthrough]]; 2644 } 2645 case NON_DATA_END_TAG_NAME: { 2646 for (;;) { 2647 if (++pos == endPos) { 2648 NS_HTML5_BREAK(stateloop); 2649 } 2650 c = P::checkChar(this, buf, pos); 2651 if (!endTagExpectationAsArray) { 2652 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2); 2653 cstart = pos; 2654 reconsume = true; 2655 state = 2656 P::transition(mViewSource.get(), returnState, reconsume, pos); 2657 NS_HTML5_CONTINUE(stateloop); 2658 } else if (index < endTagExpectationAsArray.length) { 2659 char16_t e = endTagExpectationAsArray[index]; 2660 char16_t folded = c; 2661 if (c >= 'A' && c <= 'Z') { 2662 folded += 0x20; 2663 } 2664 if (folded != e) { 2665 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2); 2666 emitStrBuf(); 2667 cstart = pos; 2668 reconsume = true; 2669 state = P::transition(mViewSource.get(), returnState, reconsume, 2670 pos); 2671 NS_HTML5_CONTINUE(stateloop); 2672 } 2673 appendStrBuf(c); 2674 index++; 2675 continue; 2676 } else { 2677 endTag = true; 2678 tagName = endTagExpectation; 2679 switch (c) { 2680 case '\r': { 2681 P::silentCarriageReturn(this); 2682 clearStrBufAfterUse(); 2683 state = P::transition(mViewSource.get(), 2684 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME, 2685 reconsume, pos); 2686 NS_HTML5_BREAK(stateloop); 2687 } 2688 case '\n': { 2689 P::silentLineFeed(this); 2690 [[fallthrough]]; 2691 } 2692 case ' ': 2693 case '\t': 2694 case '\f': { 2695 clearStrBufAfterUse(); 2696 state = P::transition(mViewSource.get(), 2697 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME, 2698 reconsume, pos); 2699 NS_HTML5_CONTINUE(stateloop); 2700 } 2701 case '/': { 2702 clearStrBufAfterUse(); 2703 state = P::transition( 2704 mViewSource.get(), 2705 nsHtml5Tokenizer::SELF_CLOSING_START_TAG, reconsume, pos); 2706 NS_HTML5_CONTINUE(stateloop); 2707 } 2708 case '>': { 2709 clearStrBufAfterUse(); 2710 state = P::transition(mViewSource.get(), 2711 emitCurrentTagToken(false, pos), 2712 reconsume, pos); 2713 if (shouldSuspend) { 2714 NS_HTML5_BREAK(stateloop); 2715 } 2716 NS_HTML5_CONTINUE(stateloop); 2717 } 2718 default: { 2719 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2); 2720 emitStrBuf(); 2721 cstart = pos; 2722 reconsume = true; 2723 state = P::transition(mViewSource.get(), returnState, 2724 reconsume, pos); 2725 NS_HTML5_CONTINUE(stateloop); 2726 } 2727 } 2728 } 2729 } 2730 } 2731 case BOGUS_COMMENT: { 2732 for (;;) { 2733 if (reconsume) { 2734 reconsume = false; 2735 } else { 2736 if (++pos == endPos) { 2737 NS_HTML5_BREAK(stateloop); 2738 } 2739 c = P::checkChar(this, buf, pos); 2740 } 2741 switch (c) { 2742 case '>': { 2743 emitComment(0, pos); 2744 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 2745 reconsume, pos); 2746 if (shouldSuspend) { 2747 NS_HTML5_BREAK(stateloop); 2748 } 2749 NS_HTML5_CONTINUE(stateloop); 2750 } 2751 case '-': { 2752 appendStrBuf(c); 2753 state = P::transition(mViewSource.get(), 2754 nsHtml5Tokenizer::BOGUS_COMMENT_HYPHEN, 2755 reconsume, pos); 2756 NS_HTML5_BREAK(boguscommentloop); 2757 } 2758 case '\r': { 2759 appendStrBufCarriageReturn<P>(); 2760 NS_HTML5_BREAK(stateloop); 2761 } 2762 case '\n': { 2763 appendStrBufLineFeed<P>(); 2764 continue; 2765 } 2766 case '\0': { 2767 c = 0xfffd; 2768 [[fallthrough]]; 2769 } 2770 default: { 2771 appendStrBuf(c); 2772 continue; 2773 } 2774 } 2775 } 2776 boguscommentloop_end:; 2777 [[fallthrough]]; 2778 } 2779 case BOGUS_COMMENT_HYPHEN: { 2780 boguscommenthyphenloop: 2781 for (;;) { 2782 if (++pos == endPos) { 2783 NS_HTML5_BREAK(stateloop); 2784 } 2785 c = P::checkChar(this, buf, pos); 2786 switch (c) { 2787 case '>': { 2788 emitComment(0, pos); 2789 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 2790 reconsume, pos); 2791 if (shouldSuspend) { 2792 NS_HTML5_BREAK(stateloop); 2793 } 2794 NS_HTML5_CONTINUE(stateloop); 2795 } 2796 case '-': { 2797 appendSecondHyphenToBogusComment(); 2798 NS_HTML5_CONTINUE(boguscommenthyphenloop); 2799 } 2800 case '\r': { 2801 appendStrBufCarriageReturn<P>(); 2802 state = P::transition(mViewSource.get(), 2803 nsHtml5Tokenizer::BOGUS_COMMENT, 2804 reconsume, pos); 2805 NS_HTML5_BREAK(stateloop); 2806 } 2807 case '\n': { 2808 appendStrBufLineFeed<P>(); 2809 state = P::transition(mViewSource.get(), 2810 nsHtml5Tokenizer::BOGUS_COMMENT, 2811 reconsume, pos); 2812 NS_HTML5_CONTINUE(stateloop); 2813 } 2814 case '\0': { 2815 c = 0xfffd; 2816 [[fallthrough]]; 2817 } 2818 default: { 2819 appendStrBuf(c); 2820 state = P::transition(mViewSource.get(), 2821 nsHtml5Tokenizer::BOGUS_COMMENT, 2822 reconsume, pos); 2823 NS_HTML5_CONTINUE(stateloop); 2824 } 2825 } 2826 } 2827 } 2828 case SCRIPT_DATA: { 2829 for (;;) { 2830 if (reconsume) { 2831 reconsume = false; 2832 } else { 2833 ++pos; 2834 pos += P::accelerateAdvancementRawtext(this, buf, pos, endPos); 2835 if (pos == endPos) { 2836 NS_HTML5_BREAK(stateloop); 2837 } 2838 c = P::checkChar(this, buf, pos); 2839 } 2840 switch (c) { 2841 case '<': { 2842 flushChars(buf, pos); 2843 returnState = state; 2844 state = 2845 P::transition(mViewSource.get(), 2846 nsHtml5Tokenizer::SCRIPT_DATA_LESS_THAN_SIGN, 2847 reconsume, pos); 2848 NS_HTML5_BREAK(scriptdataloop); 2849 } 2850 case '\0': { 2851 emitReplacementCharacter(buf, pos); 2852 continue; 2853 } 2854 case '\r': { 2855 emitCarriageReturn<P>(buf, pos); 2856 NS_HTML5_BREAK(stateloop); 2857 } 2858 case '\n': { 2859 P::silentLineFeed(this); 2860 [[fallthrough]]; 2861 } 2862 default: { 2863 continue; 2864 } 2865 } 2866 } 2867 scriptdataloop_end:; 2868 [[fallthrough]]; 2869 } 2870 case SCRIPT_DATA_LESS_THAN_SIGN: { 2871 for (;;) { 2872 if (++pos == endPos) { 2873 NS_HTML5_BREAK(stateloop); 2874 } 2875 c = P::checkChar(this, buf, pos); 2876 switch (c) { 2877 case '/': { 2878 index = 0; 2879 clearStrBufBeforeUse(); 2880 state = P::transition(mViewSource.get(), 2881 nsHtml5Tokenizer::NON_DATA_END_TAG_NAME, 2882 reconsume, pos); 2883 NS_HTML5_CONTINUE(stateloop); 2884 } 2885 case '!': { 2886 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1); 2887 cstart = pos; 2888 state = P::transition( 2889 mViewSource.get(), 2890 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPE_START, reconsume, pos); 2891 NS_HTML5_BREAK(scriptdatalessthansignloop); 2892 } 2893 default: { 2894 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1); 2895 cstart = pos; 2896 reconsume = true; 2897 state = P::transition(mViewSource.get(), 2898 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, 2899 pos); 2900 NS_HTML5_CONTINUE(stateloop); 2901 } 2902 } 2903 } 2904 scriptdatalessthansignloop_end:; 2905 [[fallthrough]]; 2906 } 2907 case SCRIPT_DATA_ESCAPE_START: { 2908 for (;;) { 2909 if (++pos == endPos) { 2910 NS_HTML5_BREAK(stateloop); 2911 } 2912 c = P::checkChar(this, buf, pos); 2913 switch (c) { 2914 case '-': { 2915 state = P::transition( 2916 mViewSource.get(), 2917 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPE_START_DASH, reconsume, 2918 pos); 2919 NS_HTML5_BREAK(scriptdataescapestartloop); 2920 } 2921 default: { 2922 reconsume = true; 2923 state = P::transition(mViewSource.get(), 2924 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, 2925 pos); 2926 NS_HTML5_CONTINUE(stateloop); 2927 } 2928 } 2929 } 2930 scriptdataescapestartloop_end:; 2931 [[fallthrough]]; 2932 } 2933 case SCRIPT_DATA_ESCAPE_START_DASH: { 2934 for (;;) { 2935 if (++pos == endPos) { 2936 NS_HTML5_BREAK(stateloop); 2937 } 2938 c = P::checkChar(this, buf, pos); 2939 switch (c) { 2940 case '-': { 2941 state = P::transition( 2942 mViewSource.get(), 2943 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH_DASH, reconsume, 2944 pos); 2945 NS_HTML5_BREAK(scriptdataescapestartdashloop); 2946 } 2947 default: { 2948 reconsume = true; 2949 state = P::transition(mViewSource.get(), 2950 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, 2951 pos); 2952 NS_HTML5_CONTINUE(stateloop); 2953 } 2954 } 2955 } 2956 scriptdataescapestartdashloop_end:; 2957 [[fallthrough]]; 2958 } 2959 case SCRIPT_DATA_ESCAPED_DASH_DASH: { 2960 for (;;) { 2961 if (++pos == endPos) { 2962 NS_HTML5_BREAK(stateloop); 2963 } 2964 c = P::checkChar(this, buf, pos); 2965 switch (c) { 2966 case '-': { 2967 continue; 2968 } 2969 case '<': { 2970 flushChars(buf, pos); 2971 state = P::transition( 2972 mViewSource.get(), 2973 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN, 2974 reconsume, pos); 2975 NS_HTML5_CONTINUE(stateloop); 2976 } 2977 case '>': { 2978 state = P::transition(mViewSource.get(), 2979 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, 2980 pos); 2981 NS_HTML5_CONTINUE(stateloop); 2982 } 2983 case '\0': { 2984 emitReplacementCharacter(buf, pos); 2985 state = P::transition(mViewSource.get(), 2986 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED, 2987 reconsume, pos); 2988 NS_HTML5_BREAK(scriptdataescapeddashdashloop); 2989 } 2990 case '\r': { 2991 emitCarriageReturn<P>(buf, pos); 2992 state = P::transition(mViewSource.get(), 2993 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED, 2994 reconsume, pos); 2995 NS_HTML5_BREAK(stateloop); 2996 } 2997 case '\n': { 2998 P::silentLineFeed(this); 2999 [[fallthrough]]; 3000 } 3001 default: { 3002 state = P::transition(mViewSource.get(), 3003 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED, 3004 reconsume, pos); 3005 NS_HTML5_BREAK(scriptdataescapeddashdashloop); 3006 } 3007 } 3008 } 3009 scriptdataescapeddashdashloop_end:; 3010 [[fallthrough]]; 3011 } 3012 case SCRIPT_DATA_ESCAPED: { 3013 for (;;) { 3014 if (reconsume) { 3015 reconsume = false; 3016 } else { 3017 ++pos; 3018 pos += P::accelerateAdvancementScriptDataEscaped(this, buf, pos, 3019 endPos); 3020 if (pos == endPos) { 3021 NS_HTML5_BREAK(stateloop); 3022 } 3023 c = P::checkChar(this, buf, pos); 3024 } 3025 switch (c) { 3026 case '-': { 3027 state = P::transition( 3028 mViewSource.get(), 3029 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH, reconsume, pos); 3030 NS_HTML5_BREAK(scriptdataescapedloop); 3031 } 3032 case '<': { 3033 flushChars(buf, pos); 3034 state = P::transition( 3035 mViewSource.get(), 3036 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN, 3037 reconsume, pos); 3038 NS_HTML5_CONTINUE(stateloop); 3039 } 3040 case '\0': { 3041 emitReplacementCharacter(buf, pos); 3042 continue; 3043 } 3044 case '\r': { 3045 emitCarriageReturn<P>(buf, pos); 3046 NS_HTML5_BREAK(stateloop); 3047 } 3048 case '\n': { 3049 P::silentLineFeed(this); 3050 [[fallthrough]]; 3051 } 3052 default: { 3053 continue; 3054 } 3055 } 3056 } 3057 scriptdataescapedloop_end:; 3058 [[fallthrough]]; 3059 } 3060 case SCRIPT_DATA_ESCAPED_DASH: { 3061 for (;;) { 3062 if (++pos == endPos) { 3063 NS_HTML5_BREAK(stateloop); 3064 } 3065 c = P::checkChar(this, buf, pos); 3066 switch (c) { 3067 case '-': { 3068 state = P::transition( 3069 mViewSource.get(), 3070 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH_DASH, reconsume, 3071 pos); 3072 NS_HTML5_CONTINUE(stateloop); 3073 } 3074 case '<': { 3075 flushChars(buf, pos); 3076 state = P::transition( 3077 mViewSource.get(), 3078 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN, 3079 reconsume, pos); 3080 NS_HTML5_BREAK(scriptdataescapeddashloop); 3081 } 3082 case '\0': { 3083 emitReplacementCharacter(buf, pos); 3084 state = P::transition(mViewSource.get(), 3085 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED, 3086 reconsume, pos); 3087 NS_HTML5_CONTINUE(stateloop); 3088 } 3089 case '\r': { 3090 emitCarriageReturn<P>(buf, pos); 3091 state = P::transition(mViewSource.get(), 3092 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED, 3093 reconsume, pos); 3094 NS_HTML5_BREAK(stateloop); 3095 } 3096 case '\n': { 3097 P::silentLineFeed(this); 3098 [[fallthrough]]; 3099 } 3100 default: { 3101 state = P::transition(mViewSource.get(), 3102 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED, 3103 reconsume, pos); 3104 NS_HTML5_CONTINUE(stateloop); 3105 } 3106 } 3107 } 3108 scriptdataescapeddashloop_end:; 3109 [[fallthrough]]; 3110 } 3111 case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: { 3112 for (;;) { 3113 if (++pos == endPos) { 3114 NS_HTML5_BREAK(stateloop); 3115 } 3116 c = P::checkChar(this, buf, pos); 3117 switch (c) { 3118 case '/': { 3119 index = 0; 3120 clearStrBufBeforeUse(); 3121 returnState = nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED; 3122 state = P::transition(mViewSource.get(), 3123 nsHtml5Tokenizer::NON_DATA_END_TAG_NAME, 3124 reconsume, pos); 3125 NS_HTML5_CONTINUE(stateloop); 3126 } 3127 case 'S': 3128 case 's': { 3129 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1); 3130 cstart = pos; 3131 index = 1; 3132 state = P::transition( 3133 mViewSource.get(), 3134 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPE_START, 3135 reconsume, pos); 3136 NS_HTML5_BREAK(scriptdataescapedlessthanloop); 3137 } 3138 default: { 3139 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1); 3140 cstart = pos; 3141 reconsume = true; 3142 state = P::transition(mViewSource.get(), 3143 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED, 3144 reconsume, pos); 3145 NS_HTML5_CONTINUE(stateloop); 3146 } 3147 } 3148 } 3149 scriptdataescapedlessthanloop_end:; 3150 [[fallthrough]]; 3151 } 3152 case SCRIPT_DATA_DOUBLE_ESCAPE_START: { 3153 for (;;) { 3154 if (++pos == endPos) { 3155 NS_HTML5_BREAK(stateloop); 3156 } 3157 c = P::checkChar(this, buf, pos); 3158 MOZ_ASSERT(index > 0); 3159 if (index < 6) { 3160 char16_t folded = c; 3161 if (c >= 'A' && c <= 'Z') { 3162 folded += 0x20; 3163 } 3164 if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) { 3165 reconsume = true; 3166 state = P::transition(mViewSource.get(), 3167 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED, 3168 reconsume, pos); 3169 NS_HTML5_CONTINUE(stateloop); 3170 } 3171 index++; 3172 continue; 3173 } 3174 switch (c) { 3175 case '\r': { 3176 emitCarriageReturn<P>(buf, pos); 3177 state = 3178 P::transition(mViewSource.get(), 3179 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, 3180 reconsume, pos); 3181 NS_HTML5_BREAK(stateloop); 3182 } 3183 case '\n': { 3184 P::silentLineFeed(this); 3185 [[fallthrough]]; 3186 } 3187 case ' ': 3188 case '\t': 3189 case '\f': 3190 case '/': 3191 case '>': { 3192 state = 3193 P::transition(mViewSource.get(), 3194 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, 3195 reconsume, pos); 3196 NS_HTML5_BREAK(scriptdatadoubleescapestartloop); 3197 } 3198 default: { 3199 reconsume = true; 3200 state = P::transition(mViewSource.get(), 3201 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED, 3202 reconsume, pos); 3203 NS_HTML5_CONTINUE(stateloop); 3204 } 3205 } 3206 } 3207 scriptdatadoubleescapestartloop_end:; 3208 [[fallthrough]]; 3209 } 3210 case SCRIPT_DATA_DOUBLE_ESCAPED: { 3211 for (;;) { 3212 if (reconsume) { 3213 reconsume = false; 3214 } else { 3215 if (++pos == endPos) { 3216 NS_HTML5_BREAK(stateloop); 3217 } 3218 c = P::checkChar(this, buf, pos); 3219 } 3220 switch (c) { 3221 case '-': { 3222 state = P::transition( 3223 mViewSource.get(), 3224 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_DASH, 3225 reconsume, pos); 3226 NS_HTML5_BREAK(scriptdatadoubleescapedloop); 3227 } 3228 case '<': { 3229 state = P::transition( 3230 mViewSource.get(), 3231 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN, 3232 reconsume, pos); 3233 NS_HTML5_CONTINUE(stateloop); 3234 } 3235 case '\0': { 3236 emitReplacementCharacter(buf, pos); 3237 continue; 3238 } 3239 case '\r': { 3240 emitCarriageReturn<P>(buf, pos); 3241 NS_HTML5_BREAK(stateloop); 3242 } 3243 case '\n': { 3244 P::silentLineFeed(this); 3245 [[fallthrough]]; 3246 } 3247 default: { 3248 continue; 3249 } 3250 } 3251 } 3252 scriptdatadoubleescapedloop_end:; 3253 [[fallthrough]]; 3254 } 3255 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH: { 3256 for (;;) { 3257 if (++pos == endPos) { 3258 NS_HTML5_BREAK(stateloop); 3259 } 3260 c = P::checkChar(this, buf, pos); 3261 switch (c) { 3262 case '-': { 3263 state = P::transition( 3264 mViewSource.get(), 3265 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH, 3266 reconsume, pos); 3267 NS_HTML5_BREAK(scriptdatadoubleescapeddashloop); 3268 } 3269 case '<': { 3270 state = P::transition( 3271 mViewSource.get(), 3272 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN, 3273 reconsume, pos); 3274 NS_HTML5_CONTINUE(stateloop); 3275 } 3276 case '\0': { 3277 emitReplacementCharacter(buf, pos); 3278 state = 3279 P::transition(mViewSource.get(), 3280 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, 3281 reconsume, pos); 3282 NS_HTML5_CONTINUE(stateloop); 3283 } 3284 case '\r': { 3285 emitCarriageReturn<P>(buf, pos); 3286 state = 3287 P::transition(mViewSource.get(), 3288 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, 3289 reconsume, pos); 3290 NS_HTML5_BREAK(stateloop); 3291 } 3292 case '\n': { 3293 P::silentLineFeed(this); 3294 [[fallthrough]]; 3295 } 3296 default: { 3297 state = 3298 P::transition(mViewSource.get(), 3299 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, 3300 reconsume, pos); 3301 NS_HTML5_CONTINUE(stateloop); 3302 } 3303 } 3304 } 3305 scriptdatadoubleescapeddashloop_end:; 3306 [[fallthrough]]; 3307 } 3308 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH: { 3309 for (;;) { 3310 if (++pos == endPos) { 3311 NS_HTML5_BREAK(stateloop); 3312 } 3313 c = P::checkChar(this, buf, pos); 3314 switch (c) { 3315 case '-': { 3316 continue; 3317 } 3318 case '<': { 3319 state = P::transition( 3320 mViewSource.get(), 3321 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN, 3322 reconsume, pos); 3323 NS_HTML5_BREAK(scriptdatadoubleescapeddashdashloop); 3324 } 3325 case '>': { 3326 state = P::transition(mViewSource.get(), 3327 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, 3328 pos); 3329 NS_HTML5_CONTINUE(stateloop); 3330 } 3331 case '\0': { 3332 emitReplacementCharacter(buf, pos); 3333 state = 3334 P::transition(mViewSource.get(), 3335 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, 3336 reconsume, pos); 3337 NS_HTML5_CONTINUE(stateloop); 3338 } 3339 case '\r': { 3340 emitCarriageReturn<P>(buf, pos); 3341 state = 3342 P::transition(mViewSource.get(), 3343 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, 3344 reconsume, pos); 3345 NS_HTML5_BREAK(stateloop); 3346 } 3347 case '\n': { 3348 P::silentLineFeed(this); 3349 [[fallthrough]]; 3350 } 3351 default: { 3352 state = 3353 P::transition(mViewSource.get(), 3354 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, 3355 reconsume, pos); 3356 NS_HTML5_CONTINUE(stateloop); 3357 } 3358 } 3359 } 3360 scriptdatadoubleescapeddashdashloop_end:; 3361 [[fallthrough]]; 3362 } 3363 case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN: { 3364 for (;;) { 3365 if (++pos == endPos) { 3366 NS_HTML5_BREAK(stateloop); 3367 } 3368 c = P::checkChar(this, buf, pos); 3369 switch (c) { 3370 case '/': { 3371 index = 0; 3372 state = P::transition( 3373 mViewSource.get(), 3374 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPE_END, reconsume, 3375 pos); 3376 NS_HTML5_BREAK(scriptdatadoubleescapedlessthanloop); 3377 } 3378 default: { 3379 reconsume = true; 3380 state = 3381 P::transition(mViewSource.get(), 3382 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, 3383 reconsume, pos); 3384 NS_HTML5_CONTINUE(stateloop); 3385 } 3386 } 3387 } 3388 scriptdatadoubleescapedlessthanloop_end:; 3389 [[fallthrough]]; 3390 } 3391 case SCRIPT_DATA_DOUBLE_ESCAPE_END: { 3392 for (;;) { 3393 if (++pos == endPos) { 3394 NS_HTML5_BREAK(stateloop); 3395 } 3396 c = P::checkChar(this, buf, pos); 3397 if (index < 6) { 3398 char16_t folded = c; 3399 if (c >= 'A' && c <= 'Z') { 3400 folded += 0x20; 3401 } 3402 if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) { 3403 reconsume = true; 3404 state = 3405 P::transition(mViewSource.get(), 3406 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, 3407 reconsume, pos); 3408 NS_HTML5_CONTINUE(stateloop); 3409 } 3410 index++; 3411 continue; 3412 } 3413 switch (c) { 3414 case '\r': { 3415 emitCarriageReturn<P>(buf, pos); 3416 state = P::transition(mViewSource.get(), 3417 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED, 3418 reconsume, pos); 3419 NS_HTML5_BREAK(stateloop); 3420 } 3421 case '\n': { 3422 P::silentLineFeed(this); 3423 [[fallthrough]]; 3424 } 3425 case ' ': 3426 case '\t': 3427 case '\f': 3428 case '/': 3429 case '>': { 3430 state = P::transition(mViewSource.get(), 3431 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED, 3432 reconsume, pos); 3433 NS_HTML5_CONTINUE(stateloop); 3434 } 3435 default: { 3436 reconsume = true; 3437 state = 3438 P::transition(mViewSource.get(), 3439 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, 3440 reconsume, pos); 3441 NS_HTML5_CONTINUE(stateloop); 3442 } 3443 } 3444 } 3445 } 3446 case MARKUP_DECLARATION_OCTYPE: { 3447 for (;;) { 3448 if (++pos == endPos) { 3449 NS_HTML5_BREAK(stateloop); 3450 } 3451 c = P::checkChar(this, buf, pos); 3452 if (index < 6) { 3453 char16_t folded = c; 3454 if (c >= 'A' && c <= 'Z') { 3455 folded += 0x20; 3456 } 3457 if (folded == nsHtml5Tokenizer::OCTYPE[index]) { 3458 appendStrBuf(c); 3459 } else { 3460 if (P::reportErrors) { 3461 errBogusComment(); 3462 } 3463 reconsume = true; 3464 state = P::transition(mViewSource.get(), 3465 nsHtml5Tokenizer::BOGUS_COMMENT, 3466 reconsume, pos); 3467 NS_HTML5_CONTINUE(stateloop); 3468 } 3469 index++; 3470 continue; 3471 } else { 3472 reconsume = true; 3473 state = P::transition(mViewSource.get(), 3474 nsHtml5Tokenizer::DOCTYPE, reconsume, pos); 3475 NS_HTML5_BREAK(markupdeclarationdoctypeloop); 3476 } 3477 } 3478 markupdeclarationdoctypeloop_end:; 3479 [[fallthrough]]; 3480 } 3481 case DOCTYPE: { 3482 for (;;) { 3483 if (reconsume) { 3484 reconsume = false; 3485 } else { 3486 if (++pos == endPos) { 3487 NS_HTML5_BREAK(stateloop); 3488 } 3489 c = P::checkChar(this, buf, pos); 3490 } 3491 initDoctypeFields(); 3492 switch (c) { 3493 case '\r': { 3494 P::silentCarriageReturn(this); 3495 state = P::transition(mViewSource.get(), 3496 nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME, 3497 reconsume, pos); 3498 NS_HTML5_BREAK(stateloop); 3499 } 3500 case '\n': { 3501 P::silentLineFeed(this); 3502 [[fallthrough]]; 3503 } 3504 case ' ': 3505 case '\t': 3506 case '\f': { 3507 state = P::transition(mViewSource.get(), 3508 nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME, 3509 reconsume, pos); 3510 NS_HTML5_BREAK(doctypeloop); 3511 } 3512 default: { 3513 if (P::reportErrors) { 3514 errMissingSpaceBeforeDoctypeName(); 3515 } 3516 reconsume = true; 3517 state = P::transition(mViewSource.get(), 3518 nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME, 3519 reconsume, pos); 3520 NS_HTML5_BREAK(doctypeloop); 3521 } 3522 } 3523 } 3524 doctypeloop_end:; 3525 [[fallthrough]]; 3526 } 3527 case BEFORE_DOCTYPE_NAME: { 3528 for (;;) { 3529 if (reconsume) { 3530 reconsume = false; 3531 } else { 3532 if (++pos == endPos) { 3533 NS_HTML5_BREAK(stateloop); 3534 } 3535 c = P::checkChar(this, buf, pos); 3536 } 3537 switch (c) { 3538 case '\r': { 3539 P::silentCarriageReturn(this); 3540 NS_HTML5_BREAK(stateloop); 3541 } 3542 case '\n': { 3543 P::silentLineFeed(this); 3544 [[fallthrough]]; 3545 } 3546 case ' ': 3547 case '\t': 3548 case '\f': { 3549 continue; 3550 } 3551 case '>': { 3552 if (P::reportErrors) { 3553 errNamelessDoctype(); 3554 } 3555 forceQuirks = true; 3556 emitDoctypeToken(pos); 3557 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 3558 reconsume, pos); 3559 if (shouldSuspend) { 3560 NS_HTML5_BREAK(stateloop); 3561 } 3562 NS_HTML5_CONTINUE(stateloop); 3563 } 3564 case '\0': { 3565 c = 0xfffd; 3566 [[fallthrough]]; 3567 } 3568 default: { 3569 if (c >= 'A' && c <= 'Z') { 3570 c += 0x20; 3571 } 3572 clearStrBufBeforeUse(); 3573 appendStrBuf(c); 3574 state = P::transition(mViewSource.get(), 3575 nsHtml5Tokenizer::DOCTYPE_NAME, reconsume, 3576 pos); 3577 NS_HTML5_BREAK(beforedoctypenameloop); 3578 } 3579 } 3580 } 3581 beforedoctypenameloop_end:; 3582 [[fallthrough]]; 3583 } 3584 case DOCTYPE_NAME: { 3585 for (;;) { 3586 if (++pos == endPos) { 3587 NS_HTML5_BREAK(stateloop); 3588 } 3589 c = P::checkChar(this, buf, pos); 3590 switch (c) { 3591 case '\r': { 3592 P::silentCarriageReturn(this); 3593 strBufToDoctypeName(); 3594 state = P::transition(mViewSource.get(), 3595 nsHtml5Tokenizer::AFTER_DOCTYPE_NAME, 3596 reconsume, pos); 3597 NS_HTML5_BREAK(stateloop); 3598 } 3599 case '\n': { 3600 P::silentLineFeed(this); 3601 [[fallthrough]]; 3602 } 3603 case ' ': 3604 case '\t': 3605 case '\f': { 3606 strBufToDoctypeName(); 3607 state = P::transition(mViewSource.get(), 3608 nsHtml5Tokenizer::AFTER_DOCTYPE_NAME, 3609 reconsume, pos); 3610 NS_HTML5_BREAK(doctypenameloop); 3611 } 3612 case '>': { 3613 strBufToDoctypeName(); 3614 emitDoctypeToken(pos); 3615 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 3616 reconsume, pos); 3617 if (shouldSuspend) { 3618 NS_HTML5_BREAK(stateloop); 3619 } 3620 NS_HTML5_CONTINUE(stateloop); 3621 } 3622 case '\0': { 3623 c = 0xfffd; 3624 [[fallthrough]]; 3625 } 3626 default: { 3627 if (c >= 'A' && c <= 'Z') { 3628 c += 0x0020; 3629 } 3630 appendStrBuf(c); 3631 continue; 3632 } 3633 } 3634 } 3635 doctypenameloop_end:; 3636 [[fallthrough]]; 3637 } 3638 case AFTER_DOCTYPE_NAME: { 3639 for (;;) { 3640 if (++pos == endPos) { 3641 NS_HTML5_BREAK(stateloop); 3642 } 3643 c = P::checkChar(this, buf, pos); 3644 switch (c) { 3645 case '\r': { 3646 P::silentCarriageReturn(this); 3647 NS_HTML5_BREAK(stateloop); 3648 } 3649 case '\n': { 3650 P::silentLineFeed(this); 3651 [[fallthrough]]; 3652 } 3653 case ' ': 3654 case '\t': 3655 case '\f': { 3656 continue; 3657 } 3658 case '>': { 3659 emitDoctypeToken(pos); 3660 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 3661 reconsume, pos); 3662 if (shouldSuspend) { 3663 NS_HTML5_BREAK(stateloop); 3664 } 3665 NS_HTML5_CONTINUE(stateloop); 3666 } 3667 case 'p': 3668 case 'P': { 3669 index = 0; 3670 state = P::transition(mViewSource.get(), 3671 nsHtml5Tokenizer::DOCTYPE_UBLIC, 3672 reconsume, pos); 3673 NS_HTML5_BREAK(afterdoctypenameloop); 3674 } 3675 case 's': 3676 case 'S': { 3677 index = 0; 3678 state = P::transition(mViewSource.get(), 3679 nsHtml5Tokenizer::DOCTYPE_YSTEM, 3680 reconsume, pos); 3681 NS_HTML5_CONTINUE(stateloop); 3682 } 3683 default: { 3684 bogusDoctype(); 3685 state = P::transition(mViewSource.get(), 3686 nsHtml5Tokenizer::BOGUS_DOCTYPE, 3687 reconsume, pos); 3688 NS_HTML5_CONTINUE(stateloop); 3689 } 3690 } 3691 } 3692 afterdoctypenameloop_end:; 3693 [[fallthrough]]; 3694 } 3695 case DOCTYPE_UBLIC: { 3696 for (;;) { 3697 if (++pos == endPos) { 3698 NS_HTML5_BREAK(stateloop); 3699 } 3700 c = P::checkChar(this, buf, pos); 3701 if (index < 5) { 3702 char16_t folded = c; 3703 if (c >= 'A' && c <= 'Z') { 3704 folded += 0x20; 3705 } 3706 if (folded != nsHtml5Tokenizer::UBLIC[index]) { 3707 bogusDoctype(); 3708 reconsume = true; 3709 state = P::transition(mViewSource.get(), 3710 nsHtml5Tokenizer::BOGUS_DOCTYPE, 3711 reconsume, pos); 3712 NS_HTML5_CONTINUE(stateloop); 3713 } 3714 index++; 3715 continue; 3716 } else { 3717 reconsume = true; 3718 state = 3719 P::transition(mViewSource.get(), 3720 nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_KEYWORD, 3721 reconsume, pos); 3722 NS_HTML5_BREAK(doctypeublicloop); 3723 } 3724 } 3725 doctypeublicloop_end:; 3726 [[fallthrough]]; 3727 } 3728 case AFTER_DOCTYPE_PUBLIC_KEYWORD: { 3729 for (;;) { 3730 if (reconsume) { 3731 reconsume = false; 3732 } else { 3733 if (++pos == endPos) { 3734 NS_HTML5_BREAK(stateloop); 3735 } 3736 c = P::checkChar(this, buf, pos); 3737 } 3738 switch (c) { 3739 case '\r': { 3740 P::silentCarriageReturn(this); 3741 state = P::transition( 3742 mViewSource.get(), 3743 nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, 3744 reconsume, pos); 3745 NS_HTML5_BREAK(stateloop); 3746 } 3747 case '\n': { 3748 P::silentLineFeed(this); 3749 [[fallthrough]]; 3750 } 3751 case ' ': 3752 case '\t': 3753 case '\f': { 3754 state = P::transition( 3755 mViewSource.get(), 3756 nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, 3757 reconsume, pos); 3758 NS_HTML5_BREAK(afterdoctypepublickeywordloop); 3759 } 3760 case '\"': { 3761 if (P::reportErrors) { 3762 errNoSpaceBetweenDoctypePublicKeywordAndQuote(); 3763 } 3764 clearStrBufBeforeUse(); 3765 state = P::transition( 3766 mViewSource.get(), 3767 nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED, 3768 reconsume, pos); 3769 NS_HTML5_CONTINUE(stateloop); 3770 } 3771 case '\'': { 3772 if (P::reportErrors) { 3773 errNoSpaceBetweenDoctypePublicKeywordAndQuote(); 3774 } 3775 clearStrBufBeforeUse(); 3776 state = P::transition( 3777 mViewSource.get(), 3778 nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED, 3779 reconsume, pos); 3780 NS_HTML5_CONTINUE(stateloop); 3781 } 3782 case '>': { 3783 if (P::reportErrors) { 3784 errExpectedPublicId(); 3785 } 3786 forceQuirks = true; 3787 emitDoctypeToken(pos); 3788 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 3789 reconsume, pos); 3790 if (shouldSuspend) { 3791 NS_HTML5_BREAK(stateloop); 3792 } 3793 NS_HTML5_CONTINUE(stateloop); 3794 } 3795 default: { 3796 bogusDoctype(); 3797 state = P::transition(mViewSource.get(), 3798 nsHtml5Tokenizer::BOGUS_DOCTYPE, 3799 reconsume, pos); 3800 NS_HTML5_CONTINUE(stateloop); 3801 } 3802 } 3803 } 3804 afterdoctypepublickeywordloop_end:; 3805 [[fallthrough]]; 3806 } 3807 case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: { 3808 for (;;) { 3809 if (++pos == endPos) { 3810 NS_HTML5_BREAK(stateloop); 3811 } 3812 c = P::checkChar(this, buf, pos); 3813 switch (c) { 3814 case '\r': { 3815 P::silentCarriageReturn(this); 3816 NS_HTML5_BREAK(stateloop); 3817 } 3818 case '\n': { 3819 P::silentLineFeed(this); 3820 [[fallthrough]]; 3821 } 3822 case ' ': 3823 case '\t': 3824 case '\f': { 3825 continue; 3826 } 3827 case '\"': { 3828 clearStrBufBeforeUse(); 3829 state = P::transition( 3830 mViewSource.get(), 3831 nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED, 3832 reconsume, pos); 3833 NS_HTML5_BREAK(beforedoctypepublicidentifierloop); 3834 } 3835 case '\'': { 3836 clearStrBufBeforeUse(); 3837 state = P::transition( 3838 mViewSource.get(), 3839 nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED, 3840 reconsume, pos); 3841 NS_HTML5_CONTINUE(stateloop); 3842 } 3843 case '>': { 3844 if (P::reportErrors) { 3845 errExpectedPublicId(); 3846 } 3847 forceQuirks = true; 3848 emitDoctypeToken(pos); 3849 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 3850 reconsume, pos); 3851 if (shouldSuspend) { 3852 NS_HTML5_BREAK(stateloop); 3853 } 3854 NS_HTML5_CONTINUE(stateloop); 3855 } 3856 default: { 3857 bogusDoctype(); 3858 state = P::transition(mViewSource.get(), 3859 nsHtml5Tokenizer::BOGUS_DOCTYPE, 3860 reconsume, pos); 3861 NS_HTML5_CONTINUE(stateloop); 3862 } 3863 } 3864 } 3865 beforedoctypepublicidentifierloop_end:; 3866 [[fallthrough]]; 3867 } 3868 case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED: { 3869 for (;;) { 3870 if (++pos == endPos) { 3871 NS_HTML5_BREAK(stateloop); 3872 } 3873 c = P::checkChar(this, buf, pos); 3874 switch (c) { 3875 case '\"': { 3876 publicIdentifier = strBufToString(); 3877 state = P::transition( 3878 mViewSource.get(), 3879 nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER, 3880 reconsume, pos); 3881 NS_HTML5_BREAK(doctypepublicidentifierdoublequotedloop); 3882 } 3883 case '>': { 3884 if (P::reportErrors) { 3885 errGtInPublicId(); 3886 } 3887 forceQuirks = true; 3888 publicIdentifier = strBufToString(); 3889 emitDoctypeToken(pos); 3890 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 3891 reconsume, pos); 3892 if (shouldSuspend) { 3893 NS_HTML5_BREAK(stateloop); 3894 } 3895 NS_HTML5_CONTINUE(stateloop); 3896 } 3897 case '\r': { 3898 appendStrBufCarriageReturn<P>(); 3899 NS_HTML5_BREAK(stateloop); 3900 } 3901 case '\n': { 3902 appendStrBufLineFeed<P>(); 3903 continue; 3904 } 3905 case '\0': { 3906 c = 0xfffd; 3907 [[fallthrough]]; 3908 } 3909 default: { 3910 appendStrBuf(c); 3911 continue; 3912 } 3913 } 3914 } 3915 doctypepublicidentifierdoublequotedloop_end:; 3916 [[fallthrough]]; 3917 } 3918 case AFTER_DOCTYPE_PUBLIC_IDENTIFIER: { 3919 for (;;) { 3920 if (++pos == endPos) { 3921 NS_HTML5_BREAK(stateloop); 3922 } 3923 c = P::checkChar(this, buf, pos); 3924 switch (c) { 3925 case '\r': { 3926 P::silentCarriageReturn(this); 3927 state = P::transition( 3928 mViewSource.get(), 3929 nsHtml5Tokenizer:: 3930 BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS, 3931 reconsume, pos); 3932 NS_HTML5_BREAK(stateloop); 3933 } 3934 case '\n': { 3935 P::silentLineFeed(this); 3936 [[fallthrough]]; 3937 } 3938 case ' ': 3939 case '\t': 3940 case '\f': { 3941 state = P::transition( 3942 mViewSource.get(), 3943 nsHtml5Tokenizer:: 3944 BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS, 3945 reconsume, pos); 3946 NS_HTML5_BREAK(afterdoctypepublicidentifierloop); 3947 } 3948 case '>': { 3949 emitDoctypeToken(pos); 3950 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 3951 reconsume, pos); 3952 if (shouldSuspend) { 3953 NS_HTML5_BREAK(stateloop); 3954 } 3955 NS_HTML5_CONTINUE(stateloop); 3956 } 3957 case '\"': { 3958 if (P::reportErrors) { 3959 errNoSpaceBetweenPublicAndSystemIds(); 3960 } 3961 clearStrBufBeforeUse(); 3962 state = P::transition( 3963 mViewSource.get(), 3964 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, 3965 reconsume, pos); 3966 NS_HTML5_CONTINUE(stateloop); 3967 } 3968 case '\'': { 3969 if (P::reportErrors) { 3970 errNoSpaceBetweenPublicAndSystemIds(); 3971 } 3972 clearStrBufBeforeUse(); 3973 state = P::transition( 3974 mViewSource.get(), 3975 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, 3976 reconsume, pos); 3977 NS_HTML5_CONTINUE(stateloop); 3978 } 3979 default: { 3980 bogusDoctype(); 3981 state = P::transition(mViewSource.get(), 3982 nsHtml5Tokenizer::BOGUS_DOCTYPE, 3983 reconsume, pos); 3984 NS_HTML5_CONTINUE(stateloop); 3985 } 3986 } 3987 } 3988 afterdoctypepublicidentifierloop_end:; 3989 [[fallthrough]]; 3990 } 3991 case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: { 3992 for (;;) { 3993 if (++pos == endPos) { 3994 NS_HTML5_BREAK(stateloop); 3995 } 3996 c = P::checkChar(this, buf, pos); 3997 switch (c) { 3998 case '\r': { 3999 P::silentCarriageReturn(this); 4000 NS_HTML5_BREAK(stateloop); 4001 } 4002 case '\n': { 4003 P::silentLineFeed(this); 4004 [[fallthrough]]; 4005 } 4006 case ' ': 4007 case '\t': 4008 case '\f': { 4009 continue; 4010 } 4011 case '>': { 4012 emitDoctypeToken(pos); 4013 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 4014 reconsume, pos); 4015 if (shouldSuspend) { 4016 NS_HTML5_BREAK(stateloop); 4017 } 4018 NS_HTML5_CONTINUE(stateloop); 4019 } 4020 case '\"': { 4021 clearStrBufBeforeUse(); 4022 state = P::transition( 4023 mViewSource.get(), 4024 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, 4025 reconsume, pos); 4026 NS_HTML5_BREAK(betweendoctypepublicandsystemidentifiersloop); 4027 } 4028 case '\'': { 4029 clearStrBufBeforeUse(); 4030 state = P::transition( 4031 mViewSource.get(), 4032 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, 4033 reconsume, pos); 4034 NS_HTML5_CONTINUE(stateloop); 4035 } 4036 default: { 4037 bogusDoctype(); 4038 state = P::transition(mViewSource.get(), 4039 nsHtml5Tokenizer::BOGUS_DOCTYPE, 4040 reconsume, pos); 4041 NS_HTML5_CONTINUE(stateloop); 4042 } 4043 } 4044 } 4045 betweendoctypepublicandsystemidentifiersloop_end:; 4046 [[fallthrough]]; 4047 } 4048 case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED: { 4049 for (;;) { 4050 if (++pos == endPos) { 4051 NS_HTML5_BREAK(stateloop); 4052 } 4053 c = P::checkChar(this, buf, pos); 4054 switch (c) { 4055 case '\"': { 4056 systemIdentifier = strBufToString(); 4057 state = P::transition( 4058 mViewSource.get(), 4059 nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER, 4060 reconsume, pos); 4061 NS_HTML5_BREAK(doctypesystemidentifierdoublequotedloop); 4062 } 4063 case '>': { 4064 if (P::reportErrors) { 4065 errGtInSystemId(); 4066 } 4067 forceQuirks = true; 4068 systemIdentifier = strBufToString(); 4069 emitDoctypeToken(pos); 4070 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 4071 reconsume, pos); 4072 if (shouldSuspend) { 4073 NS_HTML5_BREAK(stateloop); 4074 } 4075 NS_HTML5_CONTINUE(stateloop); 4076 } 4077 case '\r': { 4078 appendStrBufCarriageReturn<P>(); 4079 NS_HTML5_BREAK(stateloop); 4080 } 4081 case '\n': { 4082 appendStrBufLineFeed<P>(); 4083 continue; 4084 } 4085 case '\0': { 4086 c = 0xfffd; 4087 [[fallthrough]]; 4088 } 4089 default: { 4090 appendStrBuf(c); 4091 continue; 4092 } 4093 } 4094 } 4095 doctypesystemidentifierdoublequotedloop_end:; 4096 [[fallthrough]]; 4097 } 4098 case AFTER_DOCTYPE_SYSTEM_IDENTIFIER: { 4099 for (;;) { 4100 if (++pos == endPos) { 4101 NS_HTML5_BREAK(stateloop); 4102 } 4103 c = P::checkChar(this, buf, pos); 4104 switch (c) { 4105 case '\r': { 4106 P::silentCarriageReturn(this); 4107 NS_HTML5_BREAK(stateloop); 4108 } 4109 case '\n': { 4110 P::silentLineFeed(this); 4111 [[fallthrough]]; 4112 } 4113 case ' ': 4114 case '\t': 4115 case '\f': { 4116 continue; 4117 } 4118 case '>': { 4119 emitDoctypeToken(pos); 4120 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 4121 reconsume, pos); 4122 if (shouldSuspend) { 4123 NS_HTML5_BREAK(stateloop); 4124 } 4125 NS_HTML5_CONTINUE(stateloop); 4126 } 4127 default: { 4128 bogusDoctypeWithoutQuirks(); 4129 state = P::transition(mViewSource.get(), 4130 nsHtml5Tokenizer::BOGUS_DOCTYPE, 4131 reconsume, pos); 4132 NS_HTML5_BREAK(afterdoctypesystemidentifierloop); 4133 } 4134 } 4135 } 4136 afterdoctypesystemidentifierloop_end:; 4137 [[fallthrough]]; 4138 } 4139 case BOGUS_DOCTYPE: { 4140 for (;;) { 4141 if (reconsume) { 4142 reconsume = false; 4143 } else { 4144 if (++pos == endPos) { 4145 NS_HTML5_BREAK(stateloop); 4146 } 4147 c = P::checkChar(this, buf, pos); 4148 } 4149 switch (c) { 4150 case '>': { 4151 emitDoctypeToken(pos); 4152 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 4153 reconsume, pos); 4154 if (shouldSuspend) { 4155 NS_HTML5_BREAK(stateloop); 4156 } 4157 NS_HTML5_CONTINUE(stateloop); 4158 } 4159 case '\r': { 4160 P::silentCarriageReturn(this); 4161 NS_HTML5_BREAK(stateloop); 4162 } 4163 case '\n': { 4164 P::silentLineFeed(this); 4165 [[fallthrough]]; 4166 } 4167 default: { 4168 continue; 4169 } 4170 } 4171 } 4172 } 4173 case DOCTYPE_YSTEM: { 4174 for (;;) { 4175 if (++pos == endPos) { 4176 NS_HTML5_BREAK(stateloop); 4177 } 4178 c = P::checkChar(this, buf, pos); 4179 if (index < 5) { 4180 char16_t folded = c; 4181 if (c >= 'A' && c <= 'Z') { 4182 folded += 0x20; 4183 } 4184 if (folded != nsHtml5Tokenizer::YSTEM[index]) { 4185 bogusDoctype(); 4186 reconsume = true; 4187 state = P::transition(mViewSource.get(), 4188 nsHtml5Tokenizer::BOGUS_DOCTYPE, 4189 reconsume, pos); 4190 NS_HTML5_CONTINUE(stateloop); 4191 } 4192 index++; 4193 NS_HTML5_CONTINUE(stateloop); 4194 } else { 4195 reconsume = true; 4196 state = 4197 P::transition(mViewSource.get(), 4198 nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_KEYWORD, 4199 reconsume, pos); 4200 NS_HTML5_BREAK(doctypeystemloop); 4201 } 4202 } 4203 doctypeystemloop_end:; 4204 [[fallthrough]]; 4205 } 4206 case AFTER_DOCTYPE_SYSTEM_KEYWORD: { 4207 for (;;) { 4208 if (reconsume) { 4209 reconsume = false; 4210 } else { 4211 if (++pos == endPos) { 4212 NS_HTML5_BREAK(stateloop); 4213 } 4214 c = P::checkChar(this, buf, pos); 4215 } 4216 switch (c) { 4217 case '\r': { 4218 P::silentCarriageReturn(this); 4219 state = P::transition( 4220 mViewSource.get(), 4221 nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, 4222 reconsume, pos); 4223 NS_HTML5_BREAK(stateloop); 4224 } 4225 case '\n': { 4226 P::silentLineFeed(this); 4227 [[fallthrough]]; 4228 } 4229 case ' ': 4230 case '\t': 4231 case '\f': { 4232 state = P::transition( 4233 mViewSource.get(), 4234 nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, 4235 reconsume, pos); 4236 NS_HTML5_BREAK(afterdoctypesystemkeywordloop); 4237 } 4238 case '\"': { 4239 if (P::reportErrors) { 4240 errNoSpaceBetweenDoctypeSystemKeywordAndQuote(); 4241 } 4242 clearStrBufBeforeUse(); 4243 state = P::transition( 4244 mViewSource.get(), 4245 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, 4246 reconsume, pos); 4247 NS_HTML5_CONTINUE(stateloop); 4248 } 4249 case '\'': { 4250 if (P::reportErrors) { 4251 errNoSpaceBetweenDoctypeSystemKeywordAndQuote(); 4252 } 4253 clearStrBufBeforeUse(); 4254 state = P::transition( 4255 mViewSource.get(), 4256 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, 4257 reconsume, pos); 4258 NS_HTML5_CONTINUE(stateloop); 4259 } 4260 case '>': { 4261 if (P::reportErrors) { 4262 errExpectedPublicId(); 4263 } 4264 forceQuirks = true; 4265 emitDoctypeToken(pos); 4266 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 4267 reconsume, pos); 4268 if (shouldSuspend) { 4269 NS_HTML5_BREAK(stateloop); 4270 } 4271 NS_HTML5_CONTINUE(stateloop); 4272 } 4273 default: { 4274 bogusDoctype(); 4275 state = P::transition(mViewSource.get(), 4276 nsHtml5Tokenizer::BOGUS_DOCTYPE, 4277 reconsume, pos); 4278 NS_HTML5_CONTINUE(stateloop); 4279 } 4280 } 4281 } 4282 afterdoctypesystemkeywordloop_end:; 4283 [[fallthrough]]; 4284 } 4285 case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: { 4286 for (;;) { 4287 if (++pos == endPos) { 4288 NS_HTML5_BREAK(stateloop); 4289 } 4290 c = P::checkChar(this, buf, pos); 4291 switch (c) { 4292 case '\r': { 4293 P::silentCarriageReturn(this); 4294 NS_HTML5_BREAK(stateloop); 4295 } 4296 case '\n': { 4297 P::silentLineFeed(this); 4298 [[fallthrough]]; 4299 } 4300 case ' ': 4301 case '\t': 4302 case '\f': { 4303 continue; 4304 } 4305 case '\"': { 4306 clearStrBufBeforeUse(); 4307 state = P::transition( 4308 mViewSource.get(), 4309 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, 4310 reconsume, pos); 4311 NS_HTML5_CONTINUE(stateloop); 4312 } 4313 case '\'': { 4314 clearStrBufBeforeUse(); 4315 state = P::transition( 4316 mViewSource.get(), 4317 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, 4318 reconsume, pos); 4319 NS_HTML5_BREAK(beforedoctypesystemidentifierloop); 4320 } 4321 case '>': { 4322 if (P::reportErrors) { 4323 errExpectedSystemId(); 4324 } 4325 forceQuirks = true; 4326 emitDoctypeToken(pos); 4327 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 4328 reconsume, pos); 4329 if (shouldSuspend) { 4330 NS_HTML5_BREAK(stateloop); 4331 } 4332 NS_HTML5_CONTINUE(stateloop); 4333 } 4334 default: { 4335 bogusDoctype(); 4336 state = P::transition(mViewSource.get(), 4337 nsHtml5Tokenizer::BOGUS_DOCTYPE, 4338 reconsume, pos); 4339 NS_HTML5_CONTINUE(stateloop); 4340 } 4341 } 4342 } 4343 beforedoctypesystemidentifierloop_end:; 4344 [[fallthrough]]; 4345 } 4346 case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: { 4347 for (;;) { 4348 if (++pos == endPos) { 4349 NS_HTML5_BREAK(stateloop); 4350 } 4351 c = P::checkChar(this, buf, pos); 4352 switch (c) { 4353 case '\'': { 4354 systemIdentifier = strBufToString(); 4355 state = P::transition( 4356 mViewSource.get(), 4357 nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER, 4358 reconsume, pos); 4359 NS_HTML5_CONTINUE(stateloop); 4360 } 4361 case '>': { 4362 if (P::reportErrors) { 4363 errGtInSystemId(); 4364 } 4365 forceQuirks = true; 4366 systemIdentifier = strBufToString(); 4367 emitDoctypeToken(pos); 4368 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 4369 reconsume, pos); 4370 if (shouldSuspend) { 4371 NS_HTML5_BREAK(stateloop); 4372 } 4373 NS_HTML5_CONTINUE(stateloop); 4374 } 4375 case '\r': { 4376 appendStrBufCarriageReturn<P>(); 4377 NS_HTML5_BREAK(stateloop); 4378 } 4379 case '\n': { 4380 appendStrBufLineFeed<P>(); 4381 continue; 4382 } 4383 case '\0': { 4384 c = 0xfffd; 4385 [[fallthrough]]; 4386 } 4387 default: { 4388 appendStrBuf(c); 4389 continue; 4390 } 4391 } 4392 } 4393 } 4394 case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: { 4395 for (;;) { 4396 if (++pos == endPos) { 4397 NS_HTML5_BREAK(stateloop); 4398 } 4399 c = P::checkChar(this, buf, pos); 4400 switch (c) { 4401 case '\'': { 4402 publicIdentifier = strBufToString(); 4403 state = P::transition( 4404 mViewSource.get(), 4405 nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER, 4406 reconsume, pos); 4407 NS_HTML5_CONTINUE(stateloop); 4408 } 4409 case '>': { 4410 if (P::reportErrors) { 4411 errGtInPublicId(); 4412 } 4413 forceQuirks = true; 4414 publicIdentifier = strBufToString(); 4415 emitDoctypeToken(pos); 4416 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 4417 reconsume, pos); 4418 if (shouldSuspend) { 4419 NS_HTML5_BREAK(stateloop); 4420 } 4421 NS_HTML5_CONTINUE(stateloop); 4422 } 4423 case '\r': { 4424 appendStrBufCarriageReturn<P>(); 4425 NS_HTML5_BREAK(stateloop); 4426 } 4427 case '\n': { 4428 appendStrBufLineFeed<P>(); 4429 continue; 4430 } 4431 case '\0': { 4432 c = 0xfffd; 4433 [[fallthrough]]; 4434 } 4435 default: { 4436 appendStrBuf(c); 4437 continue; 4438 } 4439 } 4440 } 4441 } 4442 case PROCESSING_INSTRUCTION: { 4443 for (;;) { 4444 if (++pos == endPos) { 4445 NS_HTML5_BREAK(stateloop); 4446 } 4447 c = P::checkChar(this, buf, pos); 4448 switch (c) { 4449 case '\?': { 4450 state = P::transition( 4451 mViewSource.get(), 4452 nsHtml5Tokenizer::PROCESSING_INSTRUCTION_QUESTION_MARK, 4453 reconsume, pos); 4454 NS_HTML5_BREAK(processinginstructionloop); 4455 } 4456 default: { 4457 continue; 4458 } 4459 } 4460 } 4461 processinginstructionloop_end:; 4462 [[fallthrough]]; 4463 } 4464 case PROCESSING_INSTRUCTION_QUESTION_MARK: { 4465 if (++pos == endPos) { 4466 NS_HTML5_BREAK(stateloop); 4467 } 4468 c = P::checkChar(this, buf, pos); 4469 switch (c) { 4470 case '>': { 4471 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA, 4472 reconsume, pos); 4473 suspendIfRequestedAfterCurrentNonTextToken(); 4474 if (shouldSuspend) { 4475 NS_HTML5_BREAK(stateloop); 4476 } 4477 NS_HTML5_CONTINUE(stateloop); 4478 } 4479 default: { 4480 state = P::transition(mViewSource.get(), 4481 nsHtml5Tokenizer::PROCESSING_INSTRUCTION, 4482 reconsume, pos); 4483 NS_HTML5_CONTINUE(stateloop); 4484 } 4485 } 4486 } 4487 } 4488 } 4489 stateloop_end:; 4490 flushChars(buf, pos); 4491 stateSave = state; 4492 returnStateSave = returnState; 4493 return pos; 4494 } 4495 4496 void initDoctypeFields(); 4497 template <class P> 4498 inline void adjustDoubleHyphenAndAppendToStrBufCarriageReturn() { 4499 P::silentCarriageReturn(this); 4500 adjustDoubleHyphenAndAppendToStrBufAndErr('\n', false); 4501 } 4502 4503 template <class P> 4504 inline void adjustDoubleHyphenAndAppendToStrBufLineFeed() { 4505 P::silentLineFeed(this); 4506 adjustDoubleHyphenAndAppendToStrBufAndErr('\n', false); 4507 } 4508 4509 template <class P> 4510 inline void appendStrBufLineFeed() { 4511 P::silentLineFeed(this); 4512 appendStrBuf('\n'); 4513 } 4514 4515 template <class P> 4516 inline void appendStrBufCarriageReturn() { 4517 P::silentCarriageReturn(this); 4518 appendStrBuf('\n'); 4519 } 4520 4521 template <class P> 4522 inline void emitCarriageReturn(char16_t* buf, int32_t pos) { 4523 P::silentCarriageReturn(this); 4524 flushChars(buf, pos); 4525 tokenHandler->characters(nsHtml5Tokenizer::LF, 0, 1); 4526 cstart = INT32_MAX; 4527 } 4528 4529 void emitReplacementCharacter(char16_t* buf, int32_t pos); 4530 void maybeEmitReplacementCharacter(char16_t* buf, int32_t pos); 4531 void emitPlaintextReplacementCharacter(char16_t* buf, int32_t pos); 4532 inline void setAdditionalAndRememberAmpersandLocation(char16_t add) { 4533 additional = add; 4534 } 4535 4536 void bogusDoctype(); 4537 void bogusDoctypeWithoutQuirks(); 4538 void handleNcrValue(int32_t returnState); 4539 4540 public: 4541 void eof(); 4542 4543 private: 4544 void emitDoctypeToken(int32_t pos); 4545 inline void suspendIfRequestedAfterCurrentNonTextToken() { 4546 if (suspendAfterCurrentNonTextToken) { 4547 suspendAfterCurrentNonTextToken = false; 4548 shouldSuspend = true; 4549 } 4550 } 4551 4552 void suspendAfterCurrentTokenIfNotInText(); 4553 bool suspensionAfterCurrentNonTextTokenPending(); 4554 4555 public: 4556 bool internalEncodingDeclaration(nsHtml5String internalCharset); 4557 4558 private: 4559 inline void emitOrAppendTwo(const char16_t* val, int32_t returnState) { 4560 if ((returnState & DATA_AND_RCDATA_MASK)) { 4561 appendStrBuf(val[0]); 4562 appendStrBuf(val[1]); 4563 } else { 4564 tokenHandler->characters(val, 0, 2); 4565 } 4566 } 4567 4568 inline void emitOrAppendOne(const char16_t* val, int32_t returnState) { 4569 if ((returnState & DATA_AND_RCDATA_MASK)) { 4570 appendStrBuf(val[0]); 4571 } else { 4572 tokenHandler->characters(val, 0, 1); 4573 } 4574 } 4575 4576 public: 4577 void end(); 4578 inline void requestSuspension() { shouldSuspend = true; } 4579 4580 inline bool isInDataState() { return (stateSave == DATA); } 4581 4582 void resetToDataState(); 4583 void loadState(nsHtml5Tokenizer* other); 4584 void initializeWithoutStarting(); 4585 void setEncodingDeclarationHandler( 4586 nsHtml5StreamParser* encodingDeclarationHandler); 4587 ~nsHtml5Tokenizer(); 4588 static void initializeStatics(); 4589 static void releaseStatics(); 4590 4591 #include "nsHtml5TokenizerHSupplement.h" 4592 }; 4593 4594 #endif