(regression) Submission of non-numeric value on contribution form causes crash
Overview
Putting anything other than a strict numeric value in the "Other Amount" field of a price set results in a crash.
Reproduction steps
- Use a page with an "Other Amount" field (Quick Config or not, doesn't matter). This also affects all "Text / Numeric Quantity" price fields.
- Enter a value that isn't strictly numeric. Like
$5
or5 dollars
. - Submit the page.
Current behaviour
Division by zero error, crash.
Expected behaviour
Should fail validation with the message "Other Amount must be a number (with or without decimals).".
Comments
This is new in 5.70. I traced it to PR #29275. Our first validation is now $self->resetOrder($fields);
. The docblock there says we assume the input has been sanitized, but in the backtrace below, it must be happening pre-sanitization.
Backtrace:
#0 /var/www/mysite/vendor/civicrm/civicrm-core/CRM/Financial/BAO/Order.php(832): CRM_Financial_BAO_Order->calculateLineItems()
#1 /var/www/mysite/vendor/civicrm/civicrm-core/CRM/Contribute/Form/Contribution/Main.php(1983): CRM_Financial_BAO_Order->recalculateLineItems()
#2 /var/www/mysite/vendor/civicrm/civicrm-core/CRM/Contribute/Form/Contribution/Main.php(819): CRM_Contribute_Form_Contribution_Main->resetOrder(Array)
#3 /var/www/mysite/vendor/civicrm/civicrm-packages/HTML/QuickForm.php(1600): CRM_Contribute_Form_Contribution_Main::formRule(Array, Array, Object(CRM_Contribute_Form_Contribution_Main))
#4 /var/www/mysite/vendor/civicrm/civicrm-core/CRM/Core/Form.php(703): HTML_QuickForm->validate()
#5 /var/www/mysite/vendor/civicrm/civicrm-core/CRM/Core/QuickForm/Action/Upload.php(137): CRM_Core_Form->validate()
#6 /var/www/mysite/vendor/civicrm/civicrm-core/CRM/Core/QuickForm/Action/Upload.php(120): CRM_Core_QuickForm_Action_Upload->realPerform(Object(CRM_Contribute_Form_Contribution_Main), 'upload')
#7 /var/www/mysite/vendor/civicrm/civicrm-packages/HTML/QuickForm/Controller.php(203): CRM_Core_QuickForm_Action_Upload->perform(Object(CRM_Contribute_Form_Contribution_Main), 'upload')
#8 /var/www/mysite/vendor/civicrm/civicrm-packages/HTML/QuickForm/Page.php(103): HTML_QuickForm_Controller->handle(Object(CRM_Contribute_Form_Contribution_Main), 'upload')
#9 /var/www/mysite/vendor/civicrm/civicrm-core/CRM/Core/Controller.php(355): HTML_QuickForm_Page->handle('upload')
#10 /var/www/mysite/vendor/civicrm/civicrm-core/CRM/Core/Invoke.php(322): CRM_Core_Controller->run(Array, NULL)
#11 /var/www/mysite/vendor/civicrm/civicrm-core/CRM/Core/Invoke.php(69): CRM_Core_Invoke::runItem(Array)
#12 /var/www/mysite/vendor/civicrm/civicrm-core/CRM/Core/Invoke.php(36): CRM_Core_Invoke::_invoke(Array)
#13 /var/www/mysite/web/modules/contrib/civicrm/src/Civicrm.php(88): CRM_Core_Invoke::invoke(Array)
#14 /var/www/mysite/web/modules/contrib/civicrm/src/Controller/CivicrmController.php(83): Drupal\civicrm\Civicrm->invoke(Array)
#15 [internal function]: Drupal\civicrm\Controller\CivicrmController->main(Array, '')
#16 /var/www/mysite/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#17 /var/www/mysite/web/core/lib/Drupal/Core/Render/Renderer.php(627): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#18 /var/www/mysite/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#19 /var/www/mysite/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#20 /var/www/mysite/vendor/symfony/http-kernel/HttpKernel.php(181): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#21 /var/www/mysite/vendor/symfony/http-kernel/HttpKernel.php(76): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#22 /var/www/mysite/web/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#23 /var/www/mysite/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#24 /var/www/mysite/web/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#25 /var/www/mysite/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\ContentLength->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#26 /var/www/mysite/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#27 /var/www/mysite/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#28 /var/www/mysite/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#29 /var/www/mysite/web/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#30 /var/www/mysite/web/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\Core\StackMiddleware\AjaxPageState->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#31 /var/www/mysite/web/core/lib/Drupal/Core/DrupalKernel.php(704): Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#32 /var/www/mysite/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#33 {main}