#32802 [Csd->Asn]: General cookie overrides more specific cookie (path)
| From: | rasmus@php.net | Date: | Fri, 13 May 2005 13:48:26 +0000 |
| Subject: | #32802 [Csd->Asn]: General cookie overrides more specific cookie (path) | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-78981@lists.php.net to get a copy of this message | ||
ID: 32802
Updated by: rasmus@php.net
Reported By: ast at gmx dot ch
-Status: Closed
+Status: Assigned
Bug Type: HTTP related
Operating System: *
PHP Version: 4.*, 5.*
-Assigned To:
+Assigned To: ilia
New Comment:
Ilia, I reverted the PHP4 version of your patch to fix this. It
seems to be fine in PHP5, but in PHP4 it is causing a segfault. Could
you have another look?
See the backtrace in the commit message at:
http://cvs.php.net/php-src/main/php_variables.c?onb=1.45.2
Previous Comments:
------------------------------------------------------------------------
[2005-04-24 20:50:45] iliaa@php.net
This bug has been fixed in CVS.
Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
Thank you for the report, and for helping us make PHP better.
------------------------------------------------------------------------
[2005-04-24 16:25:15] ast at gmx dot ch
Your reproduce script does not describe this bug.
Your script describes a Server -> Browser issue.
This bug is about a Browser -> Server issue. The browser sends a Cookie
HTTP header with its request to the server.
The Cookie HTTP request header lists the cookies in the right order.
Cookies with more specific paths precede cookies with less specific
paths in the header string.
PHP populates the superglobal $_COOKIE with the wrong values when
reading/evaluating the Cookie HTTP header.
This The following reproduce script shows the PHP bug.
Please place it into document_root / test.
<?php
/* This script has to be executed in document_root/test/ or deeper */
/* set the first cookie with path '/' */
if (!isset($_COOKIE['TestCookie'])) {
setcookie("TestCookie", "Value1", time()+3600, "/");
header("Location: {$_SERVER['PHP_SELF']}");
exit();
}
/*
* set second cookie, with a more specific path, actually, the order in
which the cookies are set
* is irrelevant
*/
if (!strpos($_SERVER['HTTP_COOKIE'], 'Value2')) {
setcookie("TestCookie", "Value2", time()+3600, "/test");
header("Location: {$_SERVER['PHP_SELF']}");
exit();
}
echo '$_COOKIE[\'TestCookie\'] should have the value \'Value2\' because
it\'s the value of the cookie with the more specific path.<pre>';
var_dump($_COOKIE);
echo '</pre><br>';
echo '$_SERVER[\'HTTP_COOKIE\'] lists the cookies in the correct order,
Value2 before Value1. It conforms to RFC 2965.<pre>';
var_dump($_SERVER['HTTP_COOKIE']);
echo '</pre>';
?>
------------------------------------------------------------------------
[2005-04-24 14:01:21] sniper@php.net
Reproduce script:
<?php
setcookie("TestCookie", "Value1", time()+3600, "/test/");
setcookie("TestCookie", "Value2", time()+3600, "/");
if (!isset($_COOKIE['TestCookie'])) {
header("Location: {$_SERVER['PHP_SELF']}");
exit();
}
echo '<pre>';
var_dump($_COOKIE);
var_dump($_SERVER['HTTP_COOKIE']);
echo '</pre>';
?>
------------------------------------------------------------------------
[2005-04-24 03:21:37] ast at gmx dot ch
Here is a fix for my application.
/**
* Fix the superglobal $_COOKIE to conform with RFC 2965
*
* We don't use $_COOKIE[$cookiename], because it doesn't conform
to RFC 2965 (the
* cookie standard), i.e. in $_COOKIE, we don't get the cookie with
the most specific path for
* a given cookie name, we get the cookie with the least specific
cookie path.
* This function does it exactly the other way around to conform
with the RFC.
*
* This function reevaluates the HTTP Cookie header and populates
$_COOKIE with the correct
* cookies.
*
* @static
*/
function fixCookieVars() {
if (isset($_SERVER['HTTP_COOKIE']) &&
!empty($_SERVER['HTTP_COOKIE'])) {
$allCookies = explode(';', $_SERVER['HTTP_COOKIE']);
/*
* Get rid of less specific cookies if multiple cookies with the same
NAME
* are present. Do this by going from left/first cookie to right/last
cookie.
*/
/* Reset the $_COOKIE array */
$_COOKIE = array();
/* Repopulate it, but now correctly */
foreach ($allCookies as $cookie) {
/* Split NAME [=VALUE], value is optional */
$cookie = explode('=', $cookie);
$key = preg_replace('|\s|', '', $cookie[0]);
$value = isset($cookie[1]) ? $cookie[1] : '';
if (!isset($_COOKIE[$key])) {
$_COOKIE[$key] = $value;
}
}
}
}
}
------------------------------------------------------------------------
[2005-04-24 00:43:04] ast at gmx dot ch
the bug report that was closed as bogus (sorry, forgot to add the link.
originally, i wanted to add a comment there, but you can't add comments
to bugs that are marked as "bogus".
http://bugs.php.net/bug.php?id=18337
obviously, this isn't "bogus", as php doesn't comply with the RFC 2965
(and all common browsers comply with this RFC concerning the order of
the cookies).
How to reproduce:
See Example 2 of RFC 2965:
2 cookies, with the same NAME, but a different PATH.
It's about the precedence of cookies. Cookies with a more specific path
have precedence over cookies with less specific paths.
See Example 2 of the RFC, it's nicely explained there.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
http://bugs.php.net/32802
--
Edit this bug report at http://bugs.php.net/?id=32802&edit=1