Skip to content

Commit dd7a139

Browse files
authored
Merge pull request #7759 from kenjis/fix-model-insertBatch-noAutoIncrement
fix: Model::insertBatch() causes error to non auto increment table
2 parents de129dc + a2c4749 commit dd7a139

File tree

3 files changed

+75
-4
lines changed

3 files changed

+75
-4
lines changed

system/BaseModel.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -853,7 +853,7 @@ public function insertBatch(?array $set = null, ?bool $escape = null, int $batch
853853

854854
// Must be called first so we don't
855855
// strip out created_at values.
856-
$row = $this->doProtectFields($row);
856+
$row = $this->doProtectFieldsForInsert($row);
857857

858858
// Set created_at and updated_at with same time
859859
$date = $this->setDate();
@@ -1228,10 +1228,10 @@ public function protect(bool $protect = true)
12281228
}
12291229

12301230
/**
1231-
* Ensures that only the fields that are allowed to be updated
1232-
* are in the data array.
1231+
* Ensures that only the fields that are allowed to be updated are
1232+
* in the data array.
12331233
*
1234-
* Used by insert() and update() to protect against mass assignment
1234+
* Used by update() and updateBatch() to protect against mass assignment
12351235
* vulnerabilities.
12361236
*
12371237
* @param array $data Data
@@ -1257,6 +1257,22 @@ protected function doProtectFields(array $data): array
12571257
return $data;
12581258
}
12591259

1260+
/**
1261+
* Ensures that only the fields that are allowed to be inserted are in
1262+
* the data array.
1263+
*
1264+
* Used by insert() and insertBatch() to protect against mass assignment
1265+
* vulnerabilities.
1266+
*
1267+
* @param array $data Data
1268+
*
1269+
* @throws DataException
1270+
*/
1271+
protected function doProtectFieldsForInsert(array $data): array
1272+
{
1273+
return $this->doProtectFields($data);
1274+
}
1275+
12601276
/**
12611277
* Sets the date or current date if null value is passed.
12621278
*

system/Model.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,41 @@ public function insert($data = null, bool $returnID = true)
734734
return parent::insert($data, $returnID);
735735
}
736736

737+
/**
738+
* Ensures that only the fields that are allowed to be inserted are in
739+
* the data array.
740+
*
741+
* Used by insert() and insertBatch() to protect against mass assignment
742+
* vulnerabilities.
743+
*
744+
* @param array $data Data
745+
*
746+
* @throws DataException
747+
*/
748+
protected function doProtectFieldsForInsert(array $data): array
749+
{
750+
if (! $this->protectFields) {
751+
return $data;
752+
}
753+
754+
if (empty($this->allowedFields)) {
755+
throw DataException::forInvalidAllowedFields(static::class);
756+
}
757+
758+
foreach (array_keys($data) as $key) {
759+
// Do not remove the non-auto-incrementing primary key data.
760+
if ($this->useAutoIncrement === false && $key === $this->primaryKey) {
761+
continue;
762+
}
763+
764+
if (! in_array($key, $this->allowedFields, true)) {
765+
unset($data[$key]);
766+
}
767+
}
768+
769+
return $data;
770+
}
771+
737772
/**
738773
* Updates a single record in the database. If an object is provided,
739774
* it will attempt to convert it into an array.

tests/system/Models/InsertModelTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,26 @@ public function testInsertBatchSuccess(): void
6565
$this->seeInDatabase('job', ['name' => 'Cab Driver']);
6666
}
6767

68+
public function testInsertBatchUseAutoIncrementSetToFalse(): void
69+
{
70+
$insertData = [
71+
[
72+
'key' => 'key1',
73+
'value' => 'value1',
74+
],
75+
[
76+
'key' => 'key2',
77+
'value' => 'value2',
78+
],
79+
];
80+
81+
$this->createModel(WithoutAutoIncrementModel::class);
82+
$this->model->insertBatch($insertData);
83+
84+
$this->seeInDatabase('without_auto_increment', ['key' => 'key1']);
85+
$this->seeInDatabase('without_auto_increment', ['key' => 'key2']);
86+
}
87+
6888
public function testInsertBatchValidationFail(): void
6989
{
7090
$jobData = [

0 commit comments

Comments
 (0)