httpd: fix /../ sanitization (had one extra semicolon). rewrote it
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
cda6ea905d
commit
b05cd6b7a7
@ -2012,30 +2012,36 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
|
||||
/* Algorithm stolen from libbb bb_simplify_path(),
|
||||
* but don't strdup, retain trailing slash, protect root */
|
||||
urlp = tptr = urlcopy;
|
||||
do {
|
||||
for (;;) {
|
||||
if (*urlp == '/') {
|
||||
/* skip duplicate (or initial) slash */
|
||||
if (*tptr == '/') {
|
||||
continue;
|
||||
goto next_char;
|
||||
}
|
||||
if (*tptr == '.') {
|
||||
/* skip extra "/./" */
|
||||
if (tptr[1] == '/' || !tptr[1]) {
|
||||
continue;
|
||||
}
|
||||
if (tptr[1] == '.' && (tptr[2] == '/' || tptr[2] == '\0')) {
|
||||
/* "..": be careful */
|
||||
if (tptr[1] == '.' && (tptr[2] == '/' || !tptr[2])) {
|
||||
++tptr;
|
||||
if (urlp == urlcopy) /* protect root */
|
||||
/* protect root */
|
||||
if (urlp == urlcopy)
|
||||
send_headers_and_exit(HTTP_BAD_REQUEST);
|
||||
while (*--urlp != '/') /* omit previous dir */;
|
||||
/* omit previous dir */
|
||||
while (*--urlp != '/')
|
||||
continue;
|
||||
/* skip to "./" or ".<NUL>" */
|
||||
tptr++;
|
||||
}
|
||||
if (tptr[1] == '/' || tptr[1] == '\0') {
|
||||
/* skip extra "/./" */
|
||||
goto next_char;
|
||||
}
|
||||
}
|
||||
}
|
||||
*++urlp = *tptr;
|
||||
} while (*++tptr);
|
||||
*++urlp = '\0'; /* terminate after last character */
|
||||
if (*urlp == '\0')
|
||||
break;
|
||||
next_char:
|
||||
tptr++;
|
||||
}
|
||||
|
||||
/* If URL is a directory, add '/' */
|
||||
if (urlp[-1] != '/') {
|
||||
|
Loading…
Reference in New Issue
Block a user