I have several select option lists I must use on my forms are generated externally. Some of the options in these lists contain "&" in the value. When a form is submitted, selected options which have a "&" in the value are not stored.

I've attached a test webform node export.

Steps:

  1. Import provided test webform or generate webform with a select multiple component which contains options having & in the value
    • Rocky & Bullwinkle|Rocky & Bullwinkle
    • Moose and Squirrel|Moose and Squirrel
  2. View form
  3. Check all options
  4. Submit form
  5. View submission result via admin.

Expected result:
- All options are included in the submission.

Observed result:
- Not all options are recorded in the submission. The options containing "&" in the value are omitted.

This is also reproducible this by adding a pagebreak and navigating back and forth. When returning to the page with the select, options with "&" in the value which had been selected are cleared.

I only tested the checkbox variant of the select component. I assume other variants (radio, select, select multiple) are affected as well.

Comments

jwineinger’s picture

Title: Select option values are not or improperly escaped » Select option values are improperly escaped

better title

quicksketch’s picture

The quick solution for this is to use a key with alphanumeric characters like this:

rocky_bullwinkle|Rocky & Bullwinkle
moose_squirrel|Moose and Squirrel

Though I think you're right, all characters should be allowed or at least we should add validation to prevent problems with keys.

jwineinger’s picture

Yes that is a solution but not one that works in my case. I am using a custom module that generates option lists from an external source (Salesforce). Thus, I have no control over the options provided. Validation wouldn't help in this case either, since I can't do anything about their data except ask them to kindly change it (which they may not).

quicksketch’s picture

Title: Select option values are improperly escaped » Escaped checkbox option values are not saved (keys with quotes or ampersands)

This is a tricky problem. If we don't escape the value of checkboxes, then users can enter single or double quotes and cause the HTML rendering to break. According to HTML spec, the contents of a "value" attribute should be HTML encoded before displaying. So Webform's escaping is technically correct, but Drupal can't keep track of the submitted values correctly.

A good temporary solution is just to display the select component as a list, which doesn't have all the bugs of checkboxes (which are notoriously difficult to deal with). I fiddled with trying to fix this problem but didn't have much success.

cyberwolf’s picture

Subscribing.

quicksketch’s picture

Issue summary: View changes

This problem still exists in the latest 4.x version as well. Using an ampersand in the key value of a checkbox throws the "An illegal choice has been detected. Please contact the site administrator." error message.

danchadwick’s picture

Version: 6.x-3.2 » 7.x-4.x-dev
danchadwick’s picture

Testing the current implementation (7.x-4.3):

TEST CASES
blue & red|Blue & Red
a > b|a > b
Dan's|Dan's
"no way"|"no way"
<script>alert("hi");</script>|<script>alert("hi");</script>
<strong>stronger</strong>|<strong>stronger</strong>

LISTBOX / MULTIPLE
Displayed in form exactly as human values.
Displayed in submission as safe HTML: a > b, alert("hi"); stronger (in bold)
Saved in database as exact machine values.
Verdict: Acceptable. Better if form matched submissions.

LISTBOX / SINGLE
Same as multple

NOT LISTBOX / MULTIPLE = CHECKBOXES
Displayed in form as safe HTML (same as LISTBOX submission). Form cannot be submitted.
Verdict: Failure

NOT LISTBOX / SINGLE = RADIO BUTTONS
Displayed in form as safe HTML (same as LISTBOX submission).
Displayed in submission same as form.
Saved in database as exact machine values.
Verdict: Perfect

Edit: Hmmm. The code tags mess with line spacing in a very odd way. Oh well.

danchadwick’s picture

Status: Active » Needs review
StatusFileSize
new2.01 KB

Researching this. Webform currently contains the following replacement for expanding checkboxes. It installs this in lieu of form_process_checkboxes().

function webform_expand_checkboxes($element) {
  // Elements that have a value set are already in the form structure cause
  // them not to be written when the expand_checkboxes function is called.
  $default_value = array();
  foreach (element_children($element) as $key) {
    if (isset($element[$key]['#default_value'])) {
      $default_value[$key] = $element[$key]['#default_value'];
      unset($element[$key]);
    }
  }

  $element = form_process_checkboxes($element);

  // Escape the values of checkboxes.
  foreach (element_children($element) as $key) {
    $element[$key]['#return_value'] = check_plain($element[$key]['#return_value']);
    $element[$key]['#name'] = $element['#name'] . '[' . $element[$key]['#return_value'] . ']';
  }

  foreach ($default_value as $key => $val) {
    $element[$key]['#default_value'] = $val;
  }

  return $element;
}

The D6 issue where the code to remove and re-created the defaulted checkboxes:
#243839: Page Break not working in Drupal 6

The D6 issue where the escaping was added:
#354240: Answers in select fields not accepted if questions contain apostrophe AND the field accepts multiple answers

The D7 issue where the #process function is rather carefully installed to avoid conflicts with other #process functions:
#1188774: Select compoent should not directly set '#process' option for select_or_other

In my testing, this process function is entirely not needed. The escaping results in double-escaping (and hence the bug reported here). The key is placed in the 'value' attribute of the input element, and is escaped with check_plain in drupal_attributes. The value is placed in #return_value, which gets turned into the value attribute and is also escaped above.

I can't reproduce any issue with these elements already being in the form for some reason. There is a comment implying an issue with multi-page forms, but I could not reproduce any such issue. I suspect this is related to some D6 issue which is no longer needed in D7.

I've uploaded a patch which simply removes the above process function. I would like some thorough testing of difficult checkbox keys and values, and editing existing already-checked submissions. Difficult keys should include keys that need escaping, such as & and attempts to introduce XSS vulnerabilities, such as:

a<script>alert('key');</script>b|There should be no alert <script>alert('value');</script>

  • DanChadwick committed a30403a on 7.x-4.x
    Issue #914814 by DanChadwick: Fixed escaped checkbox option values are...
  • DanChadwick committed 5fb01eb on 8.x-4.x
    Issue #914814 by DanChadwick: Fixed escaped checkbox option values are...
danchadwick’s picture

Status: Needs review » Fixed

Committed to 7.x-4.x and 8.x

  • torotil committed 68c13a6 on 7.x-3.x authored by DanChadwick
    Issue #914814 by DanChadwick: Fixed escaped checkbox option values are...
torotil’s picture

I've cherry-picked this into 7.x-3.x and it will be part of the 7.x-3.23 release.

There was a merge conflict so I'm also attaching the patch.

torotil’s picture

Version: 7.x-4.x-dev » 7.x-3.x-dev

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.