Skip to content

File::types() silently discards prior chain configuration when called as instance method #59242

@AnnoyingTechnology

Description

@AnnoyingTechnology

Laravel Version

12.51.0

PHP Version

8.4.18

Database Driver & Version

N/A

Description

File::types() is declared as a static factory method that returns new static(). When called in a fluent chain on an existing File or ImageFile instance, PHP invokes the static method, which creates a new instance, silently discarding all prior configuration (image(), max(), etc.).

This makes ->types() appear chainable but it is not. There is no warning, no runtime error, and no indication that prior constraints were dropped.

With extensions() which is an instance method returning $this, it chains correctly.

Any code using File::image()->max(...)->types(...) has no size validation and the constraint is silently dropped.

Steps To Reproduce

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\File;

$image = UploadedFile::fake()->image('photo.jpg', 800, 600);
// This file is ~8 KB

// max() BEFORE types() → max is silently lost
$v1 = Validator::make(
    ['file' => $image],
    ['file' => [File::image()->max(1)->types(['jpg', 'jpeg'])]]
);
var_dump($v1->fails()); // false — 8 KB file passes max:1KB!

// types() BEFORE max() → max works
$v2 = Validator::make(
    ['file' => $image],
    ['file' => [File::image()->types(['jpg', 'jpeg'])->max(1)]]
);
var_dump($v2->fails()); // true — correctly rejected

// Without types() → max works
$v3 = Validator::make(
    ['file' => $image],
    ['file' => [File::image()->max(1)]]
);
var_dump($v3->fails()); // true — correctly rejected

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions