All pastes #2109479 Raw Edit

Unnamed

public c v1 · immutable
#2109479 ·published 2012-02-03 19:29 UTC
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[] = "&lt;";        static const char _gt[] = "&gt;";        static const char _quot[] = "&quot;";        static const char _amp[] = "&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))                                flt_replace(&out_tmp, _amp, &limit); break;                default:                       *out_tmp++ = *in++;                       limit--;                }        }        if(*out_tmp)                *out_tmp = '\0';        return out;}