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