Smarty Forum Index Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon.

3.1.3, html_checkboxes: HTML-content of labels is escaped

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Bugs
View previous topic :: View next topic  
Author Message
Estigy
Smarty Rookie


Joined: 16 Nov 2011
Posts: 5

PostPosted: Wed Nov 16, 2011 10:35 am    Post subject: 3.1.3, html_checkboxes: HTML-content of labels is escaped Reply with quote

Hi.

Starting with Smarty 3.1.3, all the content of the <label> in html_checkboxes is getting escaped, breaking output that contains HTML tags like "<br />".

The problem is on line 186:
Code:
$output = smarty_function_escape_special_chars($output);


Greetz,
Günther.
Back to top
View user's profile Send private message
rodneyrehm
Administrator


Joined: 30 Mar 2007
Posts: 674
Location: Germany, border to Switzerland

PostPosted: Wed Nov 16, 2011 11:30 am    Post subject: Reply with quote

I introduced the parameter escape to html_checkboxes and html_radios. You can set escape=false to get the pre-3.1.3 behaviour (which may open XSS, which is why we changed this…). The patch is in SVN trunk and will be released with Smarty 3.1.6.
_________________
Twitter
Back to top
View user's profile Send private message Visit poster's website
Estigy
Smarty Rookie


Joined: 16 Nov 2011
Posts: 5

PostPosted: Wed Nov 16, 2011 11:44 am    Post subject: Reply with quote

Hi, thanks for the quick answer!

I'd vote for setting the default value of the new "escape" parameter to "false".
Within the <label> tag other tags are perfectly allowed. I don't see this being the responsibility of Smarty to handle this.

And: It would break backwards-compatibility. I wouldn't want all Smarty users to change all their templates in order to turn off something they should have handled in the first place.

Maybe you can make this a configuration option I can set when instantiating Smarty?

Thanks, Günther.
Back to top
View user's profile Send private message
adibou
Smarty n00b


Joined: 22 Mar 2012
Posts: 1

PostPosted: Thu Mar 22, 2012 4:40 pm    Post subject: Reply with quote

Hi
Is it possible to get this escape parameter for html_options too ?
I tried to modify smarty_function_html_options_optoutput() but I think the values between <option></option> are filtered after, somewhere in Smarty code... and I never found where.
When escape=false, I ignore smarty_function_escape_special_chars(), and my <span> localized in my value stays, but when the whole template is compiled, this tag localized in <option></option> is striped !

Code:

<?php
/**
 * Smarty plugin
 *
 * @package Smarty
 * @subpackage PluginsFunction
 */

/**
 * Smarty {html_options} function plugin
 *
 * Type:     function<br>
 * Name:     html_options<br>
 * Purpose:  Prints the list of <option> tags generated from
 *           the passed parameters<br>
 * Params:
 * <pre>
 * - name       (optional) - string default "select"
 * - values     (required) - if no options supplied) - array
 * - options    (required) - if no values supplied) - associative array
 * - selected   (optional) - string default not set
 * - output     (required) - if not options supplied) - array
 * - id         (optional) - string default not set
 * - class      (optional) - string default not set
 * - escape      (optional) - escape the content (not value), defaults to true AC 22-03-2012
 * </pre>
 *
 * @link http://www.smarty.net/manual/en/language.function.html.options.php {html_image}
 *      (Smarty online manual)
 * @author Monte Ohrt <monte at ohrt dot com>
 * @author Ralf Strehle (minor optimization) <ralf dot strehle at yahoo dot de>
 * @param array                    $params   parameters
 * @param Smarty_Internal_Template $template template object
 * @return string
 * @uses smarty_function_escape_special_chars()
 */

function smarty_function_html_options($params, $template)
{
    require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');

    $name = null;
    $values = null;
    $options = null;
    $selected = null;
    $output = null;
    $id = null;
    $class = null;
    $escape = true; // AC 22-03-2012

    $extra = '';

    foreach ($params as $_key => $_val) {
        switch ($_key) {
            case 'name':
            case 'class':
            case 'id':
                $$_key = (string) $_val;
                break;

            case 'options':
                $options = (array) $_val;
                break;

            case 'values':
            case 'output':
                $$_key = array_values((array) $_val);
                break;
            
         // AC 22-03-2012
         case 'escape':
            $$_key = (bool) $_val;
            break;

            case 'selected':
                if (is_array($_val)) {
                    $selected = array();
                    foreach ($_val as $_sel) {
                        if (is_object($_sel)) {
                            if (method_exists($_sel, "__toString")) {
                                $_sel = smarty_function_escape_special_chars((string) $_sel->__toString());
                            } else {
                                trigger_error("html_options: selected attribute contains an object of class '". get_class($_sel) ."' without __toString() method", E_USER_NOTICE);
                                continue;
                            }
                        } else {
                            $_sel = smarty_function_escape_special_chars((string) $_sel);
                        }
                        $selected[$_sel] = true;
                    }
                } elseif (is_object($_val)) {
                    if (method_exists($_val, "__toString")) {
                        $selected = smarty_function_escape_special_chars((string) $_val->__toString());
                    } else {
                        trigger_error("html_options: selected attribute is an object of class '". get_class($_val) ."' without __toString() method", E_USER_NOTICE);
                    }
                } else {
                    $selected = smarty_function_escape_special_chars((string) $_val);
                }
                break;

            default:
                if (!is_array($_val)) {
                    $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
                } else {
                    trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
                }
                break;
        }
    }

    if (!isset($options) && !isset($values)) {
        /* raise error here? */
        return '';
    }

    $_html_result = '';
    $_idx = 0;

    if (isset($options)) {
        foreach ($options as $_key => $_val) {
           //$test .= $_val . '\n';
            $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $_idx, $escape);
        }
    } else {
        foreach ($values as $_i => $_key) {
            $_val = isset($output[$_i]) ? $output[$_i] : '';
            $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $_idx, $escape);
        }
    }

    if (!empty($name)) {
        $_html_class = !empty($class) ? ' class="'.$class.'"' : '';
        $_html_id = !empty($id) ? ' id="'.$id.'"' : '';
        $_html_result = '<select name="' . $name . '"' . $_html_class . $_html_id . $extra . '>' . "\n" . $_html_result . '</select>' . "\n";
    }

    return $_html_result;
}

function smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, &$idx, $escape = true)
{
    if (!is_array($value)) {
        $_key = smarty_function_escape_special_chars($key);
        $_html_result = '<option value="' . $_key . '"';
        if (is_array($selected)) {
            if (isset($selected[$_key])) {
                $_html_result .= ' selected="selected"';
            }
        } elseif ($_key === $selected) {
            $_html_result .= ' selected="selected"';
        }
        $_html_class = !empty($class) ? ' class="'.$class.' option"' : '';
        $_html_id = !empty($id) ? ' id="'.$id.'-'.$idx.'"' : '';
        if (is_object($value)) {
            if (method_exists($value, "__toString")) {
               if ($escape)
                   $value = smarty_function_escape_special_chars((string) $value->__toString());
            else
               $value = (string) $value->__toString();
            } else {
                trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE);
                return '';
            }
        }
        $_html_result .= $_html_class . $_html_id . '>' . $value . '</option>' . "\n";
        $idx++;
    } else {
        $_idx = 0;
        $_html_result = smarty_function_html_options_optgroup($key, $value, $selected, !empty($id) ? ($id.'-'.$idx) : null, $class, $_idx, $escape);
        $idx++;
    }
    return $_html_result;
}

function smarty_function_html_options_optgroup($key, $values, $selected, $id, $class, &$idx, $escape = true)
{
    $optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n";
    foreach ($values as $key => $value) {
        $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, $idx, $escape);
    }
    $optgroup_html .= "</optgroup>\n";
    return $optgroup_html;
}

?>


Thanks !
Back to top
View user's profile Send private message
rodneyrehm
Administrator


Joined: 30 Mar 2007
Posts: 674
Location: Germany, border to Switzerland

PostPosted: Fri Mar 23, 2012 9:54 am    Post subject: Reply with quote

adibou wrote:
Hi
Is it possible to get this escape parameter for html_options too ?
I tried to modify smarty_function_html_options_optoutput() but I think the values between <option></option> are filtered after, somewhere in Smarty code... and I never found where.
When escape=false, I ignore smarty_function_escape_special_chars(), and my <span> localized in my value stays, but when the whole template is compiled, this tag localized in <option></option> is striped !


You know that <option> may not contain any child elements?
_________________
Twitter
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Bugs All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP