Coverage Report

Created: 2024-02-21 06:19

/src/cmark/src/houdini_html_e.c
Line
Count
Source (jump to first uncovered line)
1
#include <assert.h>
2
#include <stdio.h>
3
#include <string.h>
4
5
#include "houdini.h"
6
7
#if !defined(__has_builtin)
8
# define __has_builtin(b) 0
9
#endif
10
11
#if !__has_builtin(__builtin_expect)
12
# define __builtin_expect(e, v) (e)
13
#endif
14
15
#define likely(e) __builtin_expect((e), 1)
16
24.4M
#define unlikely(e) __builtin_expect((e), 0)
17
18
/**
19
 * According to the OWASP rules:
20
 *
21
 * & --> &amp;
22
 * < --> &lt;
23
 * > --> &gt;
24
 * " --> &quot;
25
 * ' --> &#x27;     &apos; is not recommended
26
 * / --> &#x2F;     forward slash is included as it helps end an HTML entity
27
 *
28
 */
29
static const char HTML_ESCAPE_TABLE[] = {
30
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 4,
32
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
35
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
36
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
37
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
38
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41
};
42
43
static const char *HTML_ESCAPES[] = {"",      "&quot;", "&amp;", "&#39;",
44
                                     "&#47;", "&lt;",   "&gt;"};
45
46
int houdini_escape_html0(cmark_strbuf *ob, const uint8_t *src, bufsize_t size,
47
9.62M
                         int secure) {
48
9.62M
  bufsize_t i = 0, org, esc = 0;
49
50
25.0M
  while (i < size) {
51
24.4M
    org = i;
52
559M
    while (i < size && (esc = HTML_ESCAPE_TABLE[src[i]]) == 0)
53
535M
      i++;
54
55
24.4M
    if (i > org)
56
18.1M
      cmark_strbuf_put(ob, src + org, i - org);
57
58
    /* escaping */
59
24.4M
    if (unlikely(i >= size))
60
8.94M
      break;
61
62
    /* The forward slash is only escaped in secure mode */
63
15.4M
    if ((src[i] == '/' || src[i] == '\'') && !secure) {
64
2.63M
      cmark_strbuf_putc(ob, src[i]);
65
12.8M
    } else {
66
12.8M
      cmark_strbuf_puts(ob, HTML_ESCAPES[esc]);
67
12.8M
    }
68
69
15.4M
    i++;
70
15.4M
  }
71
72
9.62M
  return 1;
73
9.62M
}
74
75
0
int houdini_escape_html(cmark_strbuf *ob, const uint8_t *src, bufsize_t size) {
76
0
  return houdini_escape_html0(ob, src, size, 1);
77
0
}