HTTP parser: normalization of paths ending with "." or "..".
Earlier, the paths were normalized only if there was a "/" at the end, which is wrong according to section 5.2.4 of RFC 3986 and hypothetically may allow to the directory above the document root.
This commit is contained in:
@@ -970,9 +970,11 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp)
|
|||||||
state = sw_quoted;
|
state = sw_quoted;
|
||||||
continue;
|
continue;
|
||||||
case '?':
|
case '?':
|
||||||
|
u--;
|
||||||
args = p;
|
args = p;
|
||||||
goto args;
|
goto args;
|
||||||
case '#':
|
case '#':
|
||||||
|
u--;
|
||||||
goto done;
|
goto done;
|
||||||
default:
|
default:
|
||||||
state = sw_normal;
|
state = sw_normal;
|
||||||
@@ -991,30 +993,42 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
|
|
||||||
case '/':
|
case '/':
|
||||||
state = sw_slash;
|
case '?':
|
||||||
|
case '#':
|
||||||
u -= 5;
|
u -= 5;
|
||||||
|
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
if (u < rp->path.start) {
|
if (u < rp->path.start) {
|
||||||
return NXT_HTTP_PARSE_INVALID;
|
return NXT_HTTP_PARSE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*u == '/') {
|
if (*u == '/') {
|
||||||
u++;
|
u++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
u--;
|
u--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ch == '?') {
|
||||||
|
args = p;
|
||||||
|
goto args;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == '#') {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = sw_slash;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '%':
|
case '%':
|
||||||
saved_state = state;
|
saved_state = state;
|
||||||
state = sw_quoted;
|
state = sw_quoted;
|
||||||
continue;
|
continue;
|
||||||
case '?':
|
|
||||||
args = p;
|
|
||||||
goto args;
|
|
||||||
case '#':
|
|
||||||
goto done;
|
|
||||||
default:
|
default:
|
||||||
state = sw_normal;
|
state = sw_normal;
|
||||||
*u++ = ch;
|
*u++ = ch;
|
||||||
@@ -1097,8 +1111,14 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state >= sw_quoted) {
|
if (state >= sw_dot) {
|
||||||
return NXT_HTTP_PARSE_INVALID;
|
if (state >= sw_quoted) {
|
||||||
|
return NXT_HTTP_PARSE_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "/." and "/.." must be normalized similar to "/./" and "/../". */
|
||||||
|
ch = '/';
|
||||||
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
args:
|
args:
|
||||||
|
|||||||
Reference in New Issue
Block a user