Skip to content
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

Regex validator in annotation is inconsistent with the one in PHP #22865

Closed
lashae opened this issue May 23, 2017 · 7 comments
Closed

Regex validator in annotation is inconsistent with the one in PHP #22865

lashae opened this issue May 23, 2017 · 7 comments

Comments

@lashae
Copy link
Contributor

lashae commented May 23, 2017

I'm building an application on Symfony 3.2

On one part of the application I'm providing an interface my users to change their passwords. For this task, I have a simple form which is bound to my ChangePasword entity as follows.

Form class:

    <?php
    
    namespace MasterBundle\Form;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\Extension\Core\Type\PasswordType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolver;
    
    class ChangePasswordType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('oldPassword', PasswordType::class)
                ->add('newPassword', PasswordType::class);
        }
    
        /**
         * @param OptionsResolver $resolver
         */
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults(
                array(
                    'data_class' => 'MasterBundle\Entity\ChangePassword'
                )
            );
        }
    
        public function getBlockPrefix()
        {
            return 'change_password';
        }
    } 

And the model:

    <?php
    
    namespace MasterBundle\Entity;
    
    use Symfony\Component\Validator\Constraints as Assert;
    use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
    
    class ChangePassword
    {
    
        /**
         * @UserPassword(message="Your current password is not correct.")
         */
        private $oldPassword;
    
        /**
         * @Assert\NotBlank(message="New password can not be blank.")
         * @Assert\Regex(pattern="/^(?=.*[a-z])(?=.*\\d).{6,}$/i", message="New password is required to be minimum 6 chars in length and to include at least one letter and one number.")
         */
        private $newPassword;
    
    // other setter and getter stuff.
    }

Now, the problem is the regex validator doesn't work. It doesn't match with anything.

However, if I modify the model as below; it works flawlessly:

    <?php
    
    namespace MasterBundle\Entity;
    
    use Symfony\Component\Validator\Constraints as Assert;
    use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
    use Symfony\Component\Validator\Mapping\ClassMetadata;
    
    class ChangePassword
    {
    
        private $oldPassword;
    
        private $newPassword;
    
    public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addPropertyConstraint('oldPassword', new Userpassword(array(
            'message' => 'Your current password is not correct.',
        )));

        $metadata->addPropertyConstraint('newPassword', new Assert\NotBlank(array(
            'message' => 'New password can not be blank.',
        )));

        $metadata->addPropertyConstraint('newPassword', new Assert\Regex(array(
            'pattern' => '/^(?=.*[a-z])(?=.*\\d).{6,}$/i',
            'message' => 'New password is required to be minimum 6 chars in length and to include at least one letter and one number.'
        )));
    }

    // other setter and getter stuff.
    }

Further debugging yield that:

For this specific regular expression, the one in the annotation should not escape \d bit, however in the PHP implementation (ie using loadValidatorMetadata) we need to escape it.

If I edit the model which implemented the constraint in annotation as follows, it works:

    /**
     * @Assert\NotBlank(message="New password can not be blank.")
     * @Assert\Regex(pattern="/^(?=.*[a-z])(?=.*\d).{6,}$/i", message="New password is required to be minimum 6 chars in length and to include at least one letter and one number.")
     */
    private $newPassword;

Just edit /^(?=.*[a-z])(?=.*\\d).{6,}$/i to /^(?=.*[a-z])(?=.*\d).{6,}$/i

This seems to inconsistent. If the regex within the annotation is escaped by Symfony than the one in PHP have to be escaped as well or vice versa.

I think the annotation, yaml, xml and PHP implementations need to be identical whereas possible (except for platform limitations) and the documentation should emphasize all of the inconsistencies as verbose as possible.

@sstok
Copy link
Contributor

sstok commented May 23, 2017

FYI, there is also a bundle that validate the strength of your https://github.com/rollerworks/PasswordStrengthBundle

And there is a repeated type for Passwords in Symfony that displays two password fields (that must be the same). https://symfony.com/doc/current/reference/forms/types/repeated.html#main

@xabbuh
Copy link
Member

xabbuh commented May 23, 2017

I may be missing something, but why do you need to escape the backslash in the regex in your PHP example?

@lashae
Copy link
Contributor Author

lashae commented May 23, 2017

@xabbuh I don't know either. It works as expected only when it is escaped, in PHP.

@javiereguiluz
Copy link
Member

I agree with @xabbuh. I can't understand why \d must be \\d to work. I must be missing something 😕

@sstok
Copy link
Contributor

sstok commented May 29, 2017

Maybe it's related to how Doctrine parses the string, properly new-lines \n should still be supported. Not to mention special characters.

@xabbuh
Copy link
Member

xabbuh commented Jun 3, 2017

@lashae I was not able to reproduce your issue. Can you please create a small example project that show the bug you are experiencing?

@lashae
Copy link
Contributor Author

lashae commented Jun 5, 2017

@xabbuh I created an example isolated project and (un)fortunately I cannot reproduce the error either. Interestingly, both validation rules (annotation and php) works with no-escape and unlimited number of escapes...

We can close the issue, sorry for the noise.

@lashae lashae closed this as completed Jun 5, 2017
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

5 participants