From 4d26c301ac838915c5a4e328096e8ae8809ea903 Mon Sep 17 00:00:00 2001 From: David Rothstein <drothstein@gmail.com> Date: Sun, 29 Jul 2012 20:02:07 -0400 Subject: [PATCH] Issue #635046 by claudiu.cristea, sun, fago: Fixed form_state_values_clean() is polluting form values. --- CHANGELOG.txt | 2 + includes/common.inc | 5 ++- includes/form.inc | 8 ++-- modules/simpletest/tests/form.test | 47 ++++++++++++++++++++++- modules/simpletest/tests/form_test.module | 35 +++++++++++++++++ 5 files changed, 90 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 1446cc0ebbc4..69a6a4d1962d 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -41,6 +41,8 @@ Drupal 7.15, xxxx-xx-xx (development version) "Main page content" and "System help" blocks to appropriate regions by default and prevent error messages on the block administration page (data structure change). +- Changed the drupal_array_get_nested_value() function to return a reference + (API addition). Drupal 7.14 2012-05-02 ---------------------- diff --git a/includes/common.inc b/includes/common.inc index 50f20e685a95..051efd55a225 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -6493,7 +6493,7 @@ function drupal_array_set_nested_value(array &$array, array $parents, $value, $f * * @see drupal_array_set_nested_value() */ -function drupal_array_get_nested_value(array &$array, array $parents, &$key_exists = NULL) { +function &drupal_array_get_nested_value(array &$array, array $parents, &$key_exists = NULL) { $ref = &$array; foreach ($parents as $parent) { if (is_array($ref) && array_key_exists($parent, $ref)) { @@ -6501,7 +6501,8 @@ function drupal_array_get_nested_value(array &$array, array $parents, &$key_exis } else { $key_exists = FALSE; - return NULL; + $null = NULL; + return $null; } } $key_exists = TRUE; diff --git a/includes/form.inc b/includes/form.inc index 12d90053d137..7d5a28c6e30e 100644 --- a/includes/form.inc +++ b/includes/form.inc @@ -2161,12 +2161,12 @@ function form_state_values_clean(&$form_state) { // $form_state['values']['foo']['bar'], which is the level where we can // unset 'baz' (that is stored in $last_parent). $parents = $button['#parents']; - $values = &$form_state['values']; $last_parent = array_pop($parents); - foreach ($parents as $parent) { - $values = &$values[$parent]; + $key_exists = NULL; + $values = &drupal_array_get_nested_value($form_state['values'], $parents, $key_exists); + if ($key_exists && is_array($values)) { + unset($values[$last_parent]); } - unset($values[$last_parent]); } } diff --git a/modules/simpletest/tests/form.test b/modules/simpletest/tests/form.test index 5aa7e4aa31b2..d1bb171e1ede 100644 --- a/modules/simpletest/tests/form.test +++ b/modules/simpletest/tests/form.test @@ -589,7 +589,7 @@ class FormValidationTestCase extends DrupalWebTestCase { */ function testValidateLimitErrors() { $edit = array( - 'test' => 'invalid', + 'test' => 'invalid', 'test_numeric_index[0]' => 'invalid', 'test_substring[foo]' => 'invalid', ); @@ -1169,6 +1169,51 @@ class FormStateValuesCleanTestCase extends DrupalWebTestCase { } } +/** + * Tests $form_state clearance with form elements having buttons. + */ +class FormStateValuesCleanAdvancedTestCase extends DrupalWebTestCase { + /** + * An image file path for uploading. + */ + protected $image; + + public static function getInfo() { + return array( + 'name' => 'Form state values clearance (advanced)', + 'description' => 'Test proper removal of submitted form values using form_state_values_clean() when having forms with elements containing buttons like "managed_file".', + 'group' => 'Form API', + ); + } + + function setUp() { + parent::setUp('form_test'); + } + + /** + * Tests form_state_values_clean(). + */ + function testFormStateValuesCleanAdvanced() { + + // Get an image for uploading. + $image_files = $this->drupalGetTestFiles('image'); + $this->image = current($image_files); + + // Check if the physical file is there. + $this->assertTrue(is_file($this->image->uri), t("The image file we're going to upload exists.")); + + // "Browse" for the desired file. + $edit = array('files[image]' => drupal_realpath($this->image->uri)); + + // Post the form. + $this->drupalPost('form_test/form-state-values-clean-advanced', $edit, t('Submit')); + + // Expecting a 200 HTTP code. + $this->assertResponse(200, t('Received a 200 response for posted test file.')); + $this->assertRaw(t('You WIN!'), t('Found the success message.')); + } +} + /** * Tests form rebuilding. * diff --git a/modules/simpletest/tests/form_test.module b/modules/simpletest/tests/form_test.module index a6b21a41a9f8..e4ac77b12500 100644 --- a/modules/simpletest/tests/form_test.module +++ b/modules/simpletest/tests/form_test.module @@ -99,6 +99,14 @@ function form_test_menu() { 'type' => MENU_CALLBACK, ); + $items['form_test/form-state-values-clean-advanced'] = array( + 'title' => 'Form state values clearance advanced test', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('form_test_form_state_values_clean_advanced_form'), + 'access arguments' => array('access content'), + 'type' => MENU_CALLBACK, + ); + $items['form-test/checkbox'] = array( 'title' => t('Form test'), 'page callback' => 'drupal_get_form', @@ -878,6 +886,33 @@ function form_test_form_state_values_clean_form_submit($form, &$form_state) { exit; } +/** + * Form constructor for the form_state_values_clean() test. + */ +function form_test_form_state_values_clean_advanced_form($form, &$form_state) { + // Build an example form containing a managed file and a submit form element. + $form['image'] = array( + '#type' => 'managed_file', + '#title' => t('Image'), + '#upload_location' => 'public://', + '#default_value' => 0, + ); + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Submit'), + ); + return $form; +} + +/** + * Form submission handler for form_test_form_state_values_clean_advanced_form(). + */ +function form_test_form_state_values_clean_advanced_form_submit($form, &$form_state) { + form_state_values_clean($form_state); + print t('You WIN!'); + exit; +} + /** * Build a form to test a checkbox. */ -- GitLab