Coverage Report

Created: 2018-09-25 14:53

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