in src/request/apache_request.c [292:361]
static int ap_unescape_url_u(char *url)
{
register int x, y, badesc, badpath;
badesc = 0;
badpath = 0;
for (x = 0, y = 0; url[y]; ++x, ++y) {
if (url[y] != '%'){
url[x] = url[y];
}
else {
if(url[y + 1] == 'u' || url[y + 1] == 'U'){
unsigned int c = utf8_convert(&url[y + 2]);
y += 5;
if(c < 0x80){
url[x] = c;
}
else if(c < 0x800) {
url[x] = 0xc0 | (c >> 6);
url[++x] = 0x80 | (c & 0x3f);
}
else if(c < 0x10000){
url[x] = (0xe0 | (c >> 12));
url[++x] = (0x80 | ((c >> 6) & 0x3f));
url[++x] = (0x80 | (c & 0x3f));
}
else if(c < 0x200000){
url[x] = 0xf0 | (c >> 18);
url[++x] = 0x80 | ((c >> 12) & 0x3f);
url[++x] = 0x80 | ((c >> 6) & 0x3f);
url[++x] = 0x80 | (c & 0x3f);
}
else if(c < 0x4000000){
url[x] = 0xf8 | (c >> 24);
url[++x] = 0x80 | ((c >> 18) & 0x3f);
url[++x] = 0x80 | ((c >> 12) & 0x3f);
url[++x] = 0x80 | ((c >> 6) & 0x3f);
url[++x] = 0x80 | (c & 0x3f);
}
else if(c < 0x8000000){
url[x] = 0xfe | (c >> 30);
url[++x] = 0x80 | ((c >> 24) & 0x3f);
url[++x] = 0x80 | ((c >> 18) & 0x3f);
url[++x] = 0x80 | ((c >> 12) & 0x3f);
url[++x] = 0x80 | ((c >> 6) & 0x3f);
url[++x] = 0x80 | (c & 0x3f);
}
}
else {
if (!apr_isxdigit(url[y + 1]) || !apr_isxdigit(url[y + 2])) {
badesc = 1;
url[x] = '%';
}
else {
url[x] = x2c(&url[y + 1]);
y += 2;
if (url[x] == '/' || url[x] == '\0')
badpath = 1;
}
}
}
}
url[x] = '\0';
if (badesc)
return HTTP_BAD_REQUEST;
else if (badpath)
return HTTP_NOT_FOUND;
else
return OK;
}