]> git.kaiwu.me - nginx.git/commitdiff
Limit req: improved error handling when parsing "zone" parameter of
authorValentin Bartenev <vbart@nginx.com>
Mon, 30 Jan 2012 09:26:08 +0000 (09:26 +0000)
committerValentin Bartenev <vbart@nginx.com>
Mon, 30 Jan 2012 09:26:08 +0000 (09:26 +0000)
"limit_req_zone" directive; minimum size of zone is increased.

Previously an unsigned variable was used to keep the return value of
ngx_parse_size() function, which led to an incorrect zone size if NGX_ERROR
was returned.

The new code has been taken from the "limit_conn_zone" directive.

src/http/modules/ngx_http_limit_req_module.c

index 164ef9886011c705189bc6557afe2f7604b7ac2b..43c9e9fdf362e78b09e7941ddf2d029d36df2243 100644 (file)
@@ -589,7 +589,8 @@ static char *
 ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
     u_char                    *p;
-    size_t                     size, len;
+    size_t                     len;
+    ssize_t                    size;
     ngx_str_t                 *value, name, s;
     ngx_int_t                  rate, scale;
     ngx_uint_t                 i;
@@ -612,25 +613,32 @@ ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
             p = (u_char *) ngx_strchr(name.data, ':');
 
-            if (p) {
-                *p = '\0';
+            if (p == NULL) {
+                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                                   "invalid zone size \"%V\"", &value[i]);
+                return NGX_CONF_ERROR;
+            }
 
-                name.len = p - name.data;
+            name.len = p - name.data;
 
-                p++;
+            s.data = p + 1;
+            s.len = value[i].data + value[i].len - s.data;
 
-                s.len = value[i].data + value[i].len - p;
-                s.data = p;
+            size = ngx_parse_size(&s);
 
-                size = ngx_parse_size(&s);
-                if (size > 8191) {
-                    continue;
-                }
+            if (size == NGX_ERROR) {
+                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                                   "invalid zone size \"%V\"", &value[i]);
+                return NGX_CONF_ERROR;
+            }
+
+            if (size < (ssize_t) (8 * ngx_pagesize)) {
+                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                                   "zone \"%V\" is too small", &value[i]);
+                return NGX_CONF_ERROR;
             }
 
-            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                               "invalid zone size \"%V\"", &value[i]);
-            return NGX_CONF_ERROR;
+            continue;
         }
 
         if (ngx_strncmp(value[i].data, "rate=", 5) == 0) {
@@ -682,7 +690,7 @@ ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
         return NGX_CONF_ERROR;
     }
 
-    if (name.len == 0 || size == 0) {
+    if (name.len == 0) {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                            "\"%V\" must have \"zone\" parameter",
                            &cmd->name);