--- common/jk_status.c (revision 1648536) +++ common/jk_status.c (working copy) @@ -36,6 +36,8 @@ #include "jk_connect.h" #include "jk_uri_worker_map.h" +#include "apr.h" + #define HUGE_BUFFER_SIZE (8*1024) /** @@ -1200,6 +1202,162 @@ jk_putv(s, "\">", text, "", NULL); } +/* + Only include the function definitions for x2c and jk_unescape_url + if using APR < 1.5. Otherwise, just pass-through jk_unescape_url + to apr_unescape_url. +*/ +#ifndef APR_ESCAPE_STRING +static char x2c(const char *what) +{ + register char digit; + +#if !APR_CHARSET_EBCDIC + digit = + ((what[0] >= 'A') ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0')); + digit *= 16; + digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10 : (what[1] - '0')); +#else /*APR_CHARSET_EBCDIC*/ + char xstr[5]; + xstr[0]='0'; + xstr[1]='x'; + xstr[2]=what[0]; + xstr[3]=what[1]; + xstr[4]='\0'; + digit = convert_a2e[0xFF & strtol(xstr, NULL, 16)]; +#endif /*APR_CHARSET_EBCDIC*/ + return (digit); +} + +static int jk_unescape_url(char *const escaped, + const char *const url, + size_t slen, + const char *const forbid, + const char *const reserved, + const int plus, + size_t *len) +{ + apr_size_t size = 1; + int found = 0; + const char *s = (const char *) url; + char *d = (char *) escaped; + register int badesc, badpath; + + if (!url) { + return APR_NOTFOUND; + } + + badesc = 0; + badpath = 0; + if (s) { + if (d) { + for (; *s && slen; ++s, d++, slen--) { + if (plus && *s == '+') { + *d = ' '; + found = 1; + } + else if (*s != '%') { + *d = *s; + } + else { + if (!apr_isxdigit(*(s + 1)) || !apr_isxdigit(*(s + 2))) { + badesc = 1; + *d = '%'; + } + else { + char decoded; + decoded = x2c(s + 1); + if ((decoded == '\0') + || (forbid && strchr(forbid, decoded))) { + badpath = 1; + *d = decoded; + s += 2; + slen -= 2; + } + else if (reserved && strchr(reserved, decoded)) { + *d++ = *s++; + *d++ = *s++; + *d = *s; + size += 2; + } + else { + *d = decoded; + s += 2; + slen -= 2; + found = 1; + } + } + } + size++; + } + *d = '\0'; + } + else { + for (; *s && slen; ++s, slen--) { + if (plus && *s == '+') { + found = 1; + } + else if (*s != '%') { + /* character unchanged */ + } + else { + if (!apr_isxdigit(*(s + 1)) || !apr_isxdigit(*(s + 2))) { + badesc = 1; + } + else { + char decoded; + decoded = x2c(s + 1); + if ((decoded == '\0') + || (forbid && strchr(forbid, decoded))) { + badpath = 1; + s += 2; + slen -= 2; + } + else if (reserved && strchr(reserved, decoded)) { + s += 2; + slen -= 2; + size += 2; + } + else { + s += 2; + slen -= 2; + found = 1; + } + } + } + size++; + } + } + } + + if (len) { + *len = size; + } + if (badesc) { + return APR_EINVAL; + } + else if (badpath) { + return APR_BADCH; + } + else if (!found) { + return APR_NOTFOUND; + } + + return APR_SUCCESS; +} +#else +static int jk_unescape_url(char *const escaped, + const char *const url, + size_t slen, + const char *const forbid, + const char *const reserved, + const int plus, + size_t *len) +{ + return apr_unescape_url(escaped, url, slen, forbid, reserved, plus, len); +} +#endif + static int status_parse_uri(jk_ws_service_t *s, status_endpoint_t *p, jk_logger_t *l) @@ -1263,6 +1421,10 @@ #endif char *key = jk_pool_strdup(s->pool, param); char *value; + char decoded[JK_SHM_STR_SIZ]; /* stores url-decoded parameter value */ + size_t encoded_len; + size_t decoded_len; + if (!key) { jk_log(l, JK_LOG_ERROR, "Status worker '%s' could not copy string", @@ -1274,7 +1436,13 @@ if (value) { *value = '\0'; value++; - /* XXX Depending on the params values, we might need to trim and decode */ + + /* url-decode the parameter value */ + encoded_len = strlen(value); + if(APR_SUCCESS == jk_unescape_url(decoded, value, encoded_len, NULL, NULL, 1, &decoded_len) + && decoded_len <= encoded_len) + strcpy(value, decoded); + if (strlen(key)) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG,