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

Skip to content

Form DateType accepts random strings as valid value and converts it to 1970-01-01 #40597

Closed
@kamil-jakubowski

Description

@kamil-jakubowski

Symfony version(s) affected:5.2

Description
\Symfony\Component\Form\Extension\Core\Type\DateType when using widget "single_text" accepts incorrect date string for example "dsfsdfds" and transform it before mapping to form-data (data_class object) to 1970-01-01. It should give an error that date is invalid. Even adding constraint \Symfony\Component\Validator\Constraints\Date to the date field is not working, because the field validator checks value after transforming (1970-01-01), so the value is valid.

How to reproduce

  1. Create a form with DateType|BirthdayType field:
    $builder->add('birthDate', BirthdayType::class, [ 'label' => "Birthdate", 'widget' => 'single_text', 'html5' => false, 'format' => 'yyyy-MM-dd', 'input' => 'string', 'input_format' => 'Y-m-d', 'constraints' => [ new NotBlank(), new Date() ] ])

  2. Submit form with some incorrect value in the field
    image

  3. After submitting form and rendering it again you can see value 1970-01-01 and no error
    image

Here are dump of form array input from the Request object after submit:
array:1 [▼ "birthDate" => "dsfsdfdsdsdsfdsf" ]

and dump of associated form-data object after form->handleSubmit():
App\UI\Web\Form\Profile\ProfileCreateRequest {#548 ▼ +birthDate: "1970-01-01" }

Possible Solution
My research showed that \Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToLocalizedStringTransformer does that incorrect transition without any error.

It uses \IntlDateFormatter, which converts every incorrect date string to timestamp=false in:
symfony/form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php:123
line 123: $timestamp = @$dateFormatter->parse($value);

XDebug output:
image

I've added some test var $someTestVar to the DateTimeToLocalizedStringTransformer, only to show in xdebug output of int_get_error_code().
As you can see dateFormatter has errorCode => 9 and U_PARSE_ERROR, but whole function is run using silent mode with "@" so there is no exception thrown. Another strange thing that intl_get_error_code() gives 0 code, so also condition in line 130 is not TRUE, and an exception in line 131 is not thrown.

image

After that $timestamp var is false, which is converting to 0, when DateTime object is creating after that, so it gives a date with 1970-01-01 :)
image

Additional context
The same problem occurs when you're using, but 'input' => 'string', 'input_format' => 'Y-m-d',
it transforms incorrect value to DateTime('1970-01-01') object then.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions