#include #include #include #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 ); }