[PATCH] Ignore response header entries with zero hash in ngx_http_varaible_headers

Valentin V. Bartenev ne at vbart.ru
Tue Dec 6 08:42:10 UTC 2011


Hello, agentzh.

On Wednesday 09 November 2011 13:49:51 agentzh wrote:
> On Sat, Oct 1, 2011 at 2:08 AM, agentzh <agentzh at gmail.com> wrote:
> > Thank you for the review. I've already updated the patch per your
> > suggestion and tested on my side :)
> 
> Markus Linnala has found a memory overflow issue in my previous patch.
> Here attaches an updated one for nginx 1.0.9.

Thank you for the patch. Based on it, I wrote a slightly more optimized
version.

Would you please take a look? Also, It would be great if you try it.

Thanks!

wbr, Valentin V. Bartenev // NGINX Team


Index: src/http/ngx_http_variables.c
===================================================================
--- src/http/ngx_http_variables.c	(revision 4323)
+++ src/http/ngx_http_variables.c	(working copy)
@@ -640,8 +640,8 @@ static ngx_int_t
 ngx_http_variable_headers(ngx_http_request_t *r, ngx_http_variable_value_t *v,
     uintptr_t data)
 {
-    ssize_t            len;
-    u_char            *p;
+    size_t             len;
+    u_char            *p, *end;
     ngx_uint_t         i, n;
     ngx_array_t       *a;
     ngx_table_elt_t  **h;
@@ -649,18 +649,30 @@ ngx_http_variable_headers(ngx_http_request_t *r, n
     a = (ngx_array_t *) ((char *) r + data);
 
     n = a->nelts;
+    h = a->elts;
 
-    if (n == 0) {
+    len = 0;
+
+    for (i = 0; i < n; i++) {
+
+        if (h[i]->hash == 0) {
+            continue;
+        }
+
+        len += h[i]->value.len + sizeof("; ") - 1;
+    }
+
+    if (len == 0) {
         v->not_found = 1;
         return NGX_OK;
     }
 
+    len -= sizeof("; ") - 1;
+
     v->valid = 1;
     v->no_cacheable = 0;
     v->not_found = 0;
 
-    h = a->elts;
-
     if (n == 1) {
         v->len = (*h)->value.len;
         v->data = (*h)->value.data;
@@ -668,12 +680,6 @@ ngx_http_variable_headers(ngx_http_request_t *r, n
         return NGX_OK;
     }
 
-    len = - (ssize_t) (sizeof("; ") - 1);
-
-    for (i = 0; i < n; i++) {
-        len += h[i]->value.len + sizeof("; ") - 1;
-    }
-
     p = ngx_pnalloc(r->pool, len);
     if (p == NULL) {
         return NGX_ERROR;
@@ -682,10 +688,17 @@ ngx_http_variable_headers(ngx_http_request_t *r, n
     v->len = len;
     v->data = p;
 
+    end = p + len;
+
     for (i = 0; /* void */ ; i++) {
+
+        if (h[i]->hash == 0) {
+            continue;
+        }
+
         p = ngx_copy(p, h[i]->value.data, h[i]->value.len);
 
-        if (i == n - 1) {
+        if (p == end) {
             break;
         }
 
@@ -738,6 +751,10 @@ ngx_http_variable_unknown_header(ngx_http_variable
             i = 0;
         }
 
+        if (header[i].hash == 0) {
+            continue;
+        }
+
         for (n = 0; n + prefix < var->len && n < header[i].key.len; n++) {
             ch = header[i].key.data[n];
 



More information about the nginx-devel mailing list