Skip to content

Commit 3815e84

Browse files
committed
Merge branch '6.0' into 6.1
* 6.0: Update ExceptionInterface.php Revert removal of Stringable check Flush with flush() after ob_end_flush() [Validator] : Fix "PHP Warning: Undefined array key 1" in NotCompromisedPasswordValidator [Validator] Fix traverse option on Valid constraint when used as Attribute [HttpFoundation] Fix deleteFileAfterSend on client abortion Prevent that bad Ignore method annotations lead to incorrect results also fix the test fix deprecation fix sending request to paths containing multiple slashes Fix generated validation error message for wrong exception mapping status code
2 parents 045bce8 + 8a21226 commit 3815e84

File tree

4 files changed

+71
-3
lines changed

4 files changed

+71
-3
lines changed

Constraints/NotCompromisedPasswordValidator.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ public function validate(mixed $value, Constraint $constraint)
9191
}
9292

9393
foreach (explode("\r\n", $result) as $line) {
94+
if (!str_contains($line, ':')) {
95+
continue;
96+
}
97+
9498
[$hashSuffix, $count] = explode(':', $line);
9599

96100
if ($hashPrefix.$hashSuffix === $hash && $constraint->threshold <= (int) $count) {

Constraints/Valid.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ class Valid extends Constraint
2424
{
2525
public $traverse = true;
2626

27+
public function __construct(array $options = null, array $groups = null, $payload = null, bool $traverse = null)
28+
{
29+
parent::__construct($options ?? [], $groups, $payload);
30+
31+
$this->traverse = $traverse ?? $this->traverse;
32+
}
33+
2734
public function __get(string $option): mixed
2835
{
2936
if ('groups' === $option) {

Tests/Constraints/NotCompromisedPasswordValidatorTest.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,31 @@ public function testInvalidPasswordCustomEndpoint()
161161
->assertRaised();
162162
}
163163

164+
public function testEndpointWithInvalidValueInReturn()
165+
{
166+
$returnValue = implode(
167+
"\r\n",
168+
[
169+
'36039744C253F9B2A4E90CBEDB02EBFB82D:5',
170+
'This should not break the validator',
171+
'3686792BBC66A72D40D928ED15621124CFE:7',
172+
'36EEC709091B810AA240179A44317ED415C:2',
173+
'',
174+
]
175+
);
176+
177+
$validator = new NotCompromisedPasswordValidator(
178+
$this->createHttpClientStub($returnValue),
179+
'UTF-8',
180+
true,
181+
'https://password-check.internal.example.com/range/%s'
182+
);
183+
184+
$validator->validate(self::PASSWORD_NOT_LEAKED, new NotCompromisedPassword());
185+
186+
$this->assertNoViolation();
187+
}
188+
164189
public function testInvalidConstraint()
165190
{
166191
$this->expectException(UnexpectedTypeException::class);
@@ -195,11 +220,11 @@ public function provideErrorSkippingConstraints(): iterable
195220
yield 'named arguments' => [new NotCompromisedPassword(skipOnError: true)];
196221
}
197222

198-
private function createHttpClientStub(): HttpClientInterface
223+
private function createHttpClientStub(?string $returnValue = null): HttpClientInterface
199224
{
200225
$httpClientStub = $this->createMock(HttpClientInterface::class);
201226
$httpClientStub->method('request')->willReturnCallback(
202-
function (string $method, string $url): ResponseInterface {
227+
function (string $method, string $url) use ($returnValue): ResponseInterface {
203228
if (self::PASSWORD_TRIGGERING_AN_ERROR_RANGE_URL === $url) {
204229
throw new class('Problem contacting the Have I been Pwned API.') extends \Exception implements ServerExceptionInterface {
205230
public function getResponse(): ResponseInterface
@@ -212,7 +237,7 @@ public function getResponse(): ResponseInterface
212237
$responseStub = $this->createMock(ResponseInterface::class);
213238
$responseStub
214239
->method('getContent')
215-
->willReturn(implode("\r\n", self::RETURN));
240+
->willReturn($returnValue ?? implode("\r\n", self::RETURN));
216241

217242
return $responseStub;
218243
}

Tests/Constraints/ValidTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Validator\Constraints\Valid;
16+
use Symfony\Component\Validator\Mapping\ClassMetadata;
17+
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
1618

1719
/**
1820
* @author Bernhard Schussek <[email protected]>
@@ -32,4 +34,34 @@ public function testGroupsAreNullByDefault()
3234

3335
$this->assertNull($constraint->groups);
3436
}
37+
38+
/**
39+
* @requires PHP 8
40+
*/
41+
public function testAttributes()
42+
{
43+
$metadata = new ClassMetaData(ValidDummy::class);
44+
$loader = new AnnotationLoader();
45+
self::assertTrue($loader->loadClassMetadata($metadata));
46+
47+
[$bConstraint] = $metadata->properties['b']->getConstraints();
48+
self::assertFalse($bConstraint->traverse);
49+
self::assertSame(['traverse_group'], $bConstraint->groups);
50+
51+
[$cConstraint] = $metadata->properties['c']->getConstraints();
52+
self::assertSame(['my_group'], $cConstraint->groups);
53+
self::assertSame('some attached data', $cConstraint->payload);
54+
}
55+
}
56+
57+
class ValidDummy
58+
{
59+
#[Valid]
60+
private $a;
61+
62+
#[Valid(groups: ['traverse_group'], traverse: false)] // Needs a group to work at all for this test
63+
private $b;
64+
65+
#[Valid(groups: ['my_group'], payload: 'some attached data')]
66+
private $c;
3567
}

0 commit comments

Comments
 (0)