Patch 0001-Fixed-bug-61605-header_remove-does-not-remove-all-headers for HTTP related Bug #61605
Patch version 2012-04-03 17:44 UTC
Return to Bug #61605 |
Download this patch
Patch Revisions:
Developer: reeze.xia@gmail.com
From 447d05ff8dd4d8b2bd3249e46c8d78c1f6a617d5 Mon Sep 17 00:00:00 2001
From: reeze <reeze.xia@gmail.com>
Date: Wed, 4 Apr 2012 01:35:35 +0800
Subject: [PATCH] Fixed bug #61605 header_remove() does not remove all headers
---
NEWS | 1 +
main/SAPI.c | 38 ++++++++++++++++++++++----
sapi/cgi/tests/bug61605.phpt | 61 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 95 insertions(+), 5 deletions(-)
create mode 100644 sapi/cgi/tests/bug61605.phpt
diff --git a/NEWS b/NEWS
index c7cd2c7..361e4ea 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@ PHP NEWS
(merge after 5.3.11 release)
- Core:
+ . Fixed bug #61605 header_remove() does not remove all headers. (Reeze)
. Fixed bug #61273 (call_user_func_array with more than 16333 arguments
leaks / crashes). (Laruence)
. Fixed bug #61165 (Segfault - strip_tags()). (Laruence)
diff --git a/main/SAPI.c b/main/SAPI.c
index 693cad3..ca71f33 100644
--- a/main/SAPI.c
+++ b/main/SAPI.c
@@ -501,10 +501,38 @@ 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)
+static void sapi_remove_all_matching_headers_by_name(zend_llist *headers, char *name)
{
- int len = strlen((char*)element2);
- return strncasecmp(((sapi_header_struct*)element1)->header, (char*)element2, len) == 0 && ((sapi_header_struct*)element1)->header[len] == ':';
+ zend_llist_element *element, *next;
+ int len = strlen(name);
+ char *header;
+
+ element = headers->head;
+ while (element) {
+ next = element->next;
+ header = (char *)((sapi_header_struct *)element->data)->header;
+
+ if (strncasecmp(header, name, len) == 0 && header[len] == ':') {
+ if (element->prev) {
+ element->prev->next = (element)->next;
+ } else {
+ headers->head = element->next;
+ }
+ if (element->next) {
+ element->next->prev = (element)->prev;
+ } else {
+ headers->tail = element->prev;
+ }
+ if (headers->dtor) {
+ headers->dtor(element->data);
+ }
+
+ pefree(element, headers->persistent);
+ --headers->count;
+ }
+
+ element = next;
+ }
}
SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bool duplicate, zend_bool replace TSRMLS_DC)
@@ -611,7 +639,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC)
if (sapi_module.header_handler) {
sapi_module.header_handler(&sapi_header, op, &SG(sapi_headers) TSRMLS_CC);
}
- zend_llist_del_element(&SG(sapi_headers).headers, sapi_header.header, (int(*)(void*, void*))sapi_find_matching_header);
+ sapi_remove_all_matching_headers_by_name(&SG(sapi_headers).headers, sapi_header.header);
sapi_free_header(&sapi_header);
return SUCCESS;
}
@@ -769,7 +797,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC)
char sav;
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_all_matching_headers_by_name(&SG(sapi_headers).headers, sapi_header.header);
*colon_offset = sav;
}
}
diff --git a/sapi/cgi/tests/bug61605.phpt b/sapi/cgi/tests/bug61605.phpt
new file mode 100644
index 0000000..b152a20
--- /dev/null
+++ b/sapi/cgi/tests/bug61605.phpt
@@ -0,0 +1,61 @@
+--TEST--
+header_remove() should handle multiple same key headers
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--FILE--
+<?php
+
+include "include.inc";
+
+$php = get_cgi_path();
+reset_env_vars();
+
+$f = tempnam(sys_get_temp_dir(), 'cgitest');
+
+function test($script) {
+ file_put_contents($GLOBALS['f'], $script);
+ $cmd = escapeshellcmd($GLOBALS['php']);
+ $cmd .= ' -n -dreport_zend_debug=0 -dhtml_errors=0 ' . escapeshellarg($GLOBALS['f']);
+ echo "----------\n";
+ echo rtrim($script) . "\n";
+ echo "----------\n";
+ passthru($cmd);
+}
+
+test('<?php
+header("X-Foo: Bar");
+header("X-Foo: Bar2", false);
+
+header_remove("X-Foo");
+?>');
+
+test('<?php
+header("X-Foo: Bar");
+header("X-Foo: Baz", false);
+header("X-Foo: Baz2");
+?>');
+
+@unlink($f);
+?>
+--EXPECTF--
+----------
+<?php
+header("X-Foo: Bar");
+header("X-Foo: Bar2", false);
+
+header_remove("X-Foo");
+?>
+----------
+X-Powered-By: PHP/%s
+Content-type: text/html
+
+----------
+<?php
+header("X-Foo: Bar");
+header("X-Foo: Baz", false);
+header("X-Foo: Baz2");
+?>
+----------
+X-Powered-By: PHP/%s
+X-Foo: Baz2
+Content-type: text/html
--
1.7.9.3
|