Package home | Report new bug | New search | Development Roadmap Status: Open | Feedback | All | Closed Since Version 1.4.4

Bug #1080 Cookies UrlEncoded
Submitted: 2004-03-26 16:49 UTC Modified: 2006-12-26 22:54 UTC
From: eric_c_72 at yahoo dot com Assigned: avb
Status: Closed Package: HTTP_Request
PHP Version: 4.3.3 OS: Fedora
Roadmaps: (Not assigned)    
Subscription  


 [2004-03-26 16:49 UTC] eric_c_72 at yahoo dot com
Description: ------------ I had problem with an email address in a cookie where it was urlencoded. I was using a php script to request pages from a web server and when I passed my email address in a cookie to the web server it would recieve %40 instead of the @. I turned logging on for cookies on the web server and a browser sends the @ but my script sent a %40. Reproduce code: --------------- function addCookie($name, $value) { $cookies = isset($this->_requestHeaders['Cookie']) ? $this->_requestHeaders['Cookie']. '; ' : ''; # $this->addHeader('Cookie', $cookies . urlencode($name) . '=' . urlencode($value)); $this->addHeader('Cookie', $cookies . $name . '=' . $value); } Expected result: ---------------- The code above fixed the problem. Actual result: -------------- sent %40 instaed of @

Comments

 [2004-04-07 13:24 UTC] justinpatrin
According to thsi website: http://wp.netscape.com/newsref/std/cookie_spec.html only semi-colon, comma, and whitespace need to be encoded. Here's a patch for this: @@ -513,10 +513,30 @@ function addCookie($name, $value) { $cookies = isset($this->_requestHeaders['Cookie']) ? $this->_requestHeaders['Cookie']. '; ' : ''; - $this->addHeader('Cookie', $cookies . urlencode($name) . '=' . urlencode($value)); + $this->addHeader('Cookie', $cookies . $this->cookieEncode($name) . '=' . $this->cookieEncode($value)); } /** + * Encodes only those characters which are required to be encoded for cookies + * + * @param string string to encode + * @return string cookie encoded string + * @access public + */ + function cookieEncode($str) { + return str_replace(array(' ', + "\t", + ';', + ','), + array('%20', + '%09', + '%3B', + '%2C'), + $str); + + } + + /** * Clears any cookies that have been added (DEPRECATED). * * Useful for multiple request scenarios The newline, linefeed, vertical tab, and other whitespace chars may need to be encoded as well.
 [2004-04-07 13:30 UTC] justinpatrin
In my previous post I forgot about decoding ;-) Here's an updated diff. Beware: this is against by patch in bug 1152. --- Request.cvs.orig.php 2004-04-07 11:28:06.000000000 -0700 +++ Request.cvs.php 2004-04-07 11:36:52.000000000 -0700 @@ -513,10 +513,30 @@ function addCookie($name, $value) { $cookies = isset($this->_requestHeaders['Cookie']) ? $this->_requestHeaders['Cookie']. '; ' : ''; - $this->addHeader('Cookie', $cookies . urlencode($name) . '=' . urlencode($value)); + $this->addHeader('Cookie', $cookies . $this->cookieEncode($name) . '=' . $this->cookieEncode($value)); } /** + * Encodes only those characters which are required to be encoded for cookies + * + * @param string string to encode + * @return string cookie encoded string + * @access public + */ + function cookieEncode($str) { + return str_replace(array(' ', + "\t", + ';', + ','), + array('%20', + '%09', + '%3B', + '%2C'), + $str); + + } + + /** * Clears any cookies that have been added (DEPRECATED). * * Useful for multiple request scenarios @@ -979,6 +999,26 @@ } + /** + * Decodes only those characters which are required to be encoded for cookies + * + * @param string string to encode + * @return string cookie decoded string + * @access public + */ + function cookieDecode($str) { + return str_replace(array('%20', + '%09', + '%3B', + '%2C'), + array(' ', + "\t", + ';', + ','), + $str); + + } + /** * Parse a Set-Cookie header to fill $_cookies array * @@ -997,15 +1037,15 @@ // Only a name=value pair if (!strpos($headervalue, ';')) { list($cookie['name'], $cookie['value']) = array_map('trim', explode('=', $headervalue)); - $cookie['name'] = urldecode($cookie['name']); - $cookie['value'] = urldecode($cookie['value']); + $cookie['name'] = $this->cookieDecode($cookie['name']); + $cookie['value'] = $this->cookieDecode($cookie['value']); // Some optional parameters are supplied } else { $elements = explode(';', $headervalue); list($cookie['name'], $cookie['value']) = array_map('trim', explode('=', $elements[0])); - $cookie['name'] = urldecode($cookie['name']); - $cookie['value'] = urldecode($cookie['value']); + $cookie['name'] = $this->cookieDecode($cookie['name']); + $cookie['value'] = $this->cookieDecode($cookie['value']); for ($i = 1; $i < count($elements);$i++) { list ($elName, $elValue) = array_map('trim', explode('=', $elements[$i])); @@ -1015,7 +1055,7 @@ } elseif ('expires' == $elName) { $cookie['expires'] = str_replace('"', '', $elValue); } elseif ('path' == $elName OR 'domain' == $elName) { - $cookie[$elName] = urldecode($elValue); + $cookie[$elName] = $this->cookieDecode($elValue); } else { $cookie[$elName] = $elValue; }
 [2004-04-10 06:05 UTC] avb
I removed all encoding/decoding work on cookie name and value, as these are considered opaque for HTTP client.