From 62e89734ab23527b7f7b9f7f56a3d559b54e6e3e Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 21 Dec 2013 17:46:05 -0500 Subject: [PATCH] Throw exceptions from Hash::combine() When the key + value counts do not match Hash should throw an exception. Silently doing the wrong thing is generally not a good idea. While this change could break existing applications, those applications were probably behaving incorrectly anyways. Fixes #2470 --- lib/Cake/Test/Case/Utility/HashTest.php | 28 +++++++++++++++++++++++++ lib/Cake/Utility/Hash.php | 11 +++++++--- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/lib/Cake/Test/Case/Utility/HashTest.php b/lib/Cake/Test/Case/Utility/HashTest.php index 26bde007c..9ba6f8043 100644 --- a/lib/Cake/Test/Case/Utility/HashTest.php +++ b/lib/Cake/Test/Case/Utility/HashTest.php @@ -1473,6 +1473,34 @@ class HashTest extends CakeTestCase { $this->assertEquals($expected, $result); } +/** + * test combine() giving errors on key/value length mismatches. + * + * @expectedException CakeException + * @return void + */ + public function testCombineErrorMissingValue() { + $data = array( + array('User' => array('id' => 1, 'name' => 'mark')), + array('User' => array('name' => 'jose')), + ); + Hash::combine($data, '{n}.User.id', '{n}.User.name'); + } + +/** + * test combine() giving errors on key/value length mismatches. + * + * @expectedException CakeException + * @return void + */ + public function testCombineErrorMissingKey() { + $data = array( + array('User' => array('id' => 1, 'name' => 'mark')), + array('User' => array('id' => 2)), + ); + Hash::combine($data, '{n}.User.id', '{n}.User.name'); + } + /** * test combine() with a group path. * diff --git a/lib/Cake/Utility/Hash.php b/lib/Cake/Utility/Hash.php index 1cfe45d45..6496c095f 100644 --- a/lib/Cake/Utility/Hash.php +++ b/lib/Cake/Utility/Hash.php @@ -346,10 +346,15 @@ class Hash { } elseif (!empty($valuePath)) { $vals = self::extract($data, $valuePath); } + if (empty($vals)) { + $vals = array_fill(0, count($keys), null); + } - $count = count($keys); - for ($i = 0; $i < $count; $i++) { - $vals[$i] = isset($vals[$i]) ? $vals[$i] : null; + if (count($keys) !== count($vals)) { + throw new CakeException(__d( + 'cake_dev', + 'Hash::combine() needs an equal number of keys + values.' + )); } if ($groupPath !== null) {