#include // functions from http://git.sijanec.eu/sijanec/sear.c static int urlencode (char * o, const char * i /* o must have at least strlen(i)*3+1 bytes of memory allocated */) { if (!o || !i) return -2; size_t written = 0; /* o CANNOT be equal to i, unlike in urldecode */ for (; *i; i++) { if (isalnum(*i) || *i == '.' || *i == '_' || *i == '-' || *i == '~') { o[written++] = *i; } else { sprintf(o+written, "%%%02X", (unsigned char) *i); written += 3; } } o[written++] = '\0'; return 1; } __attribute__((unused)) static int urldecode (char * o, const char * i /* o must have at least strlen(i)+1 bytes memory allocated */) { if (!o || !i) return -2; size_t written = 0; /* o can be equal to i for decoding in-place */ char buf[] = "00"; for (; *i; i++) { if (*i == '%') { buf[0] = *++i; buf[1] = *++i; if (!buf[0] || !buf[1]) { /* malformed */ o[written++] = '\0'; return -1; } o[written++] = strtol(buf, NULL, 16); } else { o[written++] = *i; } } o[written++] = '\0'; return 1; } static char * htmlspecialchars (const char * i) { /* remember to free the output */ if (!i) // output will not be longer than strlen(i)*6 return NULL; size_t s = 128; char * o = malloc(s); if (!o) return NULL; size_t w = 0; for (; *i; i++) { if (s - w <= 10) { char * old = o; o = realloc(o, (s *= 1.5)); if (!o) { free(old); return NULL; } } switch (*i) { case '<': w += sprintf(o+w, "<"); break; case '"': w += sprintf(o+w, """); break; case '\'': w += sprintf(o+w, "'"); break; default: o[w++] = *i; break; } } o[w++] = '\0'; return o; } static char * hscf (char * i) { // htmlspecialchars and free char * hsc = htmlspecialchars(i); free(i); return hsc; }