84 lines
2 KiB
C
84 lines
2 KiB
C
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "houdini.h"
|
|
|
|
#define ESCAPE_GROW_FACTOR(x) (((x) * 12) / 10) /* this is very scientific, yes */
|
|
|
|
/**
|
|
* According to the OWASP rules:
|
|
*
|
|
* & --> &
|
|
* < --> <
|
|
* > --> >
|
|
* " --> "
|
|
* ' --> ' ' is not recommended
|
|
* / --> / forward slash is included as it helps end an HTML entity
|
|
*
|
|
*/
|
|
static const char HTML_ESCAPE_TABLE[] = {
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 4,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
};
|
|
|
|
static const char *HTML_ESCAPES[] = {
|
|
"",
|
|
""",
|
|
"&",
|
|
"'",
|
|
"/",
|
|
"<",
|
|
">"
|
|
};
|
|
|
|
void
|
|
houdini_escape_html0(struct buf *ob, const uint8_t *src, size_t size, int secure)
|
|
{
|
|
size_t i = 0, org, esc = 0;
|
|
|
|
bufgrow(ob, ESCAPE_GROW_FACTOR(size));
|
|
|
|
while (i < size) {
|
|
org = i;
|
|
while (i < size && (esc = HTML_ESCAPE_TABLE[src[i]]) == 0)
|
|
i++;
|
|
|
|
if (i > org)
|
|
bufput(ob, src + org, i - org);
|
|
|
|
/* escaping */
|
|
if (i >= size)
|
|
break;
|
|
|
|
/* The forward slash is only escaped in secure mode */
|
|
if (src[i] == '/' && !secure) {
|
|
bufputc(ob, '/');
|
|
} else {
|
|
bufputs(ob, HTML_ESCAPES[esc]);
|
|
}
|
|
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void
|
|
houdini_escape_html(struct buf *ob, const uint8_t *src, size_t size)
|
|
{
|
|
houdini_escape_html0(ob, src, size, 1);
|
|
}
|
|
|