Skip to content

Commit 897d107

Browse files
authored
[6.x] Verify column names are actual columns when using guarded (#33777)
* verify column names are actual columns when using guarded * Apply fixes from StyleCI (#33778) * remove json check
1 parent 7a74817 commit 897d107

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

src/Illuminate/Database/Eloquent/Concerns/GuardsAttributes.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ trait GuardsAttributes
2727
*/
2828
protected static $unguarded = false;
2929

30+
/**
31+
* The actual columns that exist on the database and can be guarded.
32+
*
33+
* @var array
34+
*/
35+
protected static $guardableColumns = [];
36+
3037
/**
3138
* Get the fillable attributes for the model.
3239
*
@@ -164,12 +171,30 @@ public function isFillable($key)
164171
*/
165172
public function isGuarded($key)
166173
{
167-
if (strpos($key, '->') !== false) {
168-
$key = Str::before($key, '->');
174+
if (empty($this->getGuarded())) {
175+
return false;
169176
}
170177

171178
return $this->getGuarded() == ['*'] ||
172-
! empty(preg_grep('/^'.preg_quote($key).'$/i', $this->getGuarded()));
179+
! empty(preg_grep('/^'.preg_quote($key).'$/i', $this->getGuarded())) ||
180+
! $this->isGuardableColumn($key);
181+
}
182+
183+
/**
184+
* Determine if the given column is a valid, guardable column.
185+
*
186+
* @param string $key
187+
* @return bool
188+
*/
189+
protected function isGuardableColumn($key)
190+
{
191+
if (! isset(static::$guardableColumns[get_class($this)])) {
192+
static::$guardableColumns[get_class($this)] = $this->getConnection()
193+
->getSchemaBuilder()
194+
->getColumnListing($this->getTable());
195+
}
196+
197+
return in_array($key, static::$guardableColumns[get_class($this)]);
173198
}
174199

175200
/**

tests/Database/DatabaseEloquentModelTest.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Illuminate\Contracts\Events\Dispatcher;
1111
use Illuminate\Database\Connection;
1212
use Illuminate\Database\ConnectionResolverInterface;
13+
use Illuminate\Database\ConnectionResolverInterface as Resolver;
1314
use Illuminate\Database\Eloquent\Builder;
1415
use Illuminate\Database\Eloquent\Collection;
1516
use Illuminate\Database\Eloquent\JsonEncodingException;
@@ -1014,11 +1015,21 @@ public function testUnderscorePropertiesAreNotFilled()
10141015
public function testGuarded()
10151016
{
10161017
$model = new EloquentModelStub;
1018+
1019+
EloquentModelStub::setConnectionResolver($resolver = m::mock(Resolver::class));
1020+
$resolver->shouldReceive('connection')->andReturn($connection = m::mock(stdClass::class));
1021+
$connection->shouldReceive('getSchemaBuilder->getColumnListing')->andReturn(['name', 'age', 'foo']);
1022+
10171023
$model->guard(['name', 'age']);
10181024
$model->fill(['name' => 'foo', 'age' => 'bar', 'foo' => 'bar']);
10191025
$this->assertFalse(isset($model->name));
10201026
$this->assertFalse(isset($model->age));
10211027
$this->assertSame('bar', $model->foo);
1028+
1029+
$model = new EloquentModelStub;
1030+
$model->guard(['name', 'age']);
1031+
$model->fill(['Foo' => 'bar']);
1032+
$this->assertFalse(isset($model->Foo));
10221033
}
10231034

10241035
public function testFillableOverridesGuarded()
@@ -2134,7 +2145,7 @@ public function getDates()
21342145
class EloquentModelSaveStub extends Model
21352146
{
21362147
protected $table = 'save_stub';
2137-
protected $guarded = ['id'];
2148+
protected $guarded = [];
21382149

21392150
public function save(array $options = [])
21402151
{

0 commit comments

Comments
 (0)