Line data Source code
1 : /* This Source Code Form is subject to the terms of the Mozilla Public
2 : * License, v. 2.0. If a copy of the MPL was not distributed with this
3 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 :
5 : #include "mozilla/Likely.h"
6 :
7 : // INT32_MAX is (2^31)-1. Therefore, the highest power-of-two that fits
8 : // is 2^30. Note that this is counting char16_t units. The underlying
9 : // bytes will be twice that, but they fit even in 32-bit size_t even
10 : // if a contiguous chunk of memory of that size is pretty unlikely to
11 : // be available on a 32-bit system.
12 : #define MAX_POWER_OF_TWO_IN_INT32 0x40000000
13 :
14 : bool
15 9 : nsHtml5Tokenizer::EnsureBufferSpace(int32_t aLength)
16 : {
17 9 : MOZ_RELEASE_ASSERT(aLength >= 0, "Negative length.");
18 9 : if (aLength > MAX_POWER_OF_TWO_IN_INT32) {
19 : // Can't happen when loading from network.
20 0 : return false;
21 : }
22 9 : CheckedInt<int32_t> worstCase(strBufLen);
23 9 : worstCase += aLength;
24 9 : worstCase += charRefBufLen;
25 : // Add 2 to account for emissions of LT_GT, LT_SOLIDUS and RSQB_RSQB.
26 : // Adding to the general worst case instead of only the
27 : // TreeBuilder-exposed worst case to avoid re-introducing a bug when
28 : // unifying the tokenizer and tree builder buffers in the future.
29 9 : worstCase += 2;
30 9 : if (!worstCase.isValid()) {
31 0 : return false;
32 : }
33 9 : if (worstCase.value() > MAX_POWER_OF_TWO_IN_INT32) {
34 0 : return false;
35 : }
36 : // TODO: Unify nsHtml5Tokenizer::strBuf and nsHtml5TreeBuilder::charBuffer
37 : // so that the call below becomes unnecessary.
38 9 : if (!tokenHandler->EnsureBufferSpace(worstCase.value())) {
39 0 : return false;
40 : }
41 9 : if (!strBuf) {
42 2 : if (worstCase.value() < MAX_POWER_OF_TWO_IN_INT32) {
43 : // Add one to round to the next power of two to avoid immediate
44 : // reallocation once there are a few characters in the buffer.
45 2 : worstCase += 1;
46 : }
47 2 : strBuf = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
48 2 : if (!strBuf) {
49 0 : return false;
50 : }
51 7 : } else if (worstCase.value() > strBuf.length) {
52 0 : jArray<char16_t,int32_t> newBuf = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
53 0 : if (!newBuf) {
54 0 : return false;
55 : }
56 0 : memcpy(newBuf, strBuf, sizeof(char16_t) * size_t(strBufLen));
57 0 : strBuf = newBuf;
58 : }
59 9 : return true;
60 : }
61 :
62 : void
63 0 : nsHtml5Tokenizer::StartPlainText()
64 : {
65 0 : stateSave = nsHtml5Tokenizer::PLAINTEXT;
66 0 : }
67 :
68 : void
69 0 : nsHtml5Tokenizer::EnableViewSource(nsHtml5Highlighter* aHighlighter)
70 : {
71 0 : mViewSource = aHighlighter;
72 0 : }
73 :
74 : bool
75 0 : nsHtml5Tokenizer::FlushViewSource()
76 : {
77 0 : return mViewSource->FlushOps();
78 : }
79 :
80 : void
81 0 : nsHtml5Tokenizer::StartViewSource(const nsAutoString& aTitle)
82 : {
83 0 : mViewSource->Start(aTitle);
84 0 : }
85 :
86 : void
87 0 : nsHtml5Tokenizer::EndViewSource()
88 : {
89 0 : mViewSource->End();
90 0 : }
91 :
92 : void
93 0 : nsHtml5Tokenizer::errWarnLtSlashInRcdata()
94 : {
95 0 : }
96 :
97 : // The null checks below annotated MOZ_LIKELY are not actually necessary.
98 :
99 : void
100 0 : nsHtml5Tokenizer::errUnquotedAttributeValOrNull(char16_t c)
101 : {
102 0 : if (MOZ_LIKELY(mViewSource)) {
103 0 : switch (c) {
104 : case '<':
105 0 : mViewSource->AddErrorToCurrentNode("errUnquotedAttributeLt");
106 0 : return;
107 : case '`':
108 0 : mViewSource->AddErrorToCurrentNode("errUnquotedAttributeGrave");
109 0 : return;
110 : case '\'':
111 : case '"':
112 0 : mViewSource->AddErrorToCurrentNode("errUnquotedAttributeQuote");
113 0 : return;
114 : case '=':
115 0 : mViewSource->AddErrorToCurrentNode("errUnquotedAttributeEquals");
116 0 : return;
117 : }
118 : }
119 : }
120 :
121 : void
122 0 : nsHtml5Tokenizer::errLtOrEqualsOrGraveInUnquotedAttributeOrNull(char16_t c)
123 : {
124 0 : if (MOZ_LIKELY(mViewSource)) {
125 0 : switch (c) {
126 : case '=':
127 0 : mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartEquals");
128 0 : return;
129 : case '<':
130 0 : mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartLt");
131 0 : return;
132 : case '`':
133 0 : mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartGrave");
134 0 : return;
135 : }
136 : }
137 : }
138 :
139 : void
140 0 : nsHtml5Tokenizer::errBadCharBeforeAttributeNameOrNull(char16_t c)
141 : {
142 0 : if (MOZ_LIKELY(mViewSource)) {
143 0 : if (c == '<') {
144 0 : mViewSource->AddErrorToCurrentNode("errBadCharBeforeAttributeNameLt");
145 0 : } else if (c == '=') {
146 0 : errEqualsSignBeforeAttributeName();
147 0 : } else if (c != 0xFFFD) {
148 0 : errQuoteBeforeAttributeName(c);
149 : }
150 : }
151 0 : }
152 :
153 : void
154 0 : nsHtml5Tokenizer::errBadCharAfterLt(char16_t c)
155 : {
156 0 : if (MOZ_LIKELY(mViewSource)) {
157 0 : mViewSource->AddErrorToCurrentNode("errBadCharAfterLt");
158 : }
159 0 : }
160 :
161 : void
162 0 : nsHtml5Tokenizer::errQuoteOrLtInAttributeNameOrNull(char16_t c)
163 : {
164 0 : if (MOZ_LIKELY(mViewSource)) {
165 0 : if (c == '<') {
166 0 : mViewSource->AddErrorToCurrentNode("errLtInAttributeName");
167 0 : } else if (c != 0xFFFD) {
168 0 : mViewSource->AddErrorToCurrentNode("errQuoteInAttributeName");
169 : }
170 : }
171 0 : }
172 :
173 : void
174 11 : nsHtml5Tokenizer::maybeErrAttributesOnEndTag(nsHtml5HtmlAttributes* attrs)
175 : {
176 11 : if (mViewSource && attrs->getLength() != 0) {
177 : /*
178 : * When an end tag token is emitted with attributes, that is a parse
179 : * error.
180 : */
181 0 : mViewSource->AddErrorToCurrentRun("maybeErrAttributesOnEndTag");
182 : }
183 11 : }
184 :
185 : void
186 24 : nsHtml5Tokenizer::maybeErrSlashInEndTag(bool selfClosing)
187 : {
188 24 : if (mViewSource && selfClosing && endTag) {
189 0 : mViewSource->AddErrorToCurrentSlash("maybeErrSlashInEndTag");
190 : }
191 24 : }
192 :
193 : char16_t
194 0 : nsHtml5Tokenizer::errNcrNonCharacter(char16_t ch)
195 : {
196 0 : if (MOZ_UNLIKELY(mViewSource)) {
197 0 : mViewSource->AddErrorToCurrentNode("errNcrNonCharacter");
198 : }
199 0 : return ch;
200 : }
201 :
202 : void
203 0 : nsHtml5Tokenizer::errAstralNonCharacter(int32_t ch)
204 : {
205 0 : if (MOZ_UNLIKELY(mViewSource)) {
206 0 : mViewSource->AddErrorToCurrentNode("errNcrNonCharacter");
207 : }
208 0 : }
209 :
210 : char16_t
211 0 : nsHtml5Tokenizer::errNcrControlChar(char16_t ch)
212 : {
213 0 : if (MOZ_UNLIKELY(mViewSource)) {
214 0 : mViewSource->AddErrorToCurrentNode("errNcrControlChar");
215 : }
216 0 : return ch;
217 : }
218 :
219 : void
220 0 : nsHtml5Tokenizer::errGarbageAfterLtSlash()
221 : {
222 0 : if (MOZ_LIKELY(mViewSource)) {
223 0 : mViewSource->AddErrorToCurrentNode("errGarbageAfterLtSlash");
224 : }
225 0 : }
226 :
227 : void
228 0 : nsHtml5Tokenizer::errLtSlashGt()
229 : {
230 0 : if (MOZ_LIKELY(mViewSource)) {
231 0 : mViewSource->AddErrorToCurrentNode("errLtSlashGt");
232 : }
233 0 : }
234 :
235 : void
236 0 : nsHtml5Tokenizer::errCharRefLacksSemicolon()
237 : {
238 0 : if (MOZ_UNLIKELY(mViewSource)) {
239 0 : mViewSource->AddErrorToCurrentNode("errCharRefLacksSemicolon");
240 : }
241 0 : }
242 :
243 : void
244 0 : nsHtml5Tokenizer::errNoDigitsInNCR()
245 : {
246 0 : if (MOZ_UNLIKELY(mViewSource)) {
247 0 : mViewSource->AddErrorToCurrentNode("errNoDigitsInNCR");
248 : }
249 0 : }
250 :
251 : void
252 0 : nsHtml5Tokenizer::errGtInSystemId()
253 : {
254 0 : if (MOZ_LIKELY(mViewSource)) {
255 0 : mViewSource->AddErrorToCurrentNode("errGtInSystemId");
256 : }
257 0 : }
258 :
259 : void
260 0 : nsHtml5Tokenizer::errGtInPublicId()
261 : {
262 0 : if (MOZ_LIKELY(mViewSource)) {
263 0 : mViewSource->AddErrorToCurrentNode("errGtInPublicId");
264 : }
265 0 : }
266 :
267 : void
268 0 : nsHtml5Tokenizer::errNamelessDoctype()
269 : {
270 0 : if (MOZ_LIKELY(mViewSource)) {
271 0 : mViewSource->AddErrorToCurrentNode("errNamelessDoctype");
272 : }
273 0 : }
274 :
275 : void
276 0 : nsHtml5Tokenizer::errConsecutiveHyphens()
277 : {
278 0 : if (MOZ_UNLIKELY(mViewSource)) {
279 0 : mViewSource->AddErrorToCurrentNode("errConsecutiveHyphens");
280 : }
281 0 : }
282 :
283 : void
284 0 : nsHtml5Tokenizer::errPrematureEndOfComment()
285 : {
286 0 : if (MOZ_LIKELY(mViewSource)) {
287 0 : mViewSource->AddErrorToCurrentNode("errPrematureEndOfComment");
288 : }
289 0 : }
290 :
291 : void
292 0 : nsHtml5Tokenizer::errBogusComment()
293 : {
294 0 : if (MOZ_UNLIKELY(mViewSource)) {
295 0 : mViewSource->AddErrorToCurrentNode("errBogusComment");
296 : }
297 0 : }
298 :
299 : void
300 0 : nsHtml5Tokenizer::errSlashNotFollowedByGt()
301 : {
302 0 : if (MOZ_LIKELY(mViewSource)) {
303 0 : mViewSource->AddErrorToCurrentSlash("errSlashNotFollowedByGt");
304 : }
305 0 : }
306 :
307 : void
308 0 : nsHtml5Tokenizer::errNoSpaceBetweenAttributes()
309 : {
310 0 : if (MOZ_LIKELY(mViewSource)) {
311 0 : mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenAttributes");
312 : }
313 0 : }
314 :
315 : void
316 0 : nsHtml5Tokenizer::errAttributeValueMissing()
317 : {
318 0 : if (MOZ_LIKELY(mViewSource)) {
319 0 : mViewSource->AddErrorToCurrentNode("errAttributeValueMissing");
320 : }
321 0 : }
322 :
323 : void
324 0 : nsHtml5Tokenizer::errEqualsSignBeforeAttributeName()
325 : {
326 0 : if (MOZ_LIKELY(mViewSource)) {
327 0 : mViewSource->AddErrorToCurrentNode("errEqualsSignBeforeAttributeName");
328 : }
329 0 : }
330 :
331 : void
332 0 : nsHtml5Tokenizer::errLtGt()
333 : {
334 0 : if (MOZ_LIKELY(mViewSource)) {
335 0 : mViewSource->AddErrorToCurrentNode("errLtGt");
336 : }
337 0 : }
338 :
339 : void
340 0 : nsHtml5Tokenizer::errProcessingInstruction()
341 : {
342 0 : if (MOZ_LIKELY(mViewSource)) {
343 0 : mViewSource->AddErrorToCurrentNode("errProcessingInstruction");
344 : }
345 0 : }
346 :
347 : void
348 0 : nsHtml5Tokenizer::errUnescapedAmpersandInterpretedAsCharacterReference()
349 : {
350 0 : if (MOZ_UNLIKELY(mViewSource)) {
351 0 : mViewSource->AddErrorToCurrentAmpersand("errUnescapedAmpersandInterpretedAsCharacterReference");
352 : }
353 0 : }
354 :
355 : void
356 0 : nsHtml5Tokenizer::errNotSemicolonTerminated()
357 : {
358 0 : if (MOZ_UNLIKELY(mViewSource)) {
359 0 : mViewSource->AddErrorToCurrentNode("errNotSemicolonTerminated");
360 : }
361 0 : }
362 :
363 : void
364 0 : nsHtml5Tokenizer::errNoNamedCharacterMatch()
365 : {
366 0 : if (MOZ_UNLIKELY(mViewSource)) {
367 0 : mViewSource->AddErrorToCurrentAmpersand("errNoNamedCharacterMatch");
368 : }
369 0 : }
370 :
371 : void
372 0 : nsHtml5Tokenizer::errQuoteBeforeAttributeName(char16_t c)
373 : {
374 0 : if (MOZ_LIKELY(mViewSource)) {
375 0 : mViewSource->AddErrorToCurrentNode("errQuoteBeforeAttributeName");
376 : }
377 0 : }
378 :
379 : void
380 0 : nsHtml5Tokenizer::errExpectedPublicId()
381 : {
382 0 : if (MOZ_LIKELY(mViewSource)) {
383 0 : mViewSource->AddErrorToCurrentNode("errExpectedPublicId");
384 : }
385 0 : }
386 :
387 : void
388 0 : nsHtml5Tokenizer::errBogusDoctype()
389 : {
390 0 : if (MOZ_UNLIKELY(mViewSource)) {
391 0 : mViewSource->AddErrorToCurrentNode("errBogusDoctype");
392 : }
393 0 : }
394 :
395 : void
396 0 : nsHtml5Tokenizer::errNcrSurrogate()
397 : {
398 0 : if (MOZ_UNLIKELY(mViewSource)) {
399 0 : mViewSource->AddErrorToCurrentNode("errNcrSurrogate");
400 : }
401 0 : }
402 :
403 : void
404 0 : nsHtml5Tokenizer::errNcrCr()
405 : {
406 0 : if (MOZ_UNLIKELY(mViewSource)) {
407 0 : mViewSource->AddErrorToCurrentNode("errNcrCr");
408 : }
409 0 : }
410 :
411 : void
412 0 : nsHtml5Tokenizer::errNcrInC1Range()
413 : {
414 0 : if (MOZ_UNLIKELY(mViewSource)) {
415 0 : mViewSource->AddErrorToCurrentNode("errNcrInC1Range");
416 : }
417 0 : }
418 :
419 : void
420 0 : nsHtml5Tokenizer::errEofInPublicId()
421 : {
422 0 : if (MOZ_UNLIKELY(mViewSource)) {
423 0 : mViewSource->AddErrorToCurrentRun("errEofInPublicId");
424 : }
425 0 : }
426 :
427 : void
428 0 : nsHtml5Tokenizer::errEofInComment()
429 : {
430 0 : if (MOZ_UNLIKELY(mViewSource)) {
431 0 : mViewSource->AddErrorToCurrentRun("errEofInComment");
432 : }
433 0 : }
434 :
435 : void
436 0 : nsHtml5Tokenizer::errEofInDoctype()
437 : {
438 0 : if (MOZ_UNLIKELY(mViewSource)) {
439 0 : mViewSource->AddErrorToCurrentRun("errEofInDoctype");
440 : }
441 0 : }
442 :
443 : void
444 0 : nsHtml5Tokenizer::errEofInAttributeValue()
445 : {
446 0 : if (MOZ_UNLIKELY(mViewSource)) {
447 0 : mViewSource->AddErrorToCurrentRun("errEofInAttributeValue");
448 : }
449 0 : }
450 :
451 : void
452 0 : nsHtml5Tokenizer::errEofInAttributeName()
453 : {
454 0 : if (MOZ_UNLIKELY(mViewSource)) {
455 0 : mViewSource->AddErrorToCurrentRun("errEofInAttributeName");
456 : }
457 0 : }
458 :
459 : void
460 0 : nsHtml5Tokenizer::errEofWithoutGt()
461 : {
462 0 : if (MOZ_UNLIKELY(mViewSource)) {
463 0 : mViewSource->AddErrorToCurrentRun("errEofWithoutGt");
464 : }
465 0 : }
466 :
467 : void
468 0 : nsHtml5Tokenizer::errEofInTagName()
469 : {
470 0 : if (MOZ_UNLIKELY(mViewSource)) {
471 0 : mViewSource->AddErrorToCurrentRun("errEofInTagName");
472 : }
473 0 : }
474 :
475 : void
476 0 : nsHtml5Tokenizer::errEofInEndTag()
477 : {
478 0 : if (MOZ_UNLIKELY(mViewSource)) {
479 0 : mViewSource->AddErrorToCurrentRun("errEofInEndTag");
480 : }
481 0 : }
482 :
483 : void
484 0 : nsHtml5Tokenizer::errEofAfterLt()
485 : {
486 0 : if (MOZ_UNLIKELY(mViewSource)) {
487 0 : mViewSource->AddErrorToCurrentRun("errEofAfterLt");
488 : }
489 0 : }
490 :
491 : void
492 0 : nsHtml5Tokenizer::errNcrOutOfRange()
493 : {
494 0 : if (MOZ_UNLIKELY(mViewSource)) {
495 0 : mViewSource->AddErrorToCurrentNode("errNcrOutOfRange");
496 : }
497 0 : }
498 :
499 : void
500 0 : nsHtml5Tokenizer::errNcrUnassigned()
501 : {
502 0 : if (MOZ_UNLIKELY(mViewSource)) {
503 0 : mViewSource->AddErrorToCurrentNode("errNcrUnassigned");
504 : }
505 0 : }
506 :
507 : void
508 0 : nsHtml5Tokenizer::errDuplicateAttribute()
509 : {
510 0 : if (MOZ_UNLIKELY(mViewSource)) {
511 0 : mViewSource->AddErrorToCurrentNode("errDuplicateAttribute");
512 : }
513 0 : }
514 :
515 : void
516 0 : nsHtml5Tokenizer::errEofInSystemId()
517 : {
518 0 : if (MOZ_UNLIKELY(mViewSource)) {
519 0 : mViewSource->AddErrorToCurrentRun("errEofInSystemId");
520 : }
521 0 : }
522 :
523 : void
524 0 : nsHtml5Tokenizer::errExpectedSystemId()
525 : {
526 0 : if (MOZ_LIKELY(mViewSource)) {
527 0 : mViewSource->AddErrorToCurrentNode("errExpectedSystemId");
528 : }
529 0 : }
530 :
531 : void
532 0 : nsHtml5Tokenizer::errMissingSpaceBeforeDoctypeName()
533 : {
534 0 : if (MOZ_LIKELY(mViewSource)) {
535 0 : mViewSource->AddErrorToCurrentNode("errMissingSpaceBeforeDoctypeName");
536 : }
537 0 : }
538 :
539 : void
540 0 : nsHtml5Tokenizer::errHyphenHyphenBang()
541 : {
542 0 : if (MOZ_LIKELY(mViewSource)) {
543 0 : mViewSource->AddErrorToCurrentNode("errHyphenHyphenBang");
544 : }
545 0 : }
546 :
547 : void
548 0 : nsHtml5Tokenizer::errNcrControlChar()
549 : {
550 0 : if (MOZ_UNLIKELY(mViewSource)) {
551 0 : mViewSource->AddErrorToCurrentNode("errNcrControlChar");
552 : }
553 0 : }
554 :
555 : void
556 0 : nsHtml5Tokenizer::errNcrZero()
557 : {
558 0 : if (MOZ_UNLIKELY(mViewSource)) {
559 0 : mViewSource->AddErrorToCurrentNode("errNcrZero");
560 : }
561 0 : }
562 :
563 : void
564 0 : nsHtml5Tokenizer::errNoSpaceBetweenDoctypeSystemKeywordAndQuote()
565 : {
566 0 : if (MOZ_LIKELY(mViewSource)) {
567 0 : mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenDoctypeSystemKeywordAndQuote");
568 : }
569 0 : }
570 :
571 : void
572 0 : nsHtml5Tokenizer::errNoSpaceBetweenPublicAndSystemIds()
573 : {
574 0 : if (MOZ_LIKELY(mViewSource)) {
575 0 : mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenPublicAndSystemIds");
576 : }
577 0 : }
578 :
579 : void
580 0 : nsHtml5Tokenizer::errNoSpaceBetweenDoctypePublicKeywordAndQuote()
581 : {
582 0 : if (MOZ_LIKELY(mViewSource)) {
583 0 : mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenDoctypePublicKeywordAndQuote");
584 : }
585 0 : }
|