Skip to content

Commit d4ff392

Browse files
committed
Making CookieComponent use json_encode instead of a custom
serialization. Fixes issues where values containing | or , would be handled incorrectly. Fixes #1593
1 parent 961208c commit d4ff392

File tree

2 files changed

+51
-47
lines changed

2 files changed

+51
-47
lines changed

lib/Cake/Controller/Component/CookieComponent.php

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -459,31 +459,20 @@ protected function _decrypt($values) {
459459
* Implode method to keep keys are multidimensional arrays
460460
*
461461
* @param array $array Map of key and values
462-
* @return string String in the form key1|value1,key2|value2
462+
* @return string A json encoded string.
463463
*/
464-
protected function _implode($array) {
465-
$string = '';
466-
foreach ($array as $key => $value) {
467-
$string .= ',' . $key . '|' . $value;
468-
}
469-
return substr($string, 1);
464+
protected function _implode(array $array) {
465+
return json_encode($array);
470466
}
471467

472468
/**
473469
* Explode method to return array from string set in CookieComponent::_implode()
474470
*
475-
* @param string $string String in the form key1|value1,key2|value2
471+
* @param string $string A string containing JSON encoded data, or a bare string.
476472
* @return array Map of key and values
477473
*/
478474
protected function _explode($string) {
479-
$array = array();
480-
foreach (explode(',', $string) as $pair) {
481-
$key = explode('|', $pair);
482-
if (!isset($key[1])) {
483-
return $key[0];
484-
}
485-
$array[$key[0]] = $key[1];
486-
}
487-
return $array;
475+
$ret = json_decode($string, true);
476+
return ($ret != null) ? $ret : $string;
488477
}
489478
}

lib/Cake/tests/Case/Controller/Component/CookieComponentTest.php

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,19 @@ function testWritePlainCookieArray() {
238238
$this->Cookie->delete('tag');
239239
}
240240

241+
/**
242+
* test writing values that are not scalars
243+
*
244+
* @return void
245+
*/
246+
function testWriteArrayValues() {
247+
$this->Cookie->secure = false;
248+
$this->Cookie->expects($this->once())->method('_setcookie')
249+
->with('CakeTestCookie[Testing]', '[1,2,3]', time() + 10, '/', '', false, false);
250+
251+
$this->Cookie->write('Testing', array(1, 2, 3), false);
252+
}
253+
241254
/**
242255
* testReadingCookieValue
243256
*
@@ -359,7 +372,6 @@ function testReadingCookieArray() {
359372
* @return void
360373
*/
361374
function testReadingCookieDataOnStartup() {
362-
363375
$data = $this->Cookie->read('Encrytped_array');
364376
$this->assertNull($data);
365377

@@ -378,28 +390,29 @@ function testReadingCookieDataOnStartup() {
378390
'name' => $this->__encrypt('CakePHP'),
379391
'version' => $this->__encrypt('1.2.0.x'),
380392
'tag' => $this->__encrypt('CakePHP Rocks!')),
381-
'Plain_array' => 'name|CakePHP,version|1.2.0.x,tag|CakePHP Rocks!',
393+
'Plain_array' => '{"name":"CakePHP","version":"1.2.0.x","tag":"CakePHP Rocks!"}',
382394
'Plain_multi_cookies' => array(
383395
'name' => 'CakePHP',
384396
'version' => '1.2.0.x',
385397
'tag' => 'CakePHP Rocks!'));
398+
386399
$this->Cookie->startup(null);
387400

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

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

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

400413
$data = $this->Cookie->read('Plain_multi_cookies');
401414
$expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' =>'CakePHP Rocks!');
402-
$this->assertEqual($data, $expected);
415+
$this->assertEquals($expected, $data);
403416
$this->Cookie->destroy();
404417
unset($_COOKIE['CakeTestCookie']);
405418
}
@@ -413,47 +426,47 @@ function testReadingCookieDataOnStartup() {
413426
function testReadingCookieDataWithoutStartup() {
414427
$data = $this->Cookie->read('Encrytped_array');
415428
$expected = null;
416-
$this->assertEqual($data, $expected);
429+
$this->assertEquals($expected, $data);
417430

418431
$data = $this->Cookie->read('Encrytped_multi_cookies');
419432
$expected = null;
420-
$this->assertEqual($data, $expected);
433+
$this->assertEquals($expected, $data);
421434

422435
$data = $this->Cookie->read('Plain_array');
423436
$expected = null;
424-
$this->assertEqual($data, $expected);
437+
$this->assertEquals($expected, $data);
425438

426439
$data = $this->Cookie->read('Plain_multi_cookies');
427440
$expected = null;
428-
$this->assertEqual($data, $expected);
441+
$this->assertEquals($expected, $data);
429442

430443
$_COOKIE['CakeTestCookie'] = array(
431444
'Encrytped_array' => $this->__encrypt(array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' =>'CakePHP Rocks!')),
432445
'Encrytped_multi_cookies' => array(
433446
'name' => $this->__encrypt('CakePHP'),
434447
'version' => $this->__encrypt('1.2.0.x'),
435448
'tag' => $this->__encrypt('CakePHP Rocks!')),
436-
'Plain_array' => 'name|CakePHP,version|1.2.0.x,tag|CakePHP Rocks!',
449+
'Plain_array' => '{"name":"CakePHP","version":"1.2.0.x","tag":"CakePHP Rocks!"}',
437450
'Plain_multi_cookies' => array(
438451
'name' => 'CakePHP',
439452
'version' => '1.2.0.x',
440453
'tag' => 'CakePHP Rocks!'));
441454

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

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

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

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

471484
$this->assertNull($this->Cookie->read('value'));
472485
}
486+
487+
/**
488+
* Implode method to keep keys are multidimensional arrays
489+
*
490+
* @param array $array Map of key and values
491+
* @return string String in the form key1|value1,key2|value2
492+
*/
493+
protected function _implode(array $array) {
494+
return json_encode($array);
495+
496+
$string = '';
497+
foreach ($array as $key => $value) {
498+
$string .= ',' . $key . '|' . $value;
499+
}
500+
return substr($string, 1);
501+
}
473502

474503
/**
475504
* encrypt method
@@ -480,23 +509,9 @@ function testNoErrorOnNonArrayData() {
480509
*/
481510
function __encrypt($value) {
482511
if (is_array($value)) {
483-
$value = $this->__implode($value);
512+
$value = $this->_implode($value);
484513
}
485514
return "Q2FrZQ==." . base64_encode(Security::cipher($value, $this->Cookie->key));
486515
}
487516

488-
/**
489-
* implode method
490-
*
491-
* @param array $value
492-
* @return string
493-
* @access private
494-
*/
495-
function __implode($array) {
496-
$string = '';
497-
foreach ($array as $key => $value) {
498-
$string .= ',' . $key . '|' . $value;
499-
}
500-
return substr($string, 1);
501-
}
502517
}

0 commit comments

Comments
 (0)