mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 03:18:26 +00:00
Ticket 4011 - Adding matchers support for Hash::remove() and Hash::insert()
This commit is contained in:
parent
6d45953525
commit
a0014e7a30
3 changed files with 104 additions and 13 deletions
|
@ -443,10 +443,10 @@ class CakeSessionTest extends CakeTestCase {
|
|||
public function testKeyExploit() {
|
||||
$key = "a'] = 1; phpinfo(); \$_SESSION['a";
|
||||
$result = TestCakeSession::write($key, 'haxored');
|
||||
$this->assertTrue($result);
|
||||
$this->assertFalse($result);
|
||||
|
||||
$result = TestCakeSession::read($key);
|
||||
$this->assertEquals('haxored', $result);
|
||||
$this->assertNull($result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1297,6 +1297,23 @@ class HashTest extends CakeTestCase {
|
|||
$result = Hash::insert($data, '{n}.Comment.{n}.insert', 'value');
|
||||
$this->assertEquals('value', $result[0]['Comment'][0]['insert']);
|
||||
$this->assertEquals('value', $result[0]['Comment'][1]['insert']);
|
||||
|
||||
$data = array(
|
||||
0 => array('Item' => array('id' => 1, 'title' => 'first')),
|
||||
1 => array('Item' => array('id' => 2, 'title' => 'second')),
|
||||
2 => array('Item' => array('id' => 3, 'title' => 'third')),
|
||||
3 => array('Item' => array('id' => 4, 'title' => 'fourth')),
|
||||
4 => array('Item' => array('id' => 5, 'title' => 'fifth')),
|
||||
);
|
||||
$result = Hash::insert($data, '{n}.Item[id=/\b2|\b4/]', array('test' => 2));
|
||||
$expected = array(
|
||||
0 => array('Item' => array('id' => 1, 'title' => 'first')),
|
||||
1 => array('Item' => array('id' => 2, 'title' => 'second', 'test' => 2)),
|
||||
2 => array('Item' => array('id' => 3, 'title' => 'third')),
|
||||
3 => array('Item' => array('id' => 4, 'title' => 'fourth', 'test' => 2)),
|
||||
4 => array('Item' => array('id' => 5, 'title' => 'fifth')),
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1360,6 +1377,23 @@ class HashTest extends CakeTestCase {
|
|||
$result = Hash::remove($a, 'pages.2.vars');
|
||||
$expected = $a;
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$a = array(
|
||||
0 => array(
|
||||
'name' => 'pages'
|
||||
),
|
||||
1 => array(
|
||||
'name' => 'files'
|
||||
)
|
||||
);
|
||||
|
||||
$result = Hash::remove($a, '{n}[name=files]');
|
||||
$expected = array(
|
||||
0 => array(
|
||||
'name' => 'pages'
|
||||
)
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1379,6 +1413,22 @@ class HashTest extends CakeTestCase {
|
|||
$this->assertFalse(isset($result[0]['Article']['user_id']));
|
||||
$this->assertFalse(isset($result[0]['Article']['title']));
|
||||
$this->assertFalse(isset($result[0]['Article']['body']));
|
||||
|
||||
$data = array(
|
||||
0 => array('Item' => array('id' => 1, 'title' => 'first')),
|
||||
1 => array('Item' => array('id' => 2, 'title' => 'second')),
|
||||
2 => array('Item' => array('id' => 3, 'title' => 'third')),
|
||||
3 => array('Item' => array('id' => 4, 'title' => 'fourth')),
|
||||
4 => array('Item' => array('id' => 5, 'title' => 'fifth')),
|
||||
);
|
||||
|
||||
$result = Hash::remove($data, '{n}.Item[id=/\b2|\b4/]');
|
||||
$expected = array(
|
||||
0 => array('Item' => array('id' => 1, 'title' => 'first')),
|
||||
2 => array('Item' => array('id' => 3, 'title' => 'third')),
|
||||
4 => array('Item' => array('id' => 5, 'title' => 'fifth')),
|
||||
);
|
||||
$this->assertEquals($result, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -109,12 +109,7 @@ class Hash {
|
|||
foreach ($tokens as $token) {
|
||||
$next = array();
|
||||
|
||||
$conditions = false;
|
||||
$position = strpos($token, '[');
|
||||
if ($position !== false) {
|
||||
$conditions = substr($token, $position);
|
||||
$token = substr($token, 0, $position);
|
||||
}
|
||||
list($token, $conditions) = self::_splitConditions($token);
|
||||
|
||||
foreach ($context[$_key] as $item) {
|
||||
foreach ((array)$item as $k => $v) {
|
||||
|
@ -139,6 +134,22 @@ class Hash {
|
|||
}
|
||||
return $context[$_key];
|
||||
}
|
||||
/**
|
||||
* Split token conditions
|
||||
*
|
||||
* @param string $token the token being splitted.
|
||||
* @return array array(token, conditions) with token splitted
|
||||
*/
|
||||
protected static function _splitConditions($token) {
|
||||
$conditions = false;
|
||||
$position = strpos($token, '[');
|
||||
if ($position !== false) {
|
||||
$conditions = substr($token, $position);
|
||||
$token = substr($token, 0, $position);
|
||||
}
|
||||
|
||||
return array($token, $conditions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a key against a token.
|
||||
|
@ -222,16 +233,31 @@ class Hash {
|
|||
* @return array The data with $values inserted.
|
||||
*/
|
||||
public static function insert(array $data, $path, $values = null) {
|
||||
$tokens = explode('.', $path);
|
||||
if (strpos($path, '{') === false) {
|
||||
if (strpos($path, '[') === false) {
|
||||
$tokens = explode('.', $path);
|
||||
} else {
|
||||
$tokens = String::tokenize($path, '.', '[', ']');
|
||||
}
|
||||
|
||||
if (strpos($path, '{') === false && strpos($path, '[') === false) {
|
||||
return self::_simpleOp('insert', $data, $tokens, $values);
|
||||
}
|
||||
|
||||
$token = array_shift($tokens);
|
||||
$nextPath = implode('.', $tokens);
|
||||
|
||||
list($token, $conditions) = self::_splitConditions($token);
|
||||
|
||||
foreach ($data as $k => $v) {
|
||||
if (self::_matchToken($k, $token)) {
|
||||
$data[$k] = self::insert($v, $nextPath, $values);
|
||||
if ($conditions) {
|
||||
if (self::_matches($v, $conditions)) {
|
||||
$data[$k] = array_merge($v, $values);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
$data[$k] = self::insert($v, $nextPath, $values);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
|
@ -290,17 +316,32 @@ class Hash {
|
|||
* @return array The modified array.
|
||||
*/
|
||||
public static function remove(array $data, $path) {
|
||||
$tokens = explode('.', $path);
|
||||
if (strpos($path, '{') === false) {
|
||||
if (strpos($path, '[') === false) {
|
||||
$tokens = explode('.', $path);
|
||||
} else {
|
||||
$tokens = String::tokenize($path, '.', '[', ']');
|
||||
}
|
||||
|
||||
if (strpos($path, '{') === false && strpos($path, '[') === false) {
|
||||
return self::_simpleOp('remove', $data, $tokens);
|
||||
}
|
||||
|
||||
$token = array_shift($tokens);
|
||||
$nextPath = implode('.', $tokens);
|
||||
|
||||
list($token, $conditions) = self::_splitConditions($token);
|
||||
|
||||
foreach ($data as $k => $v) {
|
||||
$match = self::_matchToken($k, $token);
|
||||
if ($match && is_array($v)) {
|
||||
if ($conditions && self::_matches($v, $conditions)) {
|
||||
unset($data[$k]);
|
||||
continue;
|
||||
}
|
||||
$data[$k] = self::remove($v, $nextPath);
|
||||
if (empty($data[$k])) {
|
||||
unset($data[$k]);
|
||||
}
|
||||
} elseif ($match) {
|
||||
unset($data[$k]);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue