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

Skip to content

MapQueryString mapped wrong on boolean values #57540

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
gcorso-nx opened this issue Jun 26, 2024 · 0 comments
Closed

MapQueryString mapped wrong on boolean values #57540

gcorso-nx opened this issue Jun 26, 2024 · 0 comments

Comments

@gcorso-nx
Copy link

Symfony version(s) affected

7.1

Description

Recently, with #54153 , support for boolean values on DTOs have been added within the #[MapQueryString].

I recently ran into an issue, where the paramter value false was mistakenly interpreted as true.

How to reproduce

While this works:

final readonly class SearchDto
{
    public function __construct(public ?bool $restricted = null)
    {
    }
}

final class MyController
{
    #[Route(name: 'search', path: '/search')]
    public function __invoke(#[MapQueryString] SearchDto $search): Response
    {
        // /search?restricted=
        // "false" would be converted to false
    }
}

This doesn't work:

final readonly class SearchDto
{
    public ?bool $restricted = null;
}

final class MyController
{
    #[Route(name: 'search', path: '/search')]
    public function __invoke(#[MapQueryString] SearchDto $search): Response
    {
        // /search?restricted=
        // "false" would be converted to true
    }
}

Other conversions work.

Applying a serialization context with the FILTER_BOOL flag aren't working too.
This also might be related to #57487.

Possible Solution

Looks like the applyFilterBool function is not called within AbstractNormalizer, if no constructor is given. Other assertions / convertions seems to work in DTOs, even if no constructor given.

Additional Context

Not using constructor works for all other use cases I've tested. With constructor we had issues with enums, why we used the solution like here

@gcorso-nx gcorso-nx added the Bug label Jun 26, 2024
nicolas-grekas added a commit that referenced this issue Jun 28, 2024
…R_BOOL is set (Maximilian Zumbansen)

This PR was squashed before being merged into the 7.1 branch.

Discussion
----------

[Serializer] [ObjectNormalizer] Use bool filter when FILTER_BOOL is set

| Q             | A
| ------------- | ---
| Branch?       | 7.1 <!-- see below -->
| Bug fix?      | yes
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Issues        | Fix #57540 <!-- prefix each issue number with "Fix #", no need to create an issue if none exists, explain below instead -->
| License       | MIT

With 7.1 it is possible to map query booleans to php bool parameters (https://symfony.com/blog/new-in-symfony-7-1-misc-improvements-part-3#mapping-boolean-query-string-parameters). But as we found out, this only works when the DTO is initialized via `construct`. Otherwise the `FILTER_BOOL` flag will be ignored and e.g. "false" will be deserialized as `true`.

To fix this, I suggest to look for the `FILTER_BOOL` in the context and apply the filter, when the type is `bool` and the data is `string`.

Commits
-------

6e657e8 [Serializer] [ObjectNormalizer] Use bool filter when FILTER_BOOL is set
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

4 participants