Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Validation skips violations in case with nested AtLeastOneOf constraint #54577

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
GeoDpto opened this issue Apr 12, 2024 · 1 comment
Closed

Comments

@GeoDpto
Copy link

GeoDpto commented Apr 12, 2024

Symfony version(s) affected

6.4

Description

When I make nested constraints AtLeastOneOf, the validator will skip all violations.

The Symfony validator employs two factories for initializing an instance of a constraint validator:

  1. Symfony\Component\ValidatorConstraintValidatorFactory - creates a new instance of the validator and caches it as an array.
  2. Symfony\Component\ContainerConstraintValidatorFactory - retrieves the validator from the DI container. As each unique service in a container is passed by reference, each validator is initialized only once.

The issue arises when creating a nested constraint, such as AtLeastOneOf. At line 752 of RecursiveContextualValidator, a new context for this validator is initialized, which is the root cause of the bug.

How to reproduce

To reproduce this bug, you can use the following code:

<?php

declare(strict_types=1);

use Symfony\Component\Validator\Constraints\AtLeastOneOf;
use Symfony\Component\Validator\Constraints\Choice;
use Symfony\Component\Validator\Constraints\Collection;
use Symfony\Component\Validator\Constraints\Type;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Validation;

require_once dirname(__DIR__) . '/vendor/autoload.php';

$values = [
    'AtLeastOneOf' => [
        'field1' => 'test',
        'AtLeastOneOfNested1' => [
            'AtLeastOneOfNested2' => \uniqid(),
            'field2' => \uniqid(),
        ],
    ],
    'test2' => '1',
];

$constraints = new Collection([
    'AtLeastOneOf' => new AtLeastOneOf([
        new Collection([
            'field1' => new NotBlank(),
            'AtLeastOneOfNested1' => new AtLeastOneOf([
                new Collection([
                    'AtLeastOneOfNested2' => new AtLeastOneOf([
                        new Type('int'),
                        new Choice(['test1', 'test2'])
                    ]),
                ]),
                new Collection([
                    'field2' => new Type('int'),
                ]),
            ]),
        ]),
        new Collection([
            'field3' => new NotBlank(),
            'AtLeastOneOfNested3' => new AtLeastOneOf([
                new Collection([
                    'field1' => new Type('int'),
                ]),
                new Collection([
                    'field2' => new Type('int'),
                ]),
            ]),
        ]),
    ]),
    'test2' => new NotBlank(),
]);

$violations = Validation::createValidator()->validate($values, $constraints);

echo $violations->count() . \PHP_EOL;

As we can see, incorrect data exists for the key AtLeastOneOfNested1, but the validator skips these violations.

Possible Solution

A possible solution is to consistently initialize a new instance of AtLeastOneOfValidator within a factory.

image
image

Additional Context

No response

@xabbuh
Copy link
Member

xabbuh commented Aug 5, 2024

see #57925 for a potential fix

xabbuh added a commit that referenced this issue Aug 11, 2024
…nested constraints (xabbuh)

This PR was merged into the 5.4 branch.

Discussion
----------

[Validator] reset the validation context after validating nested constraints

| Q             | A
| ------------- | ---
| Branch?       | 5.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Issues        | Fix #54577
| License       | MIT

Commits
-------

874e3f9 reset the validation context after validating nested constraints
@xabbuh xabbuh closed this as completed Aug 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants