rendered paste body#include <stdlib.h>#include <string.h>#include <ctype.h>inline static void flt_replace(char** where, const char* with, unsigned* limit){ unsigned len = strlen(with); if(*limit > len) { strcpy(*where, with); *where += len; *limit -= len; } else { *limit = 0; }}inline static unsigned flt_ncr(char** out, const char* in, unsigned* limit){ char *entity_end; int num; size_t len; if(in[1] != '#') return 0; if(isdigit(in[2])) { num = strtoul(in+2, &entity_end, 10); } else if (in[2] == 'x' && isxdigit(in[3])) { num = strtoul(in+3, &entity_end, 16); } else { return 0; } if(num < 0x20 || num > 0x10ffff || *entity_end != ';') { return 0; } else if(*limit < (len = entity_end - in + 1)) { *limit = 0; return 0; } else { strncpy(*out, in, len); *out += len; *limit -= len; return 1; }}// returns allocated string with up to 'limit' chars including '\0'// numeric entities are properly taken into account,// other cases of '<', '>', '&' and '"' are escapedchar* FilterHTML(const char *in, unsigned limit){ static const char _lt[] = "<"; static const char _gt[] = ">"; static const char _quot[] = """; static const char _amp[] = "&"; char *out, *out_tmp; if(!limit) return NULL; out = (char*) malloc(limit*sizeof(char)); if(!out) return NULL; out_tmp = out; while(limit > 1) { switch(*in) { case '\0': limit = 0; break; case '<': flt_replace(&out_tmp, _lt, &limit); break; case '>': flt_replace(&out_tmp, _gt, &limit); break; case '"': flt_replace(&out_tmp, _quot, &limit); break; case '&': if(!flt_ncr(&out_tmp, in, &limit)) default: *out_tmp++ = *in++; limit--; } } if(*out_tmp) *out_tmp = '\0'; return out;}