Currently drupal_prepare_form does:

  if (!isset($form['#validate'])) {
    if (function_exists($form_id . '_validate')) {
      $form['#validate'] = array($form_id . '_validate');
    }
  }
...
  if (!isset($form['#submit'])) {
    if (function_exists($form_id . '_submit')) {
      $form['#submit'] = array($form_id . '_submit');
    }
  }

So what happens in the case that $form['#validate'] or $form['#submit'] exist already? Those default handlers are not added, which is not expected behavior (see #239676: SA-CORE-2009-001: Missing validation for hook_user which will be fixed by this issue).

Comments

dave reid’s picture

Status: Active » Needs review
Issue tags: +Security improvements, +Quick fix
StatusFileSize
new1.5 KB

Patch ready for review.

dave reid’s picture

Issue tags: +Needs backport to D6

Status: Needs review » Needs work

The last submitted patch failed testing.

dave reid’s picture

Very interesting... looking into the failure.

jhedstrom’s picture

Subscribing.

dave reid’s picture

Status: Needs work » Needs review

Requesting retest.

Status: Needs review » Needs work

The last submitted patch failed testing.

dave reid’s picture

Status: Needs work » Needs review
StatusFileSize
new1.39 KB

Rerolled and retesting.

Status: Needs review » Needs work

The last submitted patch failed testing.

jody lynn’s picture

Status: Needs review » Needs work
StatusFileSize
new5.3 KB

The test failure was correctly identifying an issue in taxonomy module related to submit function handling.

There was trouble in how taxonomy vocabulary deletion was calling the submit function in the confirm delete form (the confirm delete submit function was competing with the submit function of the vocabulary edit form itself). I moved the call to mirror how taxonomy term deletion is already coded. Not sure if this should be a new issue.

jody lynn’s picture

Status: Needs work » Needs review
cburschka’s picture

   $form['teaser_length'] = array(
-    '#type' => 'select', '#title' => t('Length of trimmed posts'),
-    '#default_value' => 600,
-    '#options' => drupal_map_assoc(array(0, 200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000), '_node_characters'),
-    '#description' => t("The maximum number of characters used in the trimmed version of a post. Drupal will use this setting to determine at which offset long posts should be trimmed. The trimmed version of a post is typically used as a teaser when displaying the post on the main page, in XML feeds, etc. To disable teasers, set to 'Unlimited' . Note that this setting will only affect new or updated content and will not affect existing teasers.")
+    '#type' => 'textfield',
+    '#title' => t('Length of trimmed posts'),
+    '#default_value' => variable_get('teaser_length', 600),
+    '#size' => 4,
+    '#field_suffix' => t('characters'),
+    '#description' => t("The maximum number of characters used in the trimmed version of a post. Drupal will use this setting to determine at which offset long posts should be trimmed. The trimmed version of a post is typically used as a teaser when displaying the post on the main page, in XML feeds, etc. To disable teasers, set to 0. Note that this setting will only affect new or updated content and will not affect existing teasers.")

Relevant to drupal_prepare_form()? This patch isn't what it says on the tin.

wickedskaman’s picture

Is this still being ported to D6 or has this happened already?

dave reid’s picture

Issue tags: -Quick fix, -forms +form API

Re-rolled just with the basic part. Want to see how much is still broken with taxonomy.module.

@wickedskaman: It's still in progress for D7, and needs to be backported.

dave reid’s picture

Status: Needs work » Needs review
StatusFileSize
new1.87 KB

Status: Needs review » Needs work

The last submitted patch failed testing.

wickedskaman’s picture

Thank you for the prompt reply. I have spent a couple thankless hours troubleshooting a system settings form not realizing it's an honest to goodness bug. Waah waaaah. Thanks again.

jody lynn’s picture

Status: Needs work » Needs review
StatusFileSize
new1.96 KB

Re submit.

Status: Needs review » Needs work

The last submitted patch failed testing.

sun’s picture

Status: Needs work » Needs review
StatusFileSize
new1.23 KB

The usage of array_unshift() limits the possible use-cases without reason.

An wrapping form implementation like http://api.drupal.org/api/function/user_profile_form/7 and http://api.drupal.org/api/function/user_account_form/7 may want to invoke the #submit handler from the inner form before the #submit handler of the outer form.

That said, and looking at aforementioned wrapper, this change requires to go through all of core and remove #submit handlers... oh wait

sun’s picture

StatusFileSize
new1.38 KB

Of course, we do not want to break existing implementations like aforementioned http://api.drupal.org/api/function/user_profile_form/7

Hence, this only needs to happen if the form handler is not contained already.

sun’s picture

StatusFileSize
new2.25 KB

And why do we special case #type defaults here?

Status: Needs review » Needs work

The last submitted patch failed testing.

sun’s picture

Status: Needs work » Needs review

This patch breaks http://api.drupal.org/api/function/taxonomy_form_vocabulary/7

...and therefore it potentially breaks all multistep form handling and/or all wizard-alike form builders like this example in core (which I didn't even know exists).

Hence, except for the #type fixes... this is a won't fix for me.

cburschka’s picture

Just stumbled over this bug again. It really is kind of nasty.

sun’s picture

Status: Needs review » Closed (won't fix)
Issue tags: -Needs backport to D6, -form API

Form constructors have to be able to explicitly set #validate and #submit to an empty array, so as to explicitly disable the default callbacks, even if they exist. See node_form() for an example.

The #type clean-up from the last patch would be nice to do, but effectively is a separate issue.