static char badge_unescape_query_char(const char * * pp) { const char * p; int c; int d; /** *** Get a possibly escaped character from pointer at `pp' and *** unescape it. **/ p = *pp; c = *p++; switch (c) { case '\0': p--; break; case '+': c = ' '; break; case '%': if (!apr_isxdigit(p[0]) || !apr_isxdigit(p[1])) break; d = *p++; c = *p++; if (d >= '0' && d <= '9') d -= '0'; else if (d >= 'a' && d <= 'f') d -= 'a' - 10; else d -= 'A' - 10; if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'a' && c <= 'f') c -= 'a' - 10; else c -= 'A' - 10; c |= d << 4; break; } *pp = p; return c; }
/* * *** Ripped from HTTPD util.c (why are so many PORTABLE things not in APR UTIL?) * * Unescapes a URL, leaving reserved characters intact. * Returns 0 on success, non-zero on error * Failure is due to * bad % escape returns HTTP_BAD_REQUEST * * decoding %00 or a forbidden character returns HTTP_NOT_FOUND */ static int unescape_url(char *url, const char *forbid, const char *reserved) { register int badesc, badpath; char *x, *y; badesc = 0; badpath = 0; /* Initial scan for first '%'. Don't bother writing values before * seeing a '%' */ y = strchr(url, '%'); if (y == NULL) { return APR_SUCCESS; } for (x = y; *y; ++x, ++y) { if (*y != '%') { *x = *y; } else { if (!apr_isxdigit(*(y + 1)) || !apr_isxdigit(*(y + 2))) { badesc = 1; *x = '%'; } else { char decoded; decoded = x2c(y + 1); if ((decoded == '\0') || (forbid && strchr(forbid, decoded))) { badpath = 1; *x = decoded; y += 2; } else if (reserved && strchr(reserved, decoded)) { *x++ = *y++; *x++ = *y++; *x = *y; } else { *x = decoded; y += 2; } } } } *x = '\0'; if (badesc) { return APR_EINVAL; } else if (badpath) { return APR_EINVAL; } else { return APR_SUCCESS; } }
static int oidc_session_unescape_url(char *url, const char *forbid, const char *reserved) { register int badesc, badpath; char *x, *y; badesc = 0; badpath = 0; /* Initial scan for first '%'. Don't bother writing values before * seeing a '%' */ y = strchr(url, '%'); if (y == NULL) { return OK; } for (x = y; *y; ++x, ++y) { if (*y != '%') { *x = *y; } else { if (!apr_isxdigit(*(y + 1)) || !apr_isxdigit(*(y + 2))) { badesc = 1; *x = '%'; } else { char decoded; decoded = x2c(y + 1); if ((decoded == '\0') || (forbid && ap_strchr_c(forbid, decoded))) { badpath = 1; *x = decoded; y += 2; } else if (reserved && ap_strchr_c(reserved, decoded)) { *x++ = *y++; *x++ = *y++; *x = *y; } else { *x = decoded; y += 2; } } } } *x = '\0'; if (badesc) { return HTTP_BAD_REQUEST; } else if (badpath) { return HTTP_NOT_FOUND; } else { return OK; } }
/* * Unescapes a URL. * Returns 0 on success, non-zero on error * Failure is due to * bad % escape returns HTTP_BAD_REQUEST * * decoding %00 -> \0 (the null character) * decoding %2f -> / (a special character) * returns HTTP_NOT_FOUND */ AP_DECLARE(int) ap_unescape_url(char *url) { register int badesc, badpath; char *x, *y; badesc = 0; badpath = 0; /* Initial scan for first '%'. Don't bother writing values before * seeing a '%' */ y = strchr(url, '%'); if (y == NULL) { return OK; } for (x = y; *y; ++x, ++y) { if (*y != '%') *x = *y; else { if (!apr_isxdigit(*(y + 1)) || !apr_isxdigit(*(y + 2))) { badesc = 1; *x = '%'; } else { *x = x2c(y + 1); y += 2; if (IS_SLASH(*x) || *x == '\0') badpath = 1; } } } *x = '\0'; if (badesc) return HTTP_BAD_REQUEST; else if (badpath) return HTTP_NOT_FOUND; else return OK; }
APU_DECLARE(apr_status_t) apr_uuid_parse(apr_uuid_t *uuid, const char *uuid_str) { int i; unsigned char *d = uuid->data; for (i = 0; i < 36; ++i) { char c = uuid_str[i]; if (!apr_isxdigit(c) && !(c == '-' && (i == 8 || i == 13 || i == 18 || i == 23))) /* ### need a better value */ return APR_BADARG; } if (uuid_str[36] != '\0') { /* ### need a better value */ return APR_BADARG; } d[0] = parse_hexpair(&uuid_str[0]); d[1] = parse_hexpair(&uuid_str[2]); d[2] = parse_hexpair(&uuid_str[4]); d[3] = parse_hexpair(&uuid_str[6]); d[4] = parse_hexpair(&uuid_str[9]); d[5] = parse_hexpair(&uuid_str[11]); d[6] = parse_hexpair(&uuid_str[14]); d[7] = parse_hexpair(&uuid_str[16]); d[8] = parse_hexpair(&uuid_str[19]); d[9] = parse_hexpair(&uuid_str[21]); for (i = 6; i--;) d[10 + i] = parse_hexpair(&uuid_str[i*2+24]); return APR_SUCCESS; }