Commit:    efd671f242e87e3301a1b3e76179955f26119feb
Author:    Xinchen Hui <larue...@gmail.com>         Wed, 4 Apr 2012 16:14:28 
+0800
Parents:   3ea9fa1b4626f6125f25d8b0bcffac7becc1d092
Branches:  PHP-5.4

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=efd671f242e87e3301a1b3e76179955f26119feb

Log:
Fixed bug Fixed bug #61605 (header_remove() does not remove all headers)

Bugs:
https://bugs.php.net/61605

Changed paths:
  M  NEWS
  M  main/SAPI.c
  A  sapi/cgi/tests/bug61605.phpt


Diff:
diff --git a/NEWS b/NEWS
index 6fc9126..b8b28b1 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,8 @@ PHP                                                             
           NEWS
   . "Connection: close" instead of "Connection: closed" (Gustavo)
 
 - Core:
+  . Fixed bug Fixed bug #61605 (header_remove() does not remove all headers).
+    (Laruence)
   . Fixed bug #61374 (html_entity_decode tries to decode code points that don't
     exist in ISO-8859-1). (Gustavo)
   . Fixed bug #61273 (call_user_func_array with more than 16333 arguments 
diff --git a/main/SAPI.c b/main/SAPI.c
index 74fdbb2..0d3b4ef 100644
--- a/main/SAPI.c
+++ b/main/SAPI.c
@@ -587,10 +587,36 @@ static void sapi_update_response_code(int ncode TSRMLS_DC)
        SG(sapi_headers).http_response_code = ncode;
 }
 
-static int sapi_find_matching_header(void *element1, void *element2)
-{
-       int len = strlen((char*)element2);
-       return strncasecmp(((sapi_header_struct*)element1)->header, 
(char*)element2, len) == 0 && ((sapi_header_struct*)element1)->header[len] == 
':';
+/* 
+ * since zend_llist_del_element only remove one matched item once,
+ * we should remove them by ourself
+ */
+static void sapi_remove_header(zend_llist *l, char *name, uint len) {
+       sapi_header_struct *header;
+       zend_llist_element *next;
+       zend_llist_element *current=l->head;
+
+       while (current) {
+               header = (sapi_header_struct *)(current->data);
+               next = current->next;
+               if (header->header_len > len && header->header[len] == ':'
+                               && !strncasecmp(header->header, name, len)) {
+                       if (current->prev) {
+                               current->prev->next = next;
+                       } else {
+                               l->head = next;
+                       }
+                       if (next) {
+                               next->prev = current->prev;
+                       } else {
+                               l->tail = current->prev;
+                       }
+                       sapi_free_header(header);
+                       efree(current);
+                       --l->count;
+               }
+               current = next;
+       }
 }
 
 SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, 
zend_bool duplicate, zend_bool replace TSRMLS_DC)
@@ -621,7 +647,7 @@ static void sapi_header_add_op(sapi_header_op_enum op, 
sapi_header_struct *sapi_
                                char sav = *colon_offset;
 
                                *colon_offset = 0;
-                               
zend_llist_del_element(&SG(sapi_headers).headers, sapi_header->header, 
(int(*)(void*, void*))sapi_find_matching_header);
+                       sapi_remove_header(&SG(sapi_headers).headers, 
sapi_header->header, strlen(sapi_header->header));
                                *colon_offset = sav;
                        }
                }
@@ -703,7 +729,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void 
*arg TSRMLS_DC)
                        sapi_header.header_len = header_line_len;
                        sapi_module.header_handler(&sapi_header, op, 
&SG(sapi_headers) TSRMLS_CC);
                }
-               zend_llist_del_element(&SG(sapi_headers).headers, header_line, 
(int(*)(void*, void*))sapi_find_matching_header);
+               sapi_remove_header(&SG(sapi_headers).headers, header_line, 
header_line_len);
                efree(header_line);
                return SUCCESS;
        } else {
diff --git a/sapi/cgi/tests/bug61605.phpt b/sapi/cgi/tests/bug61605.phpt
new file mode 100644
index 0000000..c6e4cf2
--- /dev/null
+++ b/sapi/cgi/tests/bug61605.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Bug #61605 (header_remove() does not remove all headers)
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--GET--
+foo=bar
+--FILE--
+<?php
+header("A: first");
+header("A: second", TRUE);
+$headers1 = headers_list();
+header("A: third", FALSE);
+$headers2 = headers_list();
+header_remove("A");
+$headers3 = headers_list();
+print_r($headers1);
+print_r($headers2);
+print_r($headers3);
+--EXPECTF--
+Array
+(
+    [0] => X-Powered-By: %s
+    [1] => A: second
+)
+Array
+(
+    [0] => X-Powered-By: %s
+    [1] => A: second
+    [2] => A: third
+)
+Array
+(
+    [0] => X-Powered-By: %s
+)


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to