From a154fe871ecde437e50574929514005372ed936e Mon Sep 17 00:00:00 2001 From: quietone <quietone@2572884.no-reply.drupal.org> Date: Mon, 28 Aug 2023 21:14:08 +1200 Subject: [PATCH] Issue #2944421 by sathish.redcrackle, ressa, Lendude, ankithashetty, udayraj123, smustgrave, DuaelFr, JeroenT, alexpott: Double exposed filter field when trying to use "q" as identifier --- .../Plugin/views/filter/FilterPluginBase.php | 28 +++++++++++++--- .../src/Functional/Plugin/ExposedFormTest.php | 32 +++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php index f8d03e12b72c..c0fcde77ea36 100644 --- a/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php +++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php @@ -46,6 +46,23 @@ */ abstract class FilterPluginBase extends HandlerBase implements CacheableDependencyInterface { + /** + * A list of restricted identifiers. + * + * This list contains strings that could cause clashes with other site + * operations when used as a filter identifier. + * + * @var array + */ + const RESTRICTED_IDENTIFIERS = [ + 'value', + 'q', + 'destination', + '_format', + '_wrapper_format', + 'token', + ]; + /** * The value. * @@ -660,7 +677,8 @@ public function buildExposeForm(&$form, FormStateInterface $form_state) { '#default_value' => $this->options['expose']['identifier'], '#title' => $this->t('Filter identifier'), '#size' => 40, - '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank. Only letters, digits and the dot ("."), hyphen ("-"), underscore ("_"), and tilde ("~") characters are allowed.'), + '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank. Only letters, digits and the dot ("."), hyphen ("-"), underscore ("_"), and tilde ("~") characters are allowed. @reserved_identifiers are reserved words and cannot be used.', + ['@reserved_identifiers' => '"' . implode('", "', self::RESTRICTED_IDENTIFIERS) . '"']), ]; } @@ -771,7 +789,7 @@ protected function validateIdentifier($identifier, FormStateInterface $form_stat if (empty($identifier)) { $error = $this->t('The identifier is required if the filter is exposed.'); } - elseif ($identifier == 'value') { + elseif (in_array($identifier, self::RESTRICTED_IDENTIFIERS)) { $error = $this->t('This identifier is not allowed.'); } elseif (preg_match('/[^a-zA-Z0-9_~\.\-]+/', $identifier)) { @@ -1029,7 +1047,8 @@ protected function buildExposedFiltersGroupForm(&$form, FormStateInterface $form '#default_value' => $identifier, '#title' => $this->t('Filter identifier'), '#size' => 40, - '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank. Only letters, digits and the dot ("."), hyphen ("-"), underscore ("_"), and tilde ("~") characters are allowed.'), + '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank. Only letters, digits and the dot ("."), hyphen ("-"), underscore ("_"), and tilde ("~") characters are allowed. @reserved_identifiers are reserved words and cannot be used.', + ['@reserved_identifiers' => '"' . implode('", "', self::RESTRICTED_IDENTIFIERS) . '"']), ]; $form['group_info']['label'] = [ '#type' => 'textfield', @@ -1083,7 +1102,8 @@ protected function buildExposedFiltersGroupForm(&$form, FormStateInterface $form '#default_value' => $identifier, '#title' => $this->t('Filter identifier'), '#size' => 40, - '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank. Only letters, digits and the dot ("."), hyphen ("-"), underscore ("_"), and tilde ("~") characters are allowed.'), + '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank. Only letters, digits and the dot ("."), hyphen ("-"), underscore ("_"), and tilde ("~") characters are allowed. @reserved_identifiers are reserved words and cannot be used.', + ['@reserved_identifiers' => '"' . implode('", "', self::RESTRICTED_IDENTIFIERS) . '"']), ]; $form['group_info']['label'] = [ '#type' => 'textfield', diff --git a/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php b/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php index 4f6dd5b84460..99bfb6baabf5 100644 --- a/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php @@ -9,6 +9,7 @@ use Drupal\views\ViewExecutable; use Drupal\views\Views; use Drupal\views\Entity\View; +use Drupal\views\Plugin\views\filter\FilterPluginBase; /** * Tests exposed forms functionality. @@ -161,6 +162,37 @@ public function testExposedIdentifier() { 'page_1' => ['This identifier has illegal characters.'], ]; $this->assertEquals($expected, $errors); + + foreach (FilterPluginBase::RESTRICTED_IDENTIFIERS as $restricted_identifier) { + $view = Views::getView('test_exposed_form_buttons'); + $view->setDisplay(); + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'type' => [ + 'exposed' => TRUE, + 'field' => 'type', + 'id' => 'type', + 'table' => 'node_field_data', + 'plugin_id' => 'in_operator', + 'entity_type' => 'node', + 'entity_field' => 'type', + 'expose' => [ + 'identifier' => $restricted_identifier, + 'label' => 'Content: Type', + 'operator_id' => 'type_op', + 'reduce' => FALSE, + 'description' => 'Exposed overridden description', + ], + ], + ]); + $this->executeView($view); + + $errors = $view->validate(); + $expected = [ + 'default' => ['This identifier is not allowed.'], + 'page_1' => ['This identifier is not allowed.'], + ]; + $this->assertEquals($expected, $errors); + } } /** -- GitLab