The same form twice on one page with different arguments may process the wrong form when submitted

Created on 25 October 2016, over 8 years ago
Updated 4 April 2024, 11 months ago

Problem/Motivation

If the same form is on a page multiple times and with different arguments, submitting the second form may accidentally be processed with the first form's arguments. Steps to reproduce:

- Have a simple form that does not use #ajax. The #ajax property will force $form_state['cache'] = TRUE, and inadvertently "fix" the bug.
- Pass in different parameters to the form and call it twice on the same menu path.
- Submit the second form.
- You get the results from the first form's arguments, rather than the second one.

Proposed resolution

Create a consistent hash or indicator that can be used across page requests to identify when the same form has been built multiple times on the same page. Actual solution TBD. But some possibilities include:

  • This may be a "form_build_count" based on the order the form was built.
  • An automatic "form_args_hash" that is made up of the original arguments to separate the two identical forms.
  • A manually-provided indicator to separate if the form needs to be supported on the same page multiple times.

Remaining tasks

Solution to be determined. Test coverage expanded to include this bug.

User interface changes

None.

API changes

TBD

Data model changes

None.

🐛 Bug report
Status

Needs work

Version

11.0 🔥

Component
Form 

Last updated 21 minutes ago

Created by

🇺🇸United States quicksketch

Live updates comments and jobs are added and updated live.
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.

  • 🇩🇪Germany ammaletu Bonn, Germany

    The two lines in #3 indeed fix this issue -- but they also potentially open up a new, horrible bug! We added these lines, and now when more than one guest user opens a page with this form, only one of them can submit the form (whoever is quickest). The rest get a "Integrity constraint violation, duplicate entry for node_field__uuid__value" error. This only happens for guest users, because for them the whole page is cached. As I said, a horrible bug for end-users and hard to spot when testing alone.

    Think very hard before simply adding these two lines. Are these forms which are displayed to guest users and do you have the static page cache enabled? Not caching the form and using a unique form ID might be the better solution. We will for now try to simply not cache pages which have these forms. Together with the cache kill switch, the fix from #3 seems to work.

  • 🇮🇳India sukr_s

    The issue it seems that the block loads the configuration for the first block found and therefore the arguments of the first form are used. However if you check the user input in $form_state, the values sent from the browser are correct. I'm assuming that the arguments are stored in hidden fields. If so, you can check for user input for these values and use them if found, otherwise use from arguments
    e.g.

    public function buildForm(array $form, FormStateInterface $form_state, $id) {
        $input_values = $form_state->getUserInput();
        $form['id_value'] = [
          '#type' => 'hidden',
          '#value' => isset($input_values['id_value'])? $input_values['id_value'] : $id,
        ];
        $form['txt'] = [
          '#type' => 'textfield',
          '#title' => 'Textfield',
          '#default_value' => $id,
          '#required' => TRUE,
        ];
        $form['submit'] = [
          '#type' => 'submit',
          '#value' => 'Submit'
        ];    
        return $form;
    }
    

    with this approach the submit and validate have the correct values for the argument fields.

Production build 0.71.5 2024