[patch] add $smarty->escape_output feature
Andreas Korthaus <[email protected]> Wed, 03 May 2006 20:12:22 +0200
| Newsgroups | gmane.comp.php.smarty.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi! I've had a discussion with boots in the smarty forum about a new, optional(!) smarty feature for general output escaping, which should not break BC. The idea is to provide means for projects, which like to use something like a contract, which ensures, that every output from user-input in smarty template gets escaped if a special, new Smarty member variable ($smarty->escape_output) is set (the used escape-function is modifiable). Other template engines provide something like that (e.g. flexy, savant), in Smarty this is not possible today (forget about default_modifiers). You can find the discussion here: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=7806 Attatched you can find a patch against CVS-HEAD, which implements the basic functionality. It's not ready yet, because I did not catch every point where input get's displayed without escaping. From what I understand the smarty code, I think I have catched everything beside some of the plugins. But I'm not sure here, so I'd be very happy if someone with better knowledge of the smarty compiler could check if it's OK. And I'd like to know what your general opinion about such a feature is. Best regards Andreas -- Smarty Development Mailing List (http://smarty.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
escape_patch.txt
(text/plain, 4.4 KB)
Index: libs/Smarty.class.php
===================================================================
RCS file: /repository/smarty/libs/Smarty.class.php,v
retrieving revision 1.524
diff -u -r1.524 Smarty.class.php
--- libs/Smarty.class.php 18 Jan 2006 19:02:52 -0000 1.524
+++ libs/Smarty.class.php 3 May 2006 09:41:09 -0000
@@ -398,6 +398,29 @@
*/
var $config_class = 'Config_File';
+ /**
+ * This tells Smarty whether or not to auto-escape output (variables)
+ *
+ * Available values:
+ * - null: no escaping (default)
+ * - 'html': htmlspecialchars()
+ * - 'htmlall': htmlentities()
+ * - 'url': urlencode()
+ *
+ * @var null|string escape sequence name
+ */
+ var $escape_output = null;
+
+ /**
+ * This tells Smarty what character-set to use for output encoding
+ *
+ * The character set is passed to escaping-functions, if there is a
+ * parameter for that. Default is null.
+ *
+ * @var null|string character-set
+ */
+ var $output_charset = null;
+
/**#@+
* END Smarty Configuration Section
* There should be no need to touch anything below this line.
@@ -1481,6 +1504,8 @@
$smarty_compiler->compile_id = $this->_compile_id;
$smarty_compiler->_config = $this->_config;
$smarty_compiler->request_use_auto_globals = $this->request_use_auto_globals;
+ $smarty_compiler->escape_output = $this->escape_output;
+ $smarty_compiler->output_encoding = $this->output_encoding;
if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) {
$smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path];
Index: libs/Smarty_Compiler.class.php
===================================================================
RCS file: /repository/smarty/libs/Smarty_Compiler.class.php,v
retrieving revision 1.379
diff -u -r1.379 Smarty_Compiler.class.php
--- libs/Smarty_Compiler.class.php 22 Apr 2006 08:16:57 -0000 1.379
+++ libs/Smarty_Compiler.class.php 3 May 2006 09:45:09 -0000
@@ -435,15 +435,20 @@
~xs', $template_tag, $match)) {
$this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__);
}
-
+
$tag_command = $match[1];
$tag_modifier = isset($match[2]) ? $match[2] : null;
$tag_args = isset($match[3]) ? $match[3] : null;
if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) {
- /* tag name is a variable or object */
+
+ /* tag name is a variable or object */
$_return = $this->_parse_var_props($tag_command . $tag_modifier);
- return "<?php echo $_return; " . $this->_additional_newline;
+
+ /* variable gets escaped, when $Smarty->escape_output is enabled */
+ $_return_escaped = $this->_escape_var($_return, $tag_modifier);
+
+ return "<?php echo $_return_escaped; " . $this->_additional_newline;
}
/* If the tag name is a registered object, we process it. */
@@ -2286,6 +2291,40 @@
E_USER_ERROR, __FILE__, __LINE__);
}
+ /**
+ * add output-escaping around variable
+ * (called after modifiers)
+ *
+ * @param string $var_name
+ * @param string $modifier_string
+ */
+ function _escape_var($var_name, $modifier_string)
+ {
+ /* only escape if $Smarty->escape_output is set and "noescape" modifier is not used */
+ if (!is_null($this->escape_output) && !preg_match('~(^|\|)(no)?escape($|\|)~', $modifier_string)) {
+
+ if (is_null($this->output_charset)) {
+ $_charset = '';
+ }
+ else {
+ $_charset = ',' . $this->output_charset;
+ }
+ switch ($this->escape_output) {
+ case 'html':
+ return "htmlspecialchars({$var_name}, ENT_QUOTES{$_charset});";
+ case 'htmlall':
+ return "htmlentities({$var_name}, ENT_QUOTES{$_charset});";
+ case 'url':
+ return "urlencode({$var_name});";
+ default:
+ $this->_trigger_fatal_error("Smarty output escaping error: escapement type '$this->escape_output' is not implemented");
+ }
+ }
+ else {
+ return $var_name;
+ }
+ }
+
}
/**