BatchStorage fails to serialize/deserialize input batch object with FormState

Created on 16 May 2019, over 5 years ago
Updated 6 June 2024, 7 months ago

We found that after migrating our Drupal content management system to PHP 7.3, we experienced some issue related to the unserialize failure of a serialized input batch object. This batch object comes from a multi-step input form, which has following data structure

batch (array)
'sets'=> array,
...
'form_state' => Drupal\Core\Form\FormState
....
'complete_form'=>....
'values' => .....
....//Other fields

In above example, the Batch is an array of objects, inside it has a "form_state" object (Drupal FormState), inside "form_state", it has another array of the "complete_form", which encapsulate all the request form from UI.

To simple test, you can just run

unserialize(serialize($batch)

it will return false in above case.

Following are findings by playing around the unserialize(serialize($batch)
1: The reason "unserialize(serialize($batch)" return false is because "unserialize(serialize($batch['form_state'])" return false
2: If we create an empty FormState, like "$batch['form_state'] = new FormState()", unserialize(serialize($batch) will return as an array
3: If we assign some nested array of object inside 'form_state', like the "complete_form" above inside, keep the original nested structure of the $batch object as above, then unserialize(serialize($batch) return false
4: If we run "unserialize(serialize($batch['form_state'])", it will return correctly with a nested array of objects

This makes us to workaround the serialize/unserialize issue of $Batchby combing 3 and 4 above into an array, and then serialize()/unserialize it in in the BatchStorage to make sure it workaround the problem we have. But this change of data structure of the input batch object, is just an additional catch of the problem we have. This issue should be addressed in the Drupal core in a more generic solution, for example:
1: Make sure the input batch object is always serializable/deserialize correctly, which may not be easy since the input form data can be configured based on specific request, we need to make sure each nested object inside the batch object has correctly serialization implemented (either through the Serializable interface or method pair of __sleep() and __awake().
2: Add some validation in the batch processing, or change the logic of batch processing not using serialize/unserialize pair, instead, use something like json_encode/json_decode (need to reconfig the PHP object from the decode), or
3: Add certain validation before persisting to database, and validate the return after "unserialize" from database return.

πŸ› Bug report
Status

Postponed: needs info

Version

11.0 πŸ”₯

Component
BatchΒ  β†’

Last updated about 13 hours ago

Created by

πŸ‡ΊπŸ‡ΈUnited States wangchunzhang

Live updates comments and jobs are added and updated live.
  • PHP 7.3

    The issue particularly affects sites running on PHP version 7.3.0 or later.

  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Comments & Activities

Not all content is available!

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

  • πŸ‡³πŸ‡ΏNew Zealand quietone

    This problem was discovered in Drupal 8 with PHP 7.3, which are both past their End of Life date. The last comment, 2 years ago reported that the last patch fixed the problem on Drupal 9. What we need to know now is, does this problem exist in Drupal 10?

    Since we need more information to move forward with this issue, I am setting the status to Postponed (maintainer needs more info). If we don't receive additional information to help with the issue, it may be closed after three months.

    Thanks!

  • πŸ‡§πŸ‡ͺBelgium victonator

    I deleted the patch from comment #20 from a project and the feature it's attached to is working as intended.
    In my case this is not an issue anymore.

Production build 0.71.5 2024