Permalink
Browse files

Fix issue #1953 (form values being escaped twice)

Re-instaing an improved form_prep() function, reverting most of the changes from 74ffd17.
  • Loading branch information...
narfbg committed Nov 1, 2012
1 parent ce1b02a commit 7c4d10660a0a47446474bf97e3cb65f80693f1ee
@@ -124,9 +124,9 @@ function form_open_multipart($action = '', $attributes = array(), $hidden = arra
* Generates hidden fields. You can pass a simple key/value string or
* an associative array with multiple values.
*
- * @param mixed
- * @param string
- * @param bool
+ * @param mixed $name Field name
+ * @param string $value Field value
+ * @param bool $recursing
* @return string
*/
function form_hidden($name, $value = '', $recursing = FALSE)
@@ -149,7 +149,7 @@ function form_hidden($name, $value = '', $recursing = FALSE)
if ( ! is_array($value))
{
- $form .= '<input type="hidden" name="'.$name.'" value="'.html_escape($value)."\" />\n";
+ $form .= '<input type="hidden" name="'.$name.'" value="'.form_prep($value)."\" />\n";
}
else
{
@@ -243,9 +243,9 @@ function form_upload($data = '', $value = '', $extra = '')
/**
* Textarea field
*
- * @param mixed
- * @param string
- * @param string
+ * @param mixed $data
+ * @param string $value
+ * @param string $extra
* @return string
*/
function form_textarea($data = '', $value = '', $extra = '')
@@ -263,7 +263,7 @@ function form_textarea($data = '', $value = '', $extra = '')
}
$name = is_array($data) ? $data['name'] : $data;
- return '<textarea '._parse_form_attributes($data, $defaults).$extra.'>'.html_escape($val)."</textarea>\n";
+ return '<textarea '._parse_form_attributes($data, $defaults).$extra.'>'.form_prep($val, TRUE)."</textarea>\n";
}
}
@@ -298,10 +298,10 @@ function form_multiselect($name = '', $options = array(), $selected = array(), $
/**
* Drop-down Menu
*
- * @param mixed $name = ''
- * @param mixed $options = array()
- * @param mixed $selected = array()
- * @param mixed $extra = array()
+ * @param mixed $name
+ * @param mixed $options
+ * @param mixed $selected
+ * @param mixed $extra
* @return string
*/
function form_dropdown($name = '', $options = array(), $selected = array(), $extra = '')
@@ -349,15 +349,15 @@ function form_dropdown($name = '', $options = array(), $selected = array(), $ext
foreach ($val as $optgroup_key => $optgroup_val)
{
$sel = in_array($optgroup_key, $selected) ? ' selected="selected"' : '';
- $form .= '<option value="'.html_escape($optgroup_key).'"'.$sel.'>'
+ $form .= '<option value="'.form_prep($optgroup_key).'"'.$sel.'>'
.(string) $optgroup_val."</option>\n";
}
$form .= "</optgroup>\n";
}
else
{
- $form .= '<option value="'.html_escape($key).'"'
+ $form .= '<option value="'.form_prep($key).'"'
.(in_array($key, $selected) ? ' selected="selected"' : '').'>'
.(string) $val."</option>\n";
}
@@ -600,17 +600,28 @@ function form_close($extra = '')
*
* Formats text so that it can be safely placed in a form field in the event it has HTML tags.
*
- * @todo Remove in version 3.1+.
- * @deprecated 3.0.0 This function has been broken for a long time
- * and is now just an alias for html_escape(). It's
- * second argument is ignored.
- * @param string $str = ''
- * @param string $field_name = ''
- * @return string
+ * @param string|string[] $str Value to escape
+ * @param bool $is_textarea Whether we're escaping for a textarea element
+ * @return string|string[] Escaped values
*/
- function form_prep($str = '', $field_name = '')
+ function form_prep($str = '', $is_textarea = FALSE)
{
- return html_escape($str);
+ if (is_array($str))
+ {
+ foreach (array_keys($str) as $key)
+ {
+ $str[$key] = form_prep($str[$key], $is_textarea);
+ }
+
+ return $str;
+ }
+
+ if ($is_textarea === TRUE)
+ {
+ return str_replace(array('<', '>'), array('&lt;', '&gt;'), stripslashes($str));
+ }
+
+ return str_replace(array("'", '"'), array('&#39;', '&quot;'), stripslashes($data));
}
}
@@ -625,23 +636,21 @@ function form_prep($str = '', $field_name = '')
* re-populate an input field or textarea. If Form Validation
* is active it retrieves the info from the validation class
*
- * @param string
- * @param string
- * @return mixed
+ * @param string $field Field name
+ * @param string $default Default value
+ * @param bool $is_textarea Whether the field is a textarea element
+ * @return string
*/
- function set_value($field = '', $default = '')
+ function set_value($field = '', $default = '', $is_textarea = FALSE)
{
if (FALSE === ($OBJ =& _get_validation_object()))
{
- if ( ! isset($_POST[$field]))
- {
- return html_escape($default);
- }
-
- return html_escape($_POST[$field]);
+ return isset($_POST[$field])
+ ? form_prep($_POST[$field], $is_textarea)
+ : form_prep($default, $is_textarea);
}
- return html_escape($OBJ->set_value($field, $default));
+ return form_prep($OBJ->set_value($field, $default), $is_textarea);
}
}
@@ -862,8 +871,8 @@ function validation_errors($prefix = '', $suffix = '')
*
* Helper function used by some of the form helpers
*
- * @param array
- * @param array
+ * @param array $attributes List of attributes
+ * @param array $default Default values
* @return string
*/
function _parse_form_attributes($attributes, $default)
@@ -891,7 +900,7 @@ function _parse_form_attributes($attributes, $default)
{
if ($key === 'value')
{
- $val = html_escape($val);
+ $val = form_prep($val);
}
elseif ($key === 'name' && ! strlen($default['name']))
{
@@ -1323,6 +1323,11 @@ public function valid_base64($str)
*/
public function prep_for_form($data = '')
{
+ if ($this->_safe_form_data === FALSE OR empty($data))
+ {
+ return $data;
+ }
+
if (is_array($data))
{
foreach ($data as $key => $val)
@@ -1333,11 +1338,6 @@ public function prep_for_form($data = '')
return $data;
}
- if ($this->_safe_form_data === FALSE OR $data === '')
- {
- return $data;
- }
-
return str_replace(array("'", '"', '<', '>'), array('&#39;', '&quot;', '&lt;', '&gt;'), stripslashes($data));
}
@@ -272,6 +272,21 @@ public function test_form_close()
$this->assertEquals($expected, form_close('</div></div>'));
}
+ // ------------------------------------------------------------------------
+
+ public function test_form_prep()
+ {
+ $this->assertEquals(
+ 'Here is a string containing &quot;quoted&quot; text.',
+ form_prep('Here is a string containing "quoted" text.')
+ );
+
+ $this->assertEquals(
+ 'Here is a string containing a &lt;tag&gt;.',
+ form_prep('Here is a string containing a <tag>.', TRUE)
+ );
+ }
+
}
/* End of file form_helper_test.php */
@@ -77,7 +77,7 @@ Release Date: Not Released
- Added a work-around in ``force_download()`` for a bug Android <= 2.1, where the filename extension needs to be in uppercase.
- :doc:`Form Helper <helpers/form_helper>` changes include:
- ``form_dropdown()`` will now also take an array for unity with other form helpers.
- - ``form_prep()`` is now **DEPRECATED** and only acts as an alias for :doc:`common function <general/common_functions>` ``html_escape()``.
+ - ``form_prep()``'s second argument now only accepts a boolean value, which determines whether the value is escaped for a *textarea* or a regular *input* element.
- ``do_hash()`` now uses PHP's native ``hash()`` function (supporting more algorithms) and is deprecated.
- Removed previously deprecated helper function ``js_insert_smiley()`` from :doc:`Smiley Helper <helpers/smiley_helper>`.
- :doc:`File Helper <helpers/file_helper>` changes include:
@@ -463,6 +463,26 @@ the tag. For example
echo form_close($string);
// Would produce: </form> </div></div>
+form_prep()
+===========
+
+Allows you to safely use HTML and characters such as quotes within form
+elements without breaking out of the form. Consider this example
+::
+
+ $string = 'Here is a string containing "quoted" text.';
+ <input type="text" name="myform" value="$string" />
+
+Since the above string contains a set of quotes it will cause the form
+to break. The ``form_prep()`` function converts HTML so that it can be used
+safely::
+
+ <input type="text" name="myform" value="<?php echo form_prep($string); ?>" />
+
+.. note:: If you use any of the form helper functions listed in this page the form
+ values will be prepped automatically, so there is no need to call this
+ function. Use it only if you are creating your own form elements.
+
set_value()
===========
@@ -523,26 +543,4 @@ This function is identical to the **set_checkbox()** function above.
.. note:: If you are using the Form Validation class, you must always specify a rule for your field,
even if empty, in order for the set_*() functions to work. This is because if a Form Validation object
is defined, the control for set_*() is handed over to a method of the class instead of the generic helper
- function.
-
-Escaping field values
-=====================
-
-You may need to use HTML and characters such as quotes within form
-elements. In order to do that safely, you'll need to use
-:doc:`common function <../general/common_functions>` ``html_escape()``.
-
-Consider the following example::
-
- $string = 'Here is a string containing "quoted" text.';
- <input type="text" name="myform" value="$string" />
-
-Since the above string contains a set of quotes it will cause the form
-to break. The ``html_escape()`` function converts HTML so that it can be
-used safely::
-
- <input type="text" name="myform" value="<?php echo html_escape($string); ?>" />
-
-.. note:: If you use any of the form helper functions listed in this page, the form
- values will be prepped automatically, so there is no need to call this
- function. Use it only if you are creating your own form elements.
+ function.
@@ -163,16 +163,6 @@ String helper repeater()
PHP's native ``str_repeat()`` function. It is deprecated and scheduled for removal in
CodeIgniter 3.1+.
-.. note:: This function is still available, but you're strongly encouraged to remove it's usage sooner
- rather than later.
-
-Form helper form_prep()
-=======================
-
-:doc:`Form Helper <../helpers/form_helper>` function ``form_prep()`` is now just an alias for
-:doc:`common function <../general/common_functions>` ``html_escape()`` and it's second argument
-is ignored. It is deprecated and scheduled for removal in CodeIgniter 3.1+.
-
.. note:: This function is still available, but you're strongly encouraged to remove it's usage sooner
rather than later.

0 comments on commit 7c4d106

Please sign in to comment.