Skip to content

[13.x] Fix TypeError in digits_between validation rule on non-string values#59717

Merged
taylorotwell merged 2 commits intolaravel:13.xfrom
sumaiazaman:fix/digits-between-type-error
Apr 16, 2026
Merged

[13.x] Fix TypeError in digits_between validation rule on non-string values#59717
taylorotwell merged 2 commits intolaravel:13.xfrom
sumaiazaman:fix/digits-between-type-error

Conversation

@sumaiazaman
Copy link
Copy Markdown
Contributor

Summary

This PR fixes a TypeError thrown by the digits_between validation rule when a non-string, non-numeric value (such as an array) is passed. The rule calls preg_match() directly on the value without first checking its type, causing PHP 8 to throw a TypeError instead of returning a clean validation failure.

Context

Several validation rules have already received this same fix:

Rule TypeError on non-string input Fixed
starts_with Str::startsWith() type-hint ✅ (merged in #59541)
ends_with Str::endsWith() type-hint ✅ (merged in #59541)
doesnt_start_with Str::startsWith() type-hint ✅ (merged in #59541)
doesnt_end_with Str::endsWith() type-hint ✅ (merged in #59541)
lowercase Str::lower() type-hint ✅ (merged in #59541)
uppercase Str::upper() type-hint ✅ (merged in #59541)
ascii Str::isAscii() ✅ (merged in #59541)
hex_color preg_match() on array ✅ (merged in #59541)
max_digits preg_match() on array ✅ (merged in #59541)
min_digits preg_match() on array ✅ (merged in #59541)
digits preg_match() on array ✅ (guarded inline)
digits_between preg_match() on array

digits_between is the only remaining rule in this family without a type guard. Its sibling digits is protected by an inline check — digits_between was simply missed.

Solution

Added the same is_string / is_numeric guard used in max_digits and min_digits:

if (! is_string($value) && ! is_numeric($value)) {
    return false;
}

Example

// Before: throws TypeError
$v = validator(['count' => ['a', 'b']], ['count' => 'digits_between:1,5']);
$v->passes(); // TypeError: preg_match(): Argument #2 ($subject) must be of type string

// After: returns a clean validation failure
$v->passes(); // false

Why This Doesn't Break Existing Features

  • Non-string, non-numeric values were already expected to fail digits_between — now they fail cleanly instead of throwing
  • All existing passing and failing cases for string and numeric input are unaffected
  • The fix is identical to the guard already used in max_digits, min_digits, and implicitly in digits

Changes

  • src/Illuminate/Validation/Concerns/ValidatesAttributes.php — Added type guard to validateDigitsBetween()
  • tests/Validation/ValidationValidatorTest.php — Added array assertion to testValidateDigits() and a dedicated testValidateDigitsBetweenDoesNotThrowOnNonStringValue() test

Test Plan

  • testValidateDigitsBetweenDoesNotThrowOnNonStringValue — Verifies array input returns false instead of throwing TypeError
  • testValidateDigits — Existing test updated with array case for digits_between
  • Existing tests pass (no breaking changes)

@taylorotwell taylorotwell merged commit 7f3aa1a into laravel:13.x Apr 16, 2026
54 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants