summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorValentin Bartenev <vbart@nginx.com>2019-09-30 19:11:17 +0300
committerValentin Bartenev <vbart@nginx.com>2019-09-30 19:11:17 +0300
commit2dbda125db743f71d4dd104b29fa58620eb49de2 (patch)
tree751939d39c22fa5e801993e9ca820a3cde5ed7a5 /src
parent2791c00cf2df1b4c86179756f7c56064219f482f (diff)
downloadunit-2dbda125db743f71d4dd104b29fa58620eb49de2.tar.gz
unit-2dbda125db743f71d4dd104b29fa58620eb49de2.tar.bz2
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.
Diffstat (limited to '')
-rw-r--r--src/nxt_http_parse.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/src/nxt_http_parse.c b/src/nxt_http_parse.c
index 5b009d96..63fd5130 100644
--- a/src/nxt_http_parse.c
+++ b/src/nxt_http_parse.c
@@ -970,9 +970,11 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp)
state = sw_quoted;
continue;
case '?':
+ u--;
args = p;
goto args;
case '#':
+ u--;
goto done;
default:
state = sw_normal;
@@ -991,30 +993,42 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp)
}
switch (ch) {
+
case '/':
- state = sw_slash;
+ case '?':
+ case '#':
u -= 5;
+
for ( ;; ) {
if (u < rp->path.start) {
return NXT_HTTP_PARSE_INVALID;
}
+
if (*u == '/') {
u++;
break;
}
+
u--;
}
+
+ if (ch == '?') {
+ args = p;
+ goto args;
+ }
+
+ if (ch == '#') {
+ goto done;
+ }
+
+ state = sw_slash;
break;
case '%':
saved_state = state;
state = sw_quoted;
continue;
- case '?':
- args = p;
- goto args;
- case '#':
- goto done;
+
default:
state = sw_normal;
*u++ = ch;
@@ -1097,8 +1111,14 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp)
}
}
- if (state >= sw_quoted) {
- return NXT_HTTP_PARSE_INVALID;
+ if (state >= sw_dot) {
+ if (state >= sw_quoted) {
+ return NXT_HTTP_PARSE_INVALID;
+ }
+
+ /* "/." and "/.." must be normalized similar to "/./" and "/../". */
+ ch = '/';
+ goto again;
}
args: