From 5d1e4d3bc568598f5907f1642ea6a725adda0728 Mon Sep 17 00:00:00 2001 From: James Read Date: Tue, 22 Jul 2025 19:38:12 +0100 Subject: [PATCH 1/3] bug: adding unittest for guarded models Adding a unit test to cover edge cases where models exhibit inconsistent behaviour when the $guard property is empty but the $fillable is not. A MassAssignmentException is thrown. this happens because getGuarded in GuardsAttributes has two different mechanisms for unguarding a model. 1. $unguarded boolean property (default: false) 2. $guarded array property (default: ['*']) `getGuarded()` uses the $guarded and checks if it's false to return and empty array. `fillableFromArray()` uses $unguarded and $fillable properties to test if the model is unguarded. Both methods should use $unguarded for consistent behaviour. --- tests/Database/DatabaseEloquentModelTest.php | 23 ++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/tests/Database/DatabaseEloquentModelTest.php b/tests/Database/DatabaseEloquentModelTest.php index a085d3ea31e4..c2c440211b5a 100755 --- a/tests/Database/DatabaseEloquentModelTest.php +++ b/tests/Database/DatabaseEloquentModelTest.php @@ -10,7 +10,6 @@ use Illuminate\Contracts\Database\Eloquent\Castable; use Illuminate\Contracts\Database\Eloquent\CastsAttributes; use Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes; -use Illuminate\Contracts\Encryption\Encrypter; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Database\Connection; use Illuminate\Database\ConnectionResolverInterface; @@ -47,7 +46,6 @@ use Illuminate\Database\Query\Processors\Processor; use Illuminate\Support\Carbon; use Illuminate\Support\Collection as BaseCollection; -use Illuminate\Support\Facades\Crypt; use Illuminate\Support\Fluent; use Illuminate\Support\HtmlString; use Illuminate\Support\InteractsWithTime; @@ -1704,6 +1702,27 @@ public function testGuarded() Model::preventSilentlyDiscardingAttributes(false); } + public function testGuardedWithFillableConfig(): void + { + $model = new EloquentModelStub; + $model::unguard(); + + EloquentModelStub::setConnectionResolver($resolver = m::mock(Resolver::class)); + $resolver->shouldReceive('connection')->andReturn($connection = m::mock(stdClass::class)); + $connection->shouldReceive('getSchemaBuilder->getColumnListing')->andReturn(['name', 'age', 'foo']); + + $model->guard([]); + $model->fillable(['name']); + $model->fill(['name' => 'Leto Atreides', 'age' => 51]); + + self::assertSame( + ['name' => 'Leto Atreides', 'age' => 51], + $model->getAttributes(), + ); + + $model::reguard(); + } + public function testUsesOverriddenHandlerWhenDiscardingAttributes() { EloquentModelStub::setConnectionResolver($resolver = m::mock(Resolver::class)); From 8bb536fcc52c1e1c196dd1948d2f74ff66868a22 Mon Sep 17 00:00:00 2001 From: James Read Date: Tue, 22 Jul 2025 20:31:17 +0100 Subject: [PATCH 2/3] bug: changing getGuarded to use $unguarded --- src/Illuminate/Database/Eloquent/Concerns/GuardsAttributes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Database/Eloquent/Concerns/GuardsAttributes.php b/src/Illuminate/Database/Eloquent/Concerns/GuardsAttributes.php index 435c4947f769..51ba17d49735 100644 --- a/src/Illuminate/Database/Eloquent/Concerns/GuardsAttributes.php +++ b/src/Illuminate/Database/Eloquent/Concerns/GuardsAttributes.php @@ -75,7 +75,7 @@ public function mergeFillable(array $fillable) */ public function getGuarded() { - return $this->guarded === false + return self::$unguarded === true ? [] : $this->guarded; } From 2402d8eea583408f1c67a46fc8b7e71075205f6d Mon Sep 17 00:00:00 2001 From: James Read Date: Tue, 22 Jul 2025 21:28:16 +0100 Subject: [PATCH 3/3] feat: updatinng docblock --- .../Database/Eloquent/Concerns/GuardsAttributes.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Concerns/GuardsAttributes.php b/src/Illuminate/Database/Eloquent/Concerns/GuardsAttributes.php index 51ba17d49735..e09580db48df 100644 --- a/src/Illuminate/Database/Eloquent/Concerns/GuardsAttributes.php +++ b/src/Illuminate/Database/Eloquent/Concerns/GuardsAttributes.php @@ -14,7 +14,7 @@ trait GuardsAttributes /** * The attributes that aren't mass assignable. * - * @var array|bool + * @var array */ protected $guarded = ['*']; @@ -28,7 +28,7 @@ trait GuardsAttributes /** * The actual columns that exist on the database and can be guarded. * - * @var array + * @var array> */ protected static $guardableColumns = [];