[nginx] The "/." and "/.." at the end of URI should be normalized.

Ruslan Ermilov ru at nginx.com
Tue Oct 8 18:57:53 UTC 2019


details:   https://hg.nginx.org/nginx/rev/79bcbe7cd3f2
branches:  
changeset: 7578:79bcbe7cd3f2
user:      Ruslan Ermilov <ru at nginx.com>
date:      Tue Oct 08 21:56:14 2019 +0300
description:
The "/." and "/.." at the end of URI should be normalized.

diffstat:

 src/http/ngx_http_parse.c |  38 ++++++++++++++++++++++++++++++++------
 1 files changed, 32 insertions(+), 6 deletions(-)

diffs (77 lines):

diff -r 5a3426683251 -r 79bcbe7cd3f2 src/http/ngx_http_parse.c
--- a/src/http/ngx_http_parse.c	Tue Oct 08 21:56:14 2019 +0300
+++ b/src/http/ngx_http_parse.c	Tue Oct 08 21:56:14 2019 +0300
@@ -1437,9 +1437,11 @@ ngx_http_parse_complex_uri(ngx_http_requ
                 state = sw_quoted;
                 break;
             case '?':
+                u--;
                 r->args_start = p;
                 goto args;
             case '#':
+                u--;
                 goto done;
             case '+':
                 r->plus_in_uri = 1;
@@ -1467,7 +1469,8 @@ ngx_http_parse_complex_uri(ngx_http_requ
             case '\\':
 #endif
             case '/':
-                state = sw_slash;
+            case '?':
+            case '#':
                 u -= 5;
                 for ( ;; ) {
                     if (u < r->uri.data) {
@@ -1479,16 +1482,19 @@ ngx_http_parse_complex_uri(ngx_http_requ
                     }
                     u--;
                 }
+                if (ch == '?') {
+                    r->args_start = p;
+                    goto args;
+                }
+                if (ch == '#') {
+                    goto done;
+                }
+                state = sw_slash;
                 break;
             case '%':
                 quoted_state = state;
                 state = sw_quoted;
                 break;
-            case '?':
-                r->args_start = p;
-                goto args;
-            case '#':
-                goto done;
             case '+':
                 r->plus_in_uri = 1;
                 /* fall through */
@@ -1565,6 +1571,26 @@ ngx_http_parse_complex_uri(ngx_http_requ
         return NGX_HTTP_PARSE_INVALID_REQUEST;
     }
 
+    if (state == sw_dot) {
+        u--;
+
+    } else if (state == sw_dot_dot) {
+        u -= 5;
+
+        for ( ;; ) {
+            if (u < r->uri.data) {
+                return NGX_HTTP_PARSE_INVALID_REQUEST;
+            }
+
+            if (*u == '/') {
+                u++;
+                break;
+            }
+
+            u--;
+        }
+    }
+
 done:
 
     r->uri.len = u - r->uri.data;


More information about the nginx-devel mailing list