Diffstat (limited to 'html.c')
| -rw-r--r-- | html.c | 100 |
1 files changed, 78 insertions, 22 deletions
@@ -8,7 +8,6 @@ #include "cgit.h" #include "html.h" -#include "url.h" /* Percent-encoding of each character, except: a-zA-Z0-9!$()*,./:;@- */ static const char* url_escape_table[256] = { @@ -59,7 +58,7 @@ char *fmt(const char *format, ...) va_start(args, format); len = vsnprintf(buf[bufidx], sizeof(buf[bufidx]), format, args); va_end(args); - if (len >= sizeof(buf[bufidx])) { + if (len > sizeof(buf[bufidx])) { fprintf(stderr, "[html.c] string truncated: %s\n", format); exit(1); } @@ -124,20 +123,29 @@ void html_vtxtf(const char *format, va_list ap) void html_txt(const char *txt) { - if (txt) - html_ntxt(txt, strlen(txt)); + const char *t = txt; + while (t && *t) { + int c = *t; + if (c == '<' || c == '>' || c == '&') { + html_raw(txt, t - txt); + if (c == '>') + html(">"); + else if (c == '<') + html("<"); + else if (c == '&') + html("&"); + txt = t + 1; + } + t++; + } + if (t != txt) + html(txt); } -ssize_t html_ntxt(const char *txt, size_t len) +void html_ntxt(int len, const char *txt) { const char *t = txt; - ssize_t slen; - - if (len > SSIZE_MAX) - return -1; - - slen = (ssize_t) len; - while (t && *t && slen--) { + while (t && *t && len--) { int c = *t; if (c == '<' || c == '>' || c == '&') { html_raw(txt, t - txt); @@ -153,7 +161,8 @@ ssize_t html_ntxt(const char *txt, size_t len) } if (t != txt) html_raw(txt, t - txt); - return slen; + if (len < 0) + html("..."); } void html_attrf(const char *fmt, ...) @@ -328,17 +337,64 @@ int html_include(const char *filename) return 0; } -void http_parse_querystring(const char *txt, void (*fn)(const char *name, const char *value)) +static int hextoint(char c) { - const char *t = txt; + if (c >= 'a' && c <= 'f') + return 10 + c - 'a'; + else if (c >= 'A' && c <= 'F') + return 10 + c - 'A'; + else if (c >= '0' && c <= '9') + return c - '0'; + else + return -1; +} - while (t && *t) { - char *name = url_decode_parameter_name(&t); - if (*name) { - char *value = url_decode_parameter_value(&t); - fn(name, value); - free(value); +static char *convert_query_hexchar(char *txt) +{ + int d1, d2, n; + n = strlen(txt); + if (n < 3) { + *txt = '\0'; + return txt-1; + } + d1 = hextoint(*(txt + 1)); + d2 = hextoint(*(txt + 2)); + if (d1 < 0 || d2 < 0) { + memmove(txt, txt + 3, n - 2); + return txt-1; + } else { + *txt = d1 * 16 + d2; + memmove(txt + 1, txt + 3, n - 2); + return txt; + } +} + +int http_parse_querystring(const char *txt_, void (*fn)(const char *name, const char *value)) +{ + char *o, *t, *txt, *value = NULL, c; + + if (!txt_) + return 0; + + o = t = txt = xstrdup(txt_); + while ((c=*t) != '\0') { + if (c == '=') { + *t = '\0'; + value = t + 1; + } else if (c == '+') { + *t = ' '; + } else if (c == '%') { + t = convert_query_hexchar(t); + } else if (c == '&') { + *t = '\0'; + (*fn)(txt, value); + txt = t + 1; + value = NULL; } - free(name); + t++; } + if (t != txt) + (*fn)(txt, value); + free(o); + return 0; } |