We are having an issue with the captcha when there is a file upload and a captcha on a webform in php 8.0.16. We tried in a php 7.4.8 environment and there was no issue. We are on Drupal 9.3.8. We are using recaptcha but we were able to reproduce the problem with each captcha type.

The following is the error in the logs when a user tries to add a file. When the user tries to submit the form, they get the dialog "File upload in progress. Uploaded file may be lost."

AssertionError: Cannot load the "captcha_point" entity with NULL ID. in assert() (line 295 of /app/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php)
#0 /app/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php(295): assert(false, 'Cannot load the...')
#1 /app/web/core/lib/Drupal/Core/Entity/EntityBase.php(488): Drupal\Core\Entity\EntityStorageBase->load(NULL)
#2 /app/web/modules/contrib/captcha/captcha.inc(59): Drupal\Core\Entity\EntityBase::load(NULL)
#3 /app/web/modules/contrib/captcha/image_captcha/image_captcha.module(368): captcha_get_form_id_setting(NULL)
#4 [internal function]: image_captcha_after_build_process(Array, Object(Drupal\Core\Form\FormState), Array)
#5 /app/web/core/lib/Drupal/Core/Form/FormBuilder.php(1007): call_user_func_array('image_captcha_a...', Array)
#6 /app/web/core/lib/Drupal/Core/Form/FormBuilder.php(1070): Drupal\Core\Form\FormBuilder->doBuildForm('webform_submiss...', Array, Object(Drupal\Core\Form\FormState))
#7 /app/web/core/lib/Drupal/Core/Form/FormBuilder.php(1070): Drupal\Core\Form\FormBuilder->doBuildForm('webform_submiss...', Array, Object(Drupal\Core\Form\FormState))
#8 /app/web/core/lib/Drupal/Core/Form/FormBuilder.php(574): Drupal\Core\Form\FormBuilder->doBuildForm('webform_submiss...', Array, Object(Drupal\Core\Form\FormState))
#9 /app/web/core/lib/Drupal/Core/Form/FormBuilder.php(320): Drupal\Core\Form\FormBuilder->processForm('webform_submiss...', Array, Object(Drupal\Core\Form\FormState))
#10 /app/web/core/lib/Drupal/Core/Entity/EntityFormBuilder.php(48): Drupal\Core\Form\FormBuilder->buildForm(Object(Drupal\webform\WebformSubmissionForm), Object(Drupal\Core\Form\FormState))
#11 /app/web/modules/contrib/webform/src/Entity/Webform.php(1243): Drupal\Core\Entity\EntityFormBuilder->getForm(Object(Drupal\webform\Entity\WebformSubmission), 'add')
#12 /app/web/modules/contrib/webform/src/Controller/WebformEntityController.php(76): Drupal\webform\Entity\Webform->getSubmissionForm()
#13 [internal function]: Drupal\webform\Controller\WebformEntityController->addForm(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\webform\Entity\Webform))
#14 /app/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#15 /app/web/core/lib/Drupal/Core/Render/Renderer.php(564): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#16 /app/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#17 /app/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#18 /app/vendor/symfony/http-kernel/HttpKernel.php(158): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#19 /app/vendor/symfony/http-kernel/HttpKernel.php(80): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#20 /app/web/modules/contrib/redirect_after_login/src/RedirectMiddleware.php(46): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#21 /app/web/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Drupal\redirect_after_login\RedirectMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#22 /app/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#23 /app/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#24 /app/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#25 /app/vendor/asm89/stack-cors/src/Asm89/Stack/Cors.php(49): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#26 /app/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Asm89\Stack\Cors->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#27 /app/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#28 /app/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#29 /app/web/core/lib/Drupal/Core/DrupalKernel.php(708): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#30 /app/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#31 {main}

Steps to reproduce

Install php 8
Install webform module
Install webform ui
Install captcha module
Config file upload for webform
Create form with a file upload and captcha
Tried uploading a file and submitting form

Issue fork captcha-3270396

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

knowak created an issue. See original summary.

knowak’s picture

Issue summary: View changes
spookyisland’s picture

Hi, I get the "captcha_point" error above + this warning:

Warning: array_flip(): Can only flip STRING and INTEGER values! in Drupal\Core\Entity\EntityStorageBase->loadMultiple() (line 312 of /web/core/lib/Drupal/Core/Entity/EntityStorageBase.php)

Anybody’s picture

Status: Active » Postponed (maintainer needs more info)

Could you please add detailed steps, how to reproduce this in a fresh Drupal installation? I wasn't able to. Thanks :)

And please use the latest version.

Grevil’s picture

Version: 8.x-1.2 » 2.x-dev
Anybody’s picture

Status: Postponed (maintainer needs more info) » Active
Related issues: +#3323387: Remove special image_captcha_refresh handling

So these are the important lines and I'm very sure it might on happen in the combination of Webform + image_captcha:

#2 /app/web/modules/contrib/captcha/captcha.inc(59): Drupal\Core\Entity\EntityBase::load(NULL)
#3 /app/web/modules/contrib/captcha/image_captcha/image_captcha.module(368): captcha_get_form_id_setting(NULL)
#4 [internal function]: image_captcha_after_build_process(Array, Object(Drupal\Core\Form\FormState), Array)

captcha_get_form_id_setting() is called with a NULL parameter and then tries to load the entity with the ID null from image_captcha_after_build_process().

IMHO the whole image_captcha_after_build_process() function looks a bit dirty to me and seems image_captcha could need a refactoring.
The NULL value could even be specific to the WebformElement implementation:
src/Plugin/WebformElement/Captcha.php

I guess we should see if this is automagically fixed once #3323387: Remove special image_captcha_refresh handling is fixed in CAPTCHA. If not, we should try to reproduce and fix this.

Anybody’s picture

Version: 2.x-dev » 8.x-1.x-dev
Assigned: Unassigned » Anybody
Status: Active » Needs work

Okay, further details:

The reason is, that in this combination the $form_id can't be determined in image_captcha.module:

function image_captcha_after_build_process($element) {
  if (isset($element['#captcha_info'])) {
    $form_id = $element['#captcha_info']['form_id'];
    $captcha_point = captcha_get_form_id_setting($form_id);

So

captcha_get_form_id_setting($form_id);

is called with $form_id = NULL

which then leads to the issue in captcha.inc:

function captcha_get_form_id_setting($form_id, $symbolic = FALSE) {
  /** @var \Drupal\captcha\Entity\CaptchaPoint $captchaPoint */
  $captcha_point = CaptchaPoint::load($form_id);

So we need to find out, why
$element['#captcha_info']['form_id'] returns NULL in this combination in Webform.

As the original author wrote, they are using recaptcha and not image_captcha I think the implementtion in image_captcha_after_build_process() just isn't strict enough.

I'll fix this in 8.x-1.x and 2.x!

Anybody’s picture

Status: Needs work » Needs review
Anybody’s picture

Version: 8.x-1.x-dev » 2.x-dev

Grevil’s picture

Status: Needs review » Reviewed & tested by the community

LGTM!

Grevil’s picture

Status: Reviewed & tested by the community » Fixed

  • Grevil committed d0356c7 on 8.x-1.x authored by Anybody
    Issue #3270396: AssertionError: Cannot load the "captcha_point" entity...

  • Grevil committed d9519ee on 2.x authored by Anybody
    Issue #3270396: AssertionError: Cannot load the "captcha_point" entity...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.