Skip to content

Password validation rule fails on valid data if reused #38949

Closed
@hbgl

Description

@hbgl
  • Laravel Version: 8.54
  • PHP Version: 8.0.11
  • Database Driver & Version: n/a

Description:

If a Password validation rule fails once and the same rule object is later reused, then it will continue to fail on any subsequent validation run even if the input is valid.

Steps To Reproduce:

$rules = [
    'password' => Password::default(),
];

$validator1 = Validator::make(['password' => '1234'], $rules);
// Validation fails as expected: Password too short.
$this->assertTrue($validator1->fails());

$validator2 = Validator::make(['password' => '12341234'], $rules);
// Should pass, but it does not. Validation fails again with: Password too short.
$this->assertFalse($validator2->fails());

https://github.com/hbgl/laravel-validation-password-stateful

Suggested fix

TLDR: Clear the $messages field inside the Password class on each call to passes.

The Password rule internally keeps a list or messages that are populated within the passes function. The messages are, however, not reset upon repeated calls to passes, which causes the rule to fail on valid data with the same error messages as before. The messages should be reset each time the passes function is called.

I think it is generally good practice for validation rules to not carry observable state over multiple validation runs. That means that a rule should either be completely stateless or carefully reset itself when called again. Maybe this should also be mentioned as a warning in the custom validation rules documentation

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions