Skip to content

Commit

Permalink
Making CookieComponent use json_encode instead of a custom
Browse files Browse the repository at this point in the history
serialization.  Fixes issues where values containing | or , would be
handled incorrectly.  Fixes #1593
  • Loading branch information
markstory committed Apr 19, 2011
1 parent 961208c commit d4ff392
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 47 deletions.
23 changes: 6 additions & 17 deletions lib/Cake/Controller/Component/CookieComponent.php
Expand Up @@ -459,31 +459,20 @@ protected function _decrypt($values) {
* Implode method to keep keys are multidimensional arrays
*
* @param array $array Map of key and values
* @return string String in the form key1|value1,key2|value2
* @return string A json encoded string.
*/
protected function _implode($array) {
$string = '';
foreach ($array as $key => $value) {
$string .= ',' . $key . '|' . $value;
}
return substr($string, 1);
protected function _implode(array $array) {
return json_encode($array);
}

/**
* Explode method to return array from string set in CookieComponent::_implode()
*
* @param string $string String in the form key1|value1,key2|value2
* @param string $string A string containing JSON encoded data, or a bare string.
* @return array Map of key and values
*/
protected function _explode($string) {
$array = array();
foreach (explode(',', $string) as $pair) {
$key = explode('|', $pair);
if (!isset($key[1])) {
return $key[0];
}
$array[$key[0]] = $key[1];
}
return $array;
$ret = json_decode($string, true);
return ($ret != null) ? $ret : $string;
}
}
75 changes: 45 additions & 30 deletions lib/Cake/tests/Case/Controller/Component/CookieComponentTest.php
Expand Up @@ -238,6 +238,19 @@ function testWritePlainCookieArray() {
$this->Cookie->delete('tag');
}

/**
* test writing values that are not scalars
*
* @return void
*/
function testWriteArrayValues() {
$this->Cookie->secure = false;
$this->Cookie->expects($this->once())->method('_setcookie')
->with('CakeTestCookie[Testing]', '[1,2,3]', time() + 10, '/', '', false, false);

$this->Cookie->write('Testing', array(1, 2, 3), false);
}

/**
* testReadingCookieValue
*
Expand Down Expand Up @@ -359,7 +372,6 @@ function testReadingCookieArray() {
* @return void
*/
function testReadingCookieDataOnStartup() {

$data = $this->Cookie->read('Encrytped_array');
$this->assertNull($data);

Expand All @@ -378,28 +390,29 @@ function testReadingCookieDataOnStartup() {
'name' => $this->__encrypt('CakePHP'),
'version' => $this->__encrypt('1.2.0.x'),
'tag' => $this->__encrypt('CakePHP Rocks!')),
'Plain_array' => 'name|CakePHP,version|1.2.0.x,tag|CakePHP Rocks!',
'Plain_array' => '{"name":"CakePHP","version":"1.2.0.x","tag":"CakePHP Rocks!"}',
'Plain_multi_cookies' => array(
'name' => 'CakePHP',
'version' => '1.2.0.x',
'tag' => 'CakePHP Rocks!'));

$this->Cookie->startup(null);

$data = $this->Cookie->read('Encrytped_array');
$expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' =>'CakePHP Rocks!');
$this->assertEqual($data, $expected);
$this->assertEquals($expected, $data);

$data = $this->Cookie->read('Encrytped_multi_cookies');
$expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' =>'CakePHP Rocks!');
$this->assertEqual($data, $expected);
$this->assertEquals($expected, $data);

$data = $this->Cookie->read('Plain_array');
$expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' =>'CakePHP Rocks!');
$this->assertEqual($data, $expected);
$this->assertEquals($expected, $data);

$data = $this->Cookie->read('Plain_multi_cookies');
$expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' =>'CakePHP Rocks!');
$this->assertEqual($data, $expected);
$this->assertEquals($expected, $data);
$this->Cookie->destroy();
unset($_COOKIE['CakeTestCookie']);
}
Expand All @@ -413,47 +426,47 @@ function testReadingCookieDataOnStartup() {
function testReadingCookieDataWithoutStartup() {
$data = $this->Cookie->read('Encrytped_array');
$expected = null;
$this->assertEqual($data, $expected);
$this->assertEquals($expected, $data);

$data = $this->Cookie->read('Encrytped_multi_cookies');
$expected = null;
$this->assertEqual($data, $expected);
$this->assertEquals($expected, $data);

$data = $this->Cookie->read('Plain_array');
$expected = null;
$this->assertEqual($data, $expected);
$this->assertEquals($expected, $data);

$data = $this->Cookie->read('Plain_multi_cookies');
$expected = null;
$this->assertEqual($data, $expected);
$this->assertEquals($expected, $data);

$_COOKIE['CakeTestCookie'] = array(
'Encrytped_array' => $this->__encrypt(array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' =>'CakePHP Rocks!')),
'Encrytped_multi_cookies' => array(
'name' => $this->__encrypt('CakePHP'),
'version' => $this->__encrypt('1.2.0.x'),
'tag' => $this->__encrypt('CakePHP Rocks!')),
'Plain_array' => 'name|CakePHP,version|1.2.0.x,tag|CakePHP Rocks!',
'Plain_array' => '{"name":"CakePHP","version":"1.2.0.x","tag":"CakePHP Rocks!"}',
'Plain_multi_cookies' => array(
'name' => 'CakePHP',
'version' => '1.2.0.x',
'tag' => 'CakePHP Rocks!'));

$data = $this->Cookie->read('Encrytped_array');
$expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' =>'CakePHP Rocks!');
$this->assertEqual($data, $expected);
$this->assertEquals($expected, $data);

$data = $this->Cookie->read('Encrytped_multi_cookies');
$expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' =>'CakePHP Rocks!');
$this->assertEqual($data, $expected);
$this->assertEquals($expected, $data);

$data = $this->Cookie->read('Plain_array');
$expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' =>'CakePHP Rocks!');
$this->assertEqual($data, $expected);
$this->assertEquals($expected, $data);

$data = $this->Cookie->read('Plain_multi_cookies');
$expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' =>'CakePHP Rocks!');
$this->assertEqual($data, $expected);
$this->assertEquals($expected, $data);
$this->Cookie->destroy();
unset($_COOKIE['CakeTestCookie']);
}
Expand All @@ -470,6 +483,22 @@ function testNoErrorOnNonArrayData() {

$this->assertNull($this->Cookie->read('value'));
}

/**
* Implode method to keep keys are multidimensional arrays
*
* @param array $array Map of key and values
* @return string String in the form key1|value1,key2|value2
*/
protected function _implode(array $array) {
return json_encode($array);

$string = '';
foreach ($array as $key => $value) {
$string .= ',' . $key . '|' . $value;
}
return substr($string, 1);
}

/**
* encrypt method
Expand All @@ -480,23 +509,9 @@ function testNoErrorOnNonArrayData() {
*/
function __encrypt($value) {
if (is_array($value)) {
$value = $this->__implode($value);
$value = $this->_implode($value);
}
return "Q2FrZQ==." . base64_encode(Security::cipher($value, $this->Cookie->key));
}

/**
* implode method
*
* @param array $value
* @return string
* @access private
*/
function __implode($array) {
$string = '';
foreach ($array as $key => $value) {
$string .= ',' . $key . '|' . $value;
}
return substr($string, 1);
}
}

0 comments on commit d4ff392

Please sign in to comment.