Skip to content

[13.x] Cast to string before preg_match in decimal, max_digits, and min_digits rules#59739

Merged
taylorotwell merged 2 commits intolaravel:13.xfrom
sumaiazaman:fix/validation-preg-match-type-cast
Apr 17, 2026
Merged

[13.x] Cast to string before preg_match in decimal, max_digits, and min_digits rules#59739
taylorotwell merged 2 commits intolaravel:13.xfrom
sumaiazaman:fix/validation-preg-match-type-cast

Conversation

@sumaiazaman
Copy link
Copy Markdown
Contributor

Summary

  • validateDecimal, validateMaxDigits, and validateMinDigits now explicitly cast the value to string before passing it to preg_match

Context

Rule Before After
decimal preg_match('/^[+-]?\d*\.?(\d*)$/', $value, ...) preg_match('/^[+-]?\d*\.?(\d*)$/', (string) $value, ...)
max_digits preg_match('/[^0-9]/', $value) preg_match('/[^0-9]/', (string) $value)
min_digits preg_match('/[^0-9]/', $value) preg_match('/[^0-9]/', (string) $value)

All three rules already check is_string($value) || is_numeric($value) before the preg_match call, so numeric types are valid inputs. The strlen() call in the same methods already casts with (string) $value — making preg_match the only place relying on PHP's implicit cast.

This follows the same convention used in validateAlphaDash and validateAlphaNum, and matches the fix applied to validateDigitsBetween previously.

Solution

Added an explicit (string) cast to the $value argument in each preg_match call.

Example

Before:

// preg_match relied on PHP's implicit cast of int/float to string
$v = new Validator($trans, ['foo' => 123], ['foo' => 'decimal:0']);
// worked by accident, but explicit cast makes the intent clear

After:

// The value is explicitly cast to string — no reliance on implicit coercion
preg_match('/^[+-]?\d*\.?(\d*)$/', (string) $value, $matches)

Why no breaking changes

The cast produces the same string that PHP would have generated implicitly. Existing behavior is preserved; only the expression is made explicit.

Changes

  • src/Illuminate/Validation/Concerns/ValidatesAttributes.php — three (string) casts added
  • tests/Validation/ValidationValidatorTest.php — added integer/float assertions to the three relevant test methods

Test Plan

  • php83 vendor/bin/phpunit tests/Validation/ValidationValidatorTest.php --filter "testValidateDecimal|testValidateMaxDigits|testValidateMinDigits" — all 3 tests, 65 assertions pass

@taylorotwell taylorotwell merged commit 461f615 into laravel:13.x Apr 17, 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