From 0847dd88fb938de569ed865a497b2c609907887a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Mon, 21 Aug 2023 10:55:54 +0200 Subject: [PATCH 1/2] PHPORM-68 Fix partial value un exist validator --- src/Validation/DatabasePresenceVerifier.php | 9 +++++++-- tests/ValidationTest.php | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/Validation/DatabasePresenceVerifier.php b/src/Validation/DatabasePresenceVerifier.php index c563a9976..9f21e83ad 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('|', $values).')$', 'i'); $query = $this->table($collection)->where($column, 'regex', $regex); diff --git a/tests/ValidationTest.php b/tests/ValidationTest.php index 5a0459215..06eadde1f 100644 --- a/tests/ValidationTest.php +++ b/tests/ValidationTest.php @@ -103,5 +103,19 @@ 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()); + + User::create(['name' => '']); + + $validator = Validator::make( + ['name' => []], + ['name' => 'exists:users'] + ); + $this->assertFalse($validator->fails()); } } From 07e13a4f3ad57c904f224a787f99e6e2c533da21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Tue, 22 Aug 2023 22:18:42 +0200 Subject: [PATCH 2/2] escape values for regex --- src/Validation/DatabasePresenceVerifier.php | 2 +- tests/ValidationTest.php | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Validation/DatabasePresenceVerifier.php b/src/Validation/DatabasePresenceVerifier.php index 9f21e83ad..fee8ef610 100644 --- a/src/Validation/DatabasePresenceVerifier.php +++ b/src/Validation/DatabasePresenceVerifier.php @@ -49,7 +49,7 @@ public function getMultiCount($collection, $column, array $values, array $extra } // Generates a regex like '/^(a|b|c)$/i' which can query multiple values - $regex = new Regex('^('.implode('|', $values).')$', 'i'); + $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 06eadde1f..63f074de3 100644 --- a/tests/ValidationTest.php +++ b/tests/ValidationTest.php @@ -110,6 +110,18 @@ public function testExists(): void ); $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(