[13.x] Fix validation stalling for minutes on large arrays - #60908
Open
mariomka wants to merge 1 commit into
Open
[13.x] Fix validation stalling for minutes on large arrays#60908mariomka wants to merge 1 commit into
mariomka wants to merge 1 commit into
Conversation
mariomka
force-pushed
the
fix-validation-stalling-on-large-arrays
branch
from
July 27, 2026 15:47
7e53f55 to
d00b1ed
Compare
shaedrich
reviewed
Jul 27, 2026
Comment on lines
+235
to
+237
| * @param array $results | ||
| * @param string $attribute | ||
| * @param string|array $rules |
Contributor
There was a problem hiding this comment.
You can narrow this down a little:
Suggested change
| * @param array $results | |
| * @param string $attribute | |
| * @param string|array $rules | |
| * @param array<string, mixed> $results | |
| * @param string $attribute | |
| * @param string|array<string, mixed> $rules |
or even
Suggested change
| * @param array $results | |
| * @param string $attribute | |
| * @param string|array $rules | |
| * @param array<string, (string|\Illuminate\Contracts\Validation\Rule|\Illuminate\Validation\Rules\Exists|\Illuminate\Validation\Rules\Unique)[]> $results | |
| * @param string $attribute | |
| * @param string|array<string, string|\Illuminate\Validation\Rules\Date|\Illuminate\Validation\Rules\Numeric|\Illuminate\Validation\Rules\StringRule|(\Illuminate\Validation\Rules\Date|\Illuminate\Validation\Rules\Numeric|\Illuminate\Validation\Rules\StringRule|\Closure|\Illuminate\Contracts\Validation\InvokableRule|\Illuminate\Contracts\Validation\ValidationRule|\Illuminate\Contracts\Validation\Rule|\Illuminate\Validation\Rules\Exists|\Illuminate\Validation\Rules\Unique|Illuminate\Contracts\Validation\CompilableRules)[]> $rules |
Contributor
Author
There was a problem hiding this comment.
Thanks! I kept the docblock the same as mergeRulesForAttribute() and mergeRules() right above it. If I narrow only this one, it will be inconsistent with the rest of the class.
I think it's better to narrow the whole class in one go in a separate follow-up PR, and keep this one focused just on the performance fix.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
An ordinary request body can stall a request for over a minute. Expanding
foo.*.barrules is quadratic in the number of expanded attributes (array items × wildcard rules), soValidator::make()spends that time building the rule set before a single rule runs.post_max_sizeand web server body limits never trigger, 8000 items here is only ~1.1 MB.To reproduce, in
php artisan tinker:A
maxrule on the array does not help:'items' => ['array', 'max:500']still expands and evaluates everyitems.*rule before reporting that the array is too large.ValidationRuleParser::explodeWildcardRules()accumulates into$resultsby reassigning the return value ofmergeRules():mergeRulesForAttribute()receives$resultsby value and writes to it, so copy-on-write clones the whole accumulated rule set once per expanded attribute: 68,000 copies of an array averaging 34,000 entries for 17 rules over 4000 items.Validator::passes()itself is linear; all of the cost is in the expansion.The fix moves the merge body into a private method that takes
$resultsby reference, and the wildcard loop calls that instead of round-tripping through the by-valuemergeRules().No public or protected signatures change:
mergeRules()is untouched andmergeRulesForAttribute()keeps its exact signature and return value, delegating to the new private method.explodeWildcardRules()no longer routes through it, so an override there no longer affects wildcard expansion. This is unavoidable, since the by-value return is the bug itself.No new test, since the behaviour is unchanged and a timing assertion would be flaky.