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