Skip to content

Commit 11e3a8a

Browse files
committed
Marshaller should do mass assignment.
Setting properties one at a time bypasses the mass assignment protection. Since Marshaller is intended to handle convert user request data into entities, it should apply mass assignment protection rules.
1 parent bc8f1ce commit 11e3a8a

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

Cake/ORM/Marshaller.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ public function one(array $data, $include = []) {
9595
$data = $data[$tableName];
9696
}
9797

98+
$properties = [];
9899
foreach ($data as $key => $value) {
99100
$assoc = null;
100101
$nested = [];
@@ -105,8 +106,9 @@ public function one(array $data, $include = []) {
105106
if ($assoc) {
106107
$value = $this->_marshalAssociation($assoc, $value, $nested);
107108
}
108-
$entity->set($key, $value);
109+
$properties[$key] = $value;
109110
}
111+
$entity->set($properties);
110112
return $entity;
111113
}
112114

Cake/Test/TestCase/ORM/MarshallerTest.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,32 @@
1414
*/
1515
namespace Cake\Test\TestCase\ORM;
1616

17+
use Cake\ORM\Entity;
1718
use Cake\ORM\Marshaller;
1819
use Cake\ORM\Table;
1920
use Cake\ORM\TableRegistry;
2021
use Cake\TestSuite\TestCase;
2122

23+
24+
/**
25+
* Test entity for mass assignment.
26+
*/
27+
class OpenEntity extends Entity {
28+
protected $_accessible = [
29+
'*' => true,
30+
];
31+
}
32+
33+
/**
34+
* Test entity for mass assignment.
35+
*/
36+
class ProtectedArticle extends Entity {
37+
protected $_accessible = [
38+
'title' => true,
39+
'body' => true
40+
];
41+
}
42+
2243
/**
2344
* Marshaller test case
2445
*/
@@ -38,9 +59,14 @@ public function setUp() {
3859
$articles->hasMany('Comments');
3960

4061
$comments = TableRegistry::get('Comments');
62+
$users = TableRegistry::get('Users');
4163
$comments->belongsTo('Articles');
4264
$comments->belongsTo('Users');
4365

66+
$articles->entityClass(__NAMESPACE__ . '\OpenEntity');
67+
$comments->entityClass(__NAMESPACE__ . '\OpenEntity');
68+
$users->entityClass(__NAMESPACE__ . '\OpenEntity');
69+
4470
$this->articles = $articles;
4571
$this->comments = $comments;
4672
}
@@ -77,6 +103,27 @@ public function testOneSimple() {
77103
$this->assertNull($result->isNew(), 'Should be detached');
78104
}
79105

106+
/**
107+
* Test one() follows mass-assignment rules.
108+
*
109+
* @return void
110+
*/
111+
public function testOneAccessibleProperties() {
112+
$data = [
113+
'title' => 'My title',
114+
'body' => 'My content',
115+
'author_id' => 1,
116+
'not_in_schema' => true
117+
];
118+
$this->articles->entityClass(__NAMESPACE__ . '\ProtectedArticle');
119+
$marshall = new Marshaller($this->articles);
120+
$result = $marshall->one($data, []);
121+
122+
$this->assertInstanceOf(__NAMESPACE__ . '\ProtectedArticle', $result);
123+
$this->assertNull($result->author_id);
124+
$this->assertNull($result->not_in_schema);
125+
}
126+
80127
/**
81128
* test one() with a wrapping model name.
82129
*

0 commit comments

Comments
 (0)