summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYasuo Ohgaki <yohgaki@php.net>2014-01-22 19:21:25 +0900
committerYasuo Ohgaki <yohgaki@php.net>2014-01-22 19:21:25 +0900
commit58f94345a7ef8125d5c7a5a3dfe23a7c50a8bfcd (patch)
tree53db7ee72fb9f76aec27f3db1508461498797e35
parenta27e51fd4e9121f962821d0f7bd1960fce0a0fd5 (diff)
downloadphp-git-58f94345a7ef8125d5c7a5a3dfe23a7c50a8bfcd.tar.gz
Fixed previous commit may delete unwanted cookies. Sync tests from upper branches.
-rw-r--r--ext/session/session.c46
-rw-r--r--ext/session/tests/bug60634.phpt3
-rw-r--r--ext/session/tests/bug60634_error_2.phpt4
-rw-r--r--ext/session/tests/bug60634_error_4.phpt5
4 files changed, 52 insertions, 6 deletions
diff --git a/ext/session/session.c b/ext/session/session.c
index d6d5da2d0c..afc7eef56c 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -1183,6 +1183,49 @@ static int php_session_cache_limiter(TSRMLS_D) /* {{{ */
#define COOKIE_SECURE "; secure"
#define COOKIE_HTTPONLY "; HttpOnly"
+/*
+ * Remove already sent session ID cookie.
+ * It must be directly removed from SG(sapi_header) because sapi_add_header_ex()
+ * removes all of matching cookie. i.e. It deletes all of Set-Cookie headers.
+ */
+static void php_session_remove_cookie() {
+ sapi_header_struct *header;
+ zend_llist *l = &SG(sapi_headers).headers;
+ zend_llist_element *next;
+ zend_llist_element *current;
+ char *session_cookie, *e_session_name;
+ int session_cookie_len, len = sizeof("Set-Cookie")-1;
+
+ e_session_name = php_url_encode(PS(session_name), strlen(PS(session_name)), NULL);
+ spprintf(&session_cookie, 0, "Set-Cookie: %s=", e_session_name);
+ efree(e_session_name);
+
+ session_cookie_len = strlen(session_cookie);
+ current = l->head;
+ while (current) {
+ header = (sapi_header_struct *)(current->data);
+ next = current->next;
+ if (header->header_len > len && header->header[len] == ':'
+ && !strncmp(header->header, session_cookie, session_cookie_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;
+ }
+ efree(session_cookie);
+}
+
static void php_session_send_cookie(TSRMLS_D) /* {{{ */
{
smart_str ncookie = {0};
@@ -1248,7 +1291,8 @@ static void php_session_send_cookie(TSRMLS_D) /* {{{ */
smart_str_0(&ncookie);
- sapi_add_header_ex(ncookie.c, ncookie.len, 0, 1 TSRMLS_CC);
+ php_session_remove_cookie(); /* remove already sent session ID cookie */
+ sapi_add_header_ex(ncookie.c, ncookie.len, 0, 0 TSRMLS_CC);
}
/* }}} */
diff --git a/ext/session/tests/bug60634.phpt b/ext/session/tests/bug60634.phpt
index 69f3db4faa..86dcb11526 100644
--- a/ext/session/tests/bug60634.phpt
+++ b/ext/session/tests/bug60634.phpt
@@ -42,4 +42,5 @@ echo "um, hi\n";
?>
--EXPECTF--
write: goodbye cruel world
-close: goodbye cruel world \ No newline at end of file
+close: goodbye cruel world
+
diff --git a/ext/session/tests/bug60634_error_2.phpt b/ext/session/tests/bug60634_error_2.phpt
index 8ab0242b62..7c50948ba8 100644
--- a/ext/session/tests/bug60634_error_2.phpt
+++ b/ext/session/tests/bug60634_error_2.phpt
@@ -47,6 +47,6 @@ write: goodbye cruel world
Fatal error: Uncaught exception 'Exception' in %s
Stack trace:
#0 [internal function]: write('%s', '')
-#1 %s/ext/session/tests/bug60634_error_2.php(32): session_write_close()
+#1 %s(%d): session_write_close()
#2 {main}
- thrown in %s/ext/session/tests/bug60634_error_2.php on line 19 \ No newline at end of file
+ thrown in %s on line %d
diff --git a/ext/session/tests/bug60634_error_4.phpt b/ext/session/tests/bug60634_error_4.phpt
index d5e81b8abf..d0b5786af9 100644
--- a/ext/session/tests/bug60634_error_4.phpt
+++ b/ext/session/tests/bug60634_error_4.phpt
@@ -47,5 +47,6 @@ Fatal error: Uncaught exception 'Exception' in %s
Stack trace:
#0 [internal function]: write('%s', '')
#1 {main}
- thrown in %s/ext/session/tests/bug60634_error_4.php on line 20
-close: goodbye cruel world \ No newline at end of file
+ thrown in %s on line %d
+close: goodbye cruel world
+