From b5b6ddfa3fb84561cae213adbf5ac5f801089cf6 Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Sun, 31 Jan 2021 11:26:51 +0100 Subject: [PATCH 1/4] Add additional empty checks after field protection. --- system/BaseModel.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/system/BaseModel.php b/system/BaseModel.php index 42228d243375..6323c77667ed 100644 --- a/system/BaseModel.php +++ b/system/BaseModel.php @@ -728,6 +728,13 @@ public function insert($data = null, bool $returnID = true) // strip out created_at values. $data = $this->doProtectFields($data); + // doProtectFields() can further remove elements from + // $data so we need to check for empty dataset again + if (empty($data)) + { + throw DataException::forEmptyDataset('insert'); + } + // Set created_at and updated_at with same time $date = $this->setDate(); @@ -866,6 +873,13 @@ public function update($id = null, $data = null): bool // strip out updated_at values. $data = $this->doProtectFields($data); + // doProtectFields() can further remove elements from + // $data so we need to check for empty dataset again + if (empty($data)) + { + throw DataException::forEmptyDataset('update'); + } + if ($this->useTimestamps && $this->updatedField && ! array_key_exists($this->updatedField, $data)) { $data[$this->updatedField] = $this->setDate(); From b768a0e103896cafee08b44b234fbf016a0653cb Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Sun, 31 Jan 2021 12:55:02 +0100 Subject: [PATCH 2/4] Add tests for model update empty checks. --- tests/system/Models/UpdateModelTest.php | 67 +++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 4 deletions(-) diff --git a/tests/system/Models/UpdateModelTest.php b/tests/system/Models/UpdateModelTest.php index ce59a134486a..bb6b7875f832 100644 --- a/tests/system/Models/UpdateModelTest.php +++ b/tests/system/Models/UpdateModelTest.php @@ -260,6 +260,26 @@ public function testUpdateObjectWithDataException(): void $this->createModel(EventModel::class); $data = (object) [ + 'name' => 'Foo', + 'email' => 'foo@example.com', + 'country' => 'US', + 'deleted' => 0, + ]; + + $id = $this->model->insert($data); + + $data = new stdClass(); + + $this->expectException(DataException::class); + $this->expectExceptionMessage('There is no data to update.'); + $this->model->update($id, $data); + } + + public function testUpdateArrayWithDataExceptionNoAllowedFields(): void + { + $this->createModel(EventModel::class); + + $data = [ 'name' => 'Foo', 'email' => 'foo@example.com', 'country' => 'US', @@ -268,11 +288,50 @@ public function testUpdateObjectWithDataException(): void $id = $this->model->insert($data); - $data = new stdClass(); + $this->expectException(DataException::class); + $this->expectExceptionMessage('There is no data to update.'); + $this->model->update($id, ['thisKeyIsNotAllowed' => 'Bar']); + } + + public function testUpdateWithEntityNoAllowedFields(): void + { + $this->createModel(UserModel::class); + + $entity = new class extends Entity + { + protected $id; + protected $name; + protected $email; + protected $country; + protected $deleted; + protected $created_at; + protected $updated_at; + + protected $_options = [ + 'datamap' => [], + 'dates' => [ + 'created_at', + 'updated_at', + 'deleted_at', + ], + 'casts' => [], + ]; + }; + + $entity->id = 1; + $entity->name = 'Jones Martin'; + $entity->country = 'India'; + $entity->deleted = 0; + + $id = $this->model->insert($entity); + + $entity->syncOriginal(); + + $entity->fill(['thisKeyIsNotAllowed' => 'Bar']); $this->expectException(DataException::class); $this->expectExceptionMessage('There is no data to update.'); - $this->model->update($id, $data); + $this->model->update($id, $entity); } public function testUseAutoIncrementSetToFalseUpdate(): void @@ -301,9 +360,9 @@ public function testUpdateWithSetAndEscape(): void $this->assertTrue($this->model->set('country', '2+2', false)->set('email', '1+1')->update(1, $userData)); $this->seeInDatabase('user', [ - 'name' => 'Scott', + 'name' => 'Scott', 'country' => '4', - 'email' => '1+1', + 'email' => '1+1', ]); } } From a0ec0d7b7d866e9651e2aabcfc41569ec15820ff Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Sun, 31 Jan 2021 13:01:29 +0100 Subject: [PATCH 3/4] Add tests for model insert empty checks. --- tests/system/Models/InsertModelTest.php | 41 ++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/tests/system/Models/InsertModelTest.php b/tests/system/Models/InsertModelTest.php index 30597df42234..5306bb34e562 100644 --- a/tests/system/Models/InsertModelTest.php +++ b/tests/system/Models/InsertModelTest.php @@ -178,7 +178,7 @@ public function testInsertBatchNewEntityWithDateTime(): void $this->assertSame(2, $this->model->insertBatch([$entity, $entity])); } - public function testInsertArrayWithDataException(): void + public function testInsertArrayWithNoDataException(): void { $this->expectException(DataException::class); $this->expectExceptionMessage('There is no data to insert.'); @@ -193,6 +193,45 @@ public function testInsertObjectWithNoDataException(): void $this->createModel(UserModel::class)->insert($data); } + public function testInsertArrayWithNoDataExceptionNoAllowedData(): void + { + $this->expectException(DataException::class); + $this->expectExceptionMessage('There is no data to insert.'); + $this->createModel(UserModel::class)->insert(['thisKeyIsNotAllowed' => 'Bar']); + } + + public function testInsertEntityWithNoDataExceptionNoAllowedData(): void + { + $this->createModel(UserModel::class); + + $entity = new class extends Entity + { + protected $id; + protected $name; + protected $email; + protected $country; + protected $deleted; + protected $created_at; + protected $updated_at; + + protected $_options = [ + 'datamap' => [], + 'dates' => [ + 'created_at', + 'updated_at', + 'deleted_at', + ], + 'casts' => [], + ]; + }; + + $entity->fill(['thisKeyIsNotAllowed' => 'Bar']); + + $this->expectException(DataException::class); + $this->expectExceptionMessage('There is no data to insert.'); + $this->model->insert($entity); + } + public function testUseAutoIncrementSetToFalseInsertException(): void { $this->expectException(DataException::class); From 570951b52b935b74dccb8468e0088d3c04a312e1 Mon Sep 17 00:00:00 2001 From: Alex Schmitz Date: Sun, 31 Jan 2021 13:21:40 +0100 Subject: [PATCH 4/4] Fix CS. --- tests/system/Models/UpdateModelTest.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/system/Models/UpdateModelTest.php b/tests/system/Models/UpdateModelTest.php index bb6b7875f832..1aa7b7980b71 100644 --- a/tests/system/Models/UpdateModelTest.php +++ b/tests/system/Models/UpdateModelTest.php @@ -260,11 +260,11 @@ public function testUpdateObjectWithDataException(): void $this->createModel(EventModel::class); $data = (object) [ - 'name' => 'Foo', - 'email' => 'foo@example.com', - 'country' => 'US', - 'deleted' => 0, - ]; + 'name' => 'Foo', + 'email' => 'foo@example.com', + 'country' => 'US', + 'deleted' => 0, + ]; $id = $this->model->insert($data);