8000 bug #29800 [Validator] Only traverse arrays that are cascaded into (c… · symfony/symfony@1f48f7b · GitHub
[go: up one dir, main page]

Skip to content

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 1f48f7b

Browse files
committed
bug #29800 [Validator] Only traverse arrays that are cascaded into (corphi)
This PR was squashed before being merged into the 3.4 branch (closes #29800). Discussion ---------- [Validator] Only traverse arrays that are cascaded into | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #27090 | License | MIT | Doc PR | - Previously, array properties were traversed even if they were not annotated `Valid`. Commits ------- 7db9200 [Validator] Only traverse arrays that are cascaded into
2 parents 03d804e + 7db9200 commit 1f48f7b

File tree

3 files changed

+31
-12
lines changed

3 files changed

+31
-12
lines changed

src/Symfony/Component/Validator/Constraints/Collection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ protected function initializeNestedConstraints()
6868
}
6969

7070
if (!$field instanceof Optional && !$field instanceof Required) {
71-
$this->fields[$fieldName] = $field = new Required($field);
71+
$this->fields[$fieldName] = new Required($field);
7272
}
7373
}
7474
}

src/Symfony/Component/Validator/Tests/Validator/AbstractValidatorTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,30 @@ public function testRecursiveArrayReference()
589589
$this->assertNull($violations[0]->getCode());
590590
}
591591

592+
public function testOnlyCascadedArraysAreTraversed()
593+
{
594+
$entity = new Entity();
595+
$entity->reference = ['key' => new Reference()];
596+
597+
$callback = function ($value, ExecutionContextInterface $context) {
598+
$context->addViolation('Message %param%', ['%param%' => 'value']);
599+
};
600+
601+
$this->metadata->addPropertyConstraint('reference', new Callback([
602+
'callback' => function () {},
603+
'groups' => 'Group',
604+
]));
605+
$this->referenceMetadata->addConstraint(new Callback([
606+
'callback' => $callback,
607+
'groups' => 'Group',
608+
]));
609+
610+
$violations = $this->validate($entity, null, 'Group');
611+
612+
/* @var ConstraintViolationInterface[] $violations */
613+
$this->assertCount(0, $violations);
614+
}
615+
592616
public function testArrayTraversalCannotBeDisabled()
593617
{
594618
$entity = new Entity();

src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -352,24 +352,18 @@ private function validateObject($object, $propertyPath, array $groups, $traversa
352352
* Validates each object in a collection against the constraints defined
353353
* for their classes.
354354
*
355-
* If the parameter $recursive is set to true, nested {@link \Traversable}
356-
* objects are iterated as well. Nested arrays are always iterated,
357-
* regardless of the value of $recursive.
355+
* Nested arrays are also iterated.
358356
*
359357
* @param iterable $collection The collection
360358
* @param string $propertyPath The current property path
361359
* @param (string|GroupSequence)[] $groups The validated groups
362360
* @param ExecutionContextInterface $context The current execution context
363-
*
364-
* @see ClassNode
365-
* @see CollectionNode
366361
*/
367362
private function validateEachObjectIn($collection, $propertyPath, array $groups, ExecutionContextInterface $context)
368363
{
369364
foreach ($collection as $key => $value) {
370365
if (\is_array($value)) {
371-
// Arrays are always cascaded, independent of the specified
372-
// traversal strategy
366+
// Also traverse nested arrays
373367
$this->validateEachObjectIn(
374368
$value,
375369
$propertyPath.'['.$key.']',
@@ -599,7 +593,8 @@ private function validateClassNode($object, $cacheKey, ClassMetadataInterface $m
599593
* in the passed metadata object. Then, if the value is an instance of
600594
* {@link \Traversable} and the selected traversal strategy permits it,
601595
* the value is traversed and each nested object validated against its own
602-
* constraints. Arrays are always traversed.
596+
* constraints. If the value is an array, it is traversed regardless of
597+
* the given strategy.
603598
*
604599
* @param mixed $value The validated value
605600
* @param object|null $object The current object
@@ -658,8 +653,8 @@ private function validateGenericNode($value, $object, $cacheKey, MetadataInterfa
658653

659654
$cascadingStrategy = $metadata->getCascadingStrategy();
660655

661-
// Quit unless we have an array or a cascaded object
662-
if (!\is_array($value) && !($cascadingStrategy & CascadingStrategy::CASCADE)) {
656+
// Quit unless we cascade
657+
if (!($cascadingStrategy & CascadingStrategy::CASCADE)) {
663658
return;
664659
}
665660

0 commit comments

Comments
 (0)
0