laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
32.22k stars 10.91k forks source link

Validation in / not in breaks with values ending in backslash #50712

Closed vkwbpo closed 6 months ago

vkwbpo commented 6 months ago

Laravel Version

10.29.0

PHP Version

8.2.14

Database Driver & Version

No response

Description

In and NotIn validation rules do not work correctly for values ending in backslash.

Steps To Reproduce

Execute the following tinker commands:

Validator::make(['a' => 'b\\'], ['a' => Illuminate\Validation\Rule::notIn('b\\')])->passes();
Validator::make(['a' => 'b\\c'], ['a' => Illuminate\Validation\Rule::notIn('b\\c')])->passes();

First validator passes, seconds fails as expected. First should fail too.

github-actions[bot] commented 6 months ago

Thank you for reporting this issue!

As Laravel is an open source project, we rely on the community to help us diagnose and fix issues as it is not possible to research and fix every issue reported to us via GitHub.

If possible, please make a pull request fixing the issue you have described, along with corresponding tests. All pull requests are promptly reviewed by the Laravel team.

Thank you!

Katalam commented 6 months ago

The Validator uses the function str_getcsv($parameter) inside the validation cycle to hydrate the Validation Rules based on a string. In your example not_in:"b\" the problem is, that the function str_getcsv uses \" as an escape and enclose character. So the value the parser will output will be b\" and that is not b\ so the validation passes. I don't really have an idea on how to fix this

But the probleme is here: https://github.com/laravel/framework/blob/fc453b908fc41fea8b428260b2d4f3527d046bf8/src/Illuminate/Validation/ValidationRuleParser.php#L283

PaperTurtle commented 6 months ago

This might not be a pretty or perfect solution, but it seems to work.

protected static function parseParameters($rule, $parameter)
{
    return array_map(function ($param) { return str_replace('\\\\', '\\', $param); },
        static::ruleIsRegex($rule) ? [$parameter] : str_getcsv(str_replace('\\', '\\\\', $parameter), ',', '"', "\\")
    );
}

I don't know if there are any security concerns or if this might cause bugs for other cases. But it passes the tests

driesvints commented 6 months ago

Looks like for now, we're not going to support this, sorry.