diff --git a/src/Validation/DatabasePresenceVerifier.php b/src/Validation/DatabasePresenceVerifier.php index c563a9976..fee8ef610 100644 --- a/src/Validation/DatabasePresenceVerifier.php +++ b/src/Validation/DatabasePresenceVerifier.php @@ -43,8 +43,13 @@ public function getCount($collection, $column, $value, $excludeId = null, $idCol */ public function getMultiCount($collection, $column, array $values, array $extra = []) { - // Generates a regex like '/(a|b|c)/i' which can query multiple values - $regex = '/('.implode('|', $values).')/i'; + // Nothing can match an empty array. Return early to avoid matching an empty string. + if ($values === []) { + return 0; + } + + // Generates a regex like '/^(a|b|c)$/i' which can query multiple values + $regex = new Regex('^('.implode('|', array_map(preg_quote(...), $values)).')$', 'i'); $query = $this->table($collection)->where($column, 'regex', $regex); diff --git a/tests/ValidationTest.php b/tests/ValidationTest.php index 5a0459215..63f074de3 100644 --- a/tests/ValidationTest.php +++ b/tests/ValidationTest.php @@ -103,5 +103,31 @@ public function testExists(): void ['name' => 'required|exists:users'] ); $this->assertFalse($validator->fails()); + + $validator = Validator::make( + ['name' => ['test name', 'john']], // Part of an existing value + ['name' => 'required|exists:users'] + ); + $this->assertTrue($validator->fails()); + + $validator = Validator::make( + ['name' => '(invalid regex{'], + ['name' => 'required|exists:users'] + ); + $this->assertTrue($validator->fails()); + + $validator = Validator::make( + ['name' => ['foo', '(invalid regex{']], + ['name' => 'required|exists:users'] + ); + $this->assertTrue($validator->fails()); + + User::create(['name' => '']); + + $validator = Validator::make( + ['name' => []], + ['name' => 'exists:users'] + ); + $this->assertFalse($validator->fails()); } }