in native/common/jk_url.c [176:291]
int jk_unescape_url(char *const unescaped,
const char *const url,
size_t slen,
const char *const forbid,
const char *const reserved,
const int plus,
size_t *len)
{
size_t size = 1;
int found = 0;
const char *s = (const char *) url;
char *d = (char *) unescaped;
register int badesc, badpath;
if (!url) {
return JK_FALSE;
}
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 (!jk_isxdigit(*(s + 1)) || !jk_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 (!jk_isxdigit(*(s + 1)) || !jk_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 JK_FALSE;
}
else if (badpath) {
return JK_FALSE;
}
else if (!found) {
return JK_TRUE;
}
return JK_TRUE;
}