#include <stdlib.h>#include <string.h>#include <ctype.h>inline static void flt_replace(char** where, const char* with, size_t* limit){ // Тот самый size_t size_t 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, size_t* limit){ char *entity_end; // почему int, почему не unsigned long или хотя бы проcто unsigned int num; // а здесь ты сам size_t сделал size_t len; if (in[1] != '#') return 0; // фигурные скобочки if (isdigit(in[2])) // переполнение и прочие радости пушкин проверять будет num = strtoul(in+2, &entity_end, 10); else if ((in[2] == 'x' || in[2] == 'X') && isxdigit(in[3])) // X тоже можно num = strtoul(in+3, &entity_end, 16); else return 0; // 0x10ffff is a magic number // что за ненависть к символам до 0x20 // if(num < 0x20 || num > 0x10ffff || *entity_end != ';') { // зачем else когда return if (num > 0x10ffff || *entity_end != ';') return 0; // зачем присваивание len в какой-то жопе дальней // либо // if ( (len = entity_end - in + 1) > *limit) // либо // len = entity_end - in + 1; // if (len > *limit) if (*limit < (len = entity_end - in + 1)) { *limit = 0; return 0; } 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 escaped// Почему бы не кошерный size_t вместо unsigned// к тому именно size_t возвращается strlen()'омchar* FilterHTML(const char *in, size_t limit){ // Зачем отдельные массивы? Зачем static? //static const char _lt[] = "<"; //static const char _gt[] = ">"; //static const char _quot[] = """; //static const char _amp[] = "&"; // Несоответствие в названиях между out_tmp и in // можно что-то типа out_cut и in_cur, а in оставить в покое char *out, *out_cur, *in_cur; // пробел между скобкой и if if (!limit) return NULL; // Зачем вола ебать + пробел между скобкой и if // out = (char*) malloc(limit*sizeof(char)); //if(!out) if ( (out = (char*) malloc(limit*sizeof(char))) == NULL) return NULL; out_cur = out; in_cur = in; // зачем повторять flt_replace(&out_tmp, ..., &limit);#define REPLACE(a) flt_replace(&out_tmp, a, &limit); // пробел между скобкой и while while (limit > 1) { // пробел блеадь switch (*in) { // зачем брэйки на той же строчке? case '\0': limit = 0; break; case '<': REPLACE("<"); break; case '>': REPLACE(">"); break; case '"': REPLACE("""); break; case '&': if(!flt_ncr(&out_tmp, in, &limit)) REPLACE("&"); break; default: *out_cur++ = *in_cur++; // наъер постфиксный инкремент --limit; } } // Зачем эта проверка? //if(*out_tmp) *out_cur = '\0'; return out;}