Advertisement
cyclingzealot

Escape strategies for Twig (in Symfony)

Oct 1st, 2014
557
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 6.24 KB | None | 0 0
  1.  
  2. /**
  3.  * Escapes a string.
  4.  *
  5.  * @param Twig_Environment $env        A Twig_Environment instance
  6.  * @param string           $string     The value to be escaped
  7.  * @param string           $strategy   The escaping strategy
  8.  * @param string           $charset    The charset
  9.  * @param Boolean          $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false)
  10.  */
  11. function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html', $charset = null, $autoescape = false)
  12. {
  13.     if ($autoescape && $string instanceof Twig_Markup) {
  14.         return $string;
  15.     }
  16.  
  17.     if (!is_string($string)) {
  18.         if (is_object($string) && method_exists($string, '__toString')) {
  19.             $string = (string) $string;
  20.         } else {
  21.             return $string;
  22.         }
  23.     }
  24.  
  25.     if (null === $charset) {
  26.         $charset = $env->getCharset();
  27.     }
  28.  
  29.     switch ($strategy) {
  30.         case 'html':
  31.             // see http://php.net/htmlspecialchars
  32.  
  33.             // Using a static variable to avoid initializing the array
  34.             // each time the function is called. Moving the declaration on the
  35.             // top of the function slow downs other escaping strategies.
  36.             static $htmlspecialcharsCharsets;
  37.  
  38.             if (null === $htmlspecialcharsCharsets) {
  39.                 if ('hiphop' === substr(PHP_VERSION, -6)) {
  40.                     $htmlspecialcharsCharsets = array('utf-8' => true, 'UTF-8' => true);
  41.                 } else {
  42.                     $htmlspecialcharsCharsets = array(
  43.                         'ISO-8859-1' => true, 'ISO8859-1' => true,
  44.                         'ISO-8859-15' => true, 'ISO8859-15' => true,
  45.                         'utf-8' => true, 'UTF-8' => true,
  46.                         'CP866' => true, 'IBM866' => true, '866' => true,
  47.                         'CP1251' => true, 'WINDOWS-1251' => true, 'WIN-1251' => true,
  48.                         '1251' => true,
  49.                         'CP1252' => true, 'WINDOWS-1252' => true, '1252' => true,
  50.                         'KOI8-R' => true, 'KOI8-RU' => true, 'KOI8R' => true,
  51.                         'BIG5' => true, '950' => true,
  52.                         'GB2312' => true, '936' => true,
  53.                         'BIG5-HKSCS' => true,
  54.                         'SHIFT_JIS' => true, 'SJIS' => true, '932' => true,
  55.                         'EUC-JP' => true, 'EUCJP' => true,
  56.                         'ISO8859-5' => true, 'ISO-8859-5' => true, 'MACROMAN' => true,
  57.                     );
  58.                 }
  59.             }
  60.  
  61.             if (isset($htmlspecialcharsCharsets[$charset])) {
  62.                 return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset);
  63.             }
  64.  
  65.             if (isset($htmlspecialcharsCharsets[strtoupper($charset)])) {
  66.                 // cache the lowercase variant for future iterations
  67.                 $htmlspecialcharsCharsets[$charset] = true;
  68.  
  69.                 return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset);
  70.             }
  71.  
  72.             $string = twig_convert_encoding($string, 'UTF-8', $charset);
  73.             $string = htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
  74.  
  75.             return twig_convert_encoding($string, $charset, 'UTF-8');
  76.  
  77.         case 'js':
  78.             // escape all non-alphanumeric characters
  79.             // into their \xHH or \uHHHH representations
  80.             if ('UTF-8' != $charset) {
  81.                 $string = twig_convert_encoding($string, 'UTF-8', $charset);
  82.             }
  83.  
  84.             if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) {
  85.                 throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.');
  86.             }
  87.  
  88.             $string = preg_replace_callback('#[^a-zA-Z0-9,\._]#Su', '_twig_escape_js_callback', $string);
  89.  
  90.             if ('UTF-8' != $charset) {
  91.                 $string = twig_convert_encoding($string, $charset, 'UTF-8');
  92.             }
  93.  
  94.             return $string;
  95.  
  96.         case 'css':
  97.             if ('UTF-8' != $charset) {
  98.                 $string = twig_convert_encoding($string, 'UTF-8', $charset);
  99.             }
  100.  
  101.             if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) {
  102.                 throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.');
  103.             }
  104.  
  105.             $string = preg_replace_callback('#[^a-zA-Z0-9]#Su', '_twig_escape_css_callback', $string);
  106.  
  107.             if ('UTF-8' != $charset) {
  108.                 $string = twig_convert_encoding($string, $charset, 'UTF-8');
  109.             }
  110.  
  111.             return $string;
  112.  
  113.         case 'html_attr':
  114.             if ('UTF-8' != $charset) {
  115.                 $string = twig_convert_encoding($string, 'UTF-8', $charset);
  116.             }
  117.  
  118.             if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) {
  119.                 throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.');
  120.             }
  121.  
  122.             $string = preg_replace_callback('#[^a-zA-Z0-9,\.\-_]#Su', '_twig_escape_html_attr_callback', $string);
  123.  
  124.             if ('UTF-8' != $charset) {
  125.                 $string = twig_convert_encoding($string, $charset, 'UTF-8');
  126.             }
  127.  
  128.             return $string;
  129.  
  130.         case 'url':
  131.             // hackish test to avoid version_compare that is much slower, this works unless PHP releases a 5.10.*
  132.             // at that point however PHP 5.2.* support can be removed
  133.             if (PHP_VERSION < '5.3.0') {
  134.                 return str_replace('%7E', '~', rawurlencode($string));
  135.             }
  136.  
  137.             return rawurlencode($string);
  138.  
  139.         default:
  140.             static $escapers;
  141.  
  142.             if (null === $escapers) {
  143.                 $escapers = $env->getExtension('core')->getEscapers();
  144.             }
  145.  
  146.             if (isset($escapers[$strategy])) {
  147.                 return call_user_func($escapers[$strategy], $env, $string, $charset);
  148.             }
  149.  
  150.             $validStrategies = implode(', ', array_merge(array('html', 'js', 'url', 'css', 'html_attr'), array_keys($escapers)));
  151.  
  152.             throw new Twig_Error_Runtime(sprintf('Invalid escaping strategy "%s" (valid ones: %s).', $strategy, $validStrategies));
  153.     }
  154. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement