[OutputEscaping] refactor the component to take advantage of new PHP 5.3 features
This commit is contained in:
parent
5c20bfec92
commit
26f1434b14
@ -59,7 +59,7 @@ class ArrayDecorator extends GetterDecorator implements \Iterator, \ArrayAccess,
|
|||||||
*/
|
*/
|
||||||
public function current()
|
public function current()
|
||||||
{
|
{
|
||||||
return Escaper::escape($this->escapingMethod, current($this->value));
|
return Escaper::escape($this->escaper, current($this->value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,7 +107,7 @@ class ArrayDecorator extends GetterDecorator implements \Iterator, \ArrayAccess,
|
|||||||
*/
|
*/
|
||||||
public function offsetGet($offset)
|
public function offsetGet($offset)
|
||||||
{
|
{
|
||||||
return Escaper::escape($this->escapingMethod, $this->value[$offset]);
|
return Escaper::escape($this->escaper, $this->value[$offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
namespace Symfony\Components\OutputEscaper;
|
namespace Symfony\Components\OutputEscaper;
|
||||||
|
|
||||||
require_once __DIR__.'/escaping_helpers.php';
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of the symfony package.
|
* This file is part of the symfony package.
|
||||||
*
|
*
|
||||||
@ -31,32 +29,35 @@ abstract class Escaper
|
|||||||
protected $value;
|
protected $value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The escaping method that is going to be applied to the value and its
|
* The escaper (a PHP callable) that is going to be applied to the value and its
|
||||||
* children. This is actually a PHP callable.
|
* children.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $escapingMethod;
|
protected $escaper;
|
||||||
|
|
||||||
static protected $charset = 'UTF-8';
|
static protected $charset = 'UTF-8';
|
||||||
|
|
||||||
static protected $safeClasses = array();
|
static protected $safeClasses = array();
|
||||||
|
static protected $escapers;
|
||||||
static protected $strategies = array();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor stores the escaping method and value.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* Since Escaper is an abstract class, instances cannot be created
|
* Since Escaper is an abstract class, instances cannot be created
|
||||||
* directly but the constructor will be inherited by sub-classes.
|
* directly but the constructor will be inherited by sub-classes.
|
||||||
*
|
*
|
||||||
* @param string $escapingMethod Escaping method
|
* @param string $callable A PHP callable
|
||||||
* @param string $value Escaping value
|
* @param string $value Escaping value
|
||||||
*/
|
*/
|
||||||
public function __construct($escapingMethod, $value)
|
public function __construct($escaper, $value)
|
||||||
{
|
{
|
||||||
$this->value = $value;
|
if (null === self::$escapers)
|
||||||
$this->escapingMethod = $escapingMethod;
|
{
|
||||||
|
self::initializeEscapers();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->escaper = is_string($escaper) && isset(self::$escapers[$escaper]) ? self::$escapers[$escaper] : $escaper;
|
||||||
|
$this->value = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,31 +79,41 @@ abstract class Escaper
|
|||||||
* method calls is escaped.
|
* method calls is escaped.
|
||||||
*
|
*
|
||||||
* The escaping method is actually a PHP callable. This class hosts a set
|
* The escaping method is actually a PHP callable. This class hosts a set
|
||||||
* of standard escaping methods.
|
* of standard escaping strategies.
|
||||||
*
|
*
|
||||||
* @param string $escapingMethod The escaping method (a PHP callable) to apply to the value
|
* @param string $escaper The escaping method (a PHP callable) to apply to the value
|
||||||
* @param mixed $value The value to escape
|
* @param mixed $value The value to escape
|
||||||
*
|
*
|
||||||
* @return mixed Escaping value
|
* @return mixed Escaped value
|
||||||
*
|
*
|
||||||
* @throws \InvalidArgumentException If the escaping fails
|
* @throws \InvalidArgumentException If the escaping fails
|
||||||
*/
|
*/
|
||||||
static public function escape($escapingMethod, $value)
|
static public function escape($escaper, $value)
|
||||||
{
|
{
|
||||||
if (null === $value)
|
if (null === $value)
|
||||||
{
|
{
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null === self::$escapers)
|
||||||
|
{
|
||||||
|
self::initializeEscapers();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($escaper) && isset(self::$escapers[$escaper]))
|
||||||
|
{
|
||||||
|
$escaper = self::$escapers[$escaper];
|
||||||
|
}
|
||||||
|
|
||||||
// Scalars are anything other than arrays, objects and resources.
|
// Scalars are anything other than arrays, objects and resources.
|
||||||
if (is_scalar($value))
|
if (is_scalar($value))
|
||||||
{
|
{
|
||||||
return call_user_func($escapingMethod, $value);
|
return call_user_func($escaper, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_array($value))
|
if (is_array($value))
|
||||||
{
|
{
|
||||||
return new ArrayDecorator($escapingMethod, $value);
|
return new ArrayDecorator($escaper, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_object($value))
|
if (is_object($value))
|
||||||
@ -112,29 +123,29 @@ abstract class Escaper
|
|||||||
// avoid double decoration
|
// avoid double decoration
|
||||||
$copy = clone $value;
|
$copy = clone $value;
|
||||||
|
|
||||||
$copy->escapingMethod = $escapingMethod;
|
$copy->escaper = $escaper;
|
||||||
|
|
||||||
return $copy;
|
return $copy;
|
||||||
}
|
}
|
||||||
else if (self::isClassMarkedAsSafe(get_class($value)))
|
elseif (self::isClassMarkedAsSafe(get_class($value)))
|
||||||
{
|
{
|
||||||
// the class or one of its children is marked as safe
|
// the class or one of its children is marked as safe
|
||||||
// return the unescaped object
|
// return the unescaped object
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
else if ($value instanceof Safe)
|
elseif ($value instanceof Safe)
|
||||||
{
|
{
|
||||||
// do not escape objects marked as safe
|
// do not escape objects marked as safe
|
||||||
// return the original object
|
// return the original object
|
||||||
return $value->getValue();
|
return $value->getValue();
|
||||||
}
|
}
|
||||||
else if ($value instanceof \Traversable)
|
elseif ($value instanceof \Traversable)
|
||||||
{
|
{
|
||||||
return new IteratorDecorator($escapingMethod, $value);
|
return new IteratorDecorator($escaper, $value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new ObjectDecorator($escapingMethod, $value);
|
return new ObjectDecorator($escaper, $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,7 +257,7 @@ abstract class Escaper
|
|||||||
*/
|
*/
|
||||||
public function __get($var)
|
public function __get($var)
|
||||||
{
|
{
|
||||||
return $this->escape($this->escapingMethod, $this->value->$var);
|
return $this->escape($this->escaper, $this->value->$var);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -268,4 +279,101 @@ abstract class Escaper
|
|||||||
{
|
{
|
||||||
return self::$charset;
|
return self::$charset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a named escaper.
|
||||||
|
*
|
||||||
|
* @param string $name The escaper name
|
||||||
|
* @param mixed $escaper A PHP callable
|
||||||
|
*/
|
||||||
|
static public function setEscaper($name, $escaper)
|
||||||
|
{
|
||||||
|
self::$escapers[$name] = $escaper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the built-in escapers.
|
||||||
|
*
|
||||||
|
* Each function specifies a way for applying a transformation to a string
|
||||||
|
* passed to it. The purpose is for the string to be "escaped" so it is
|
||||||
|
* suitable for the format it is being displayed in.
|
||||||
|
*
|
||||||
|
* For example, the string: "It's required that you enter a username & password.\n"
|
||||||
|
* If this were to be displayed as HTML it would be sensible to turn the
|
||||||
|
* ampersand into '&' and the apostrophe into '&aps;'. However if it were
|
||||||
|
* going to be used as a string in JavaScript to be displayed in an alert box
|
||||||
|
* it would be right to leave the string as-is, but c-escape the apostrophe and
|
||||||
|
* the new line.
|
||||||
|
*
|
||||||
|
* For each function there is a define to avoid problems with strings being
|
||||||
|
* incorrectly specified.
|
||||||
|
*/
|
||||||
|
static function initializeEscapers()
|
||||||
|
{
|
||||||
|
self::$escapers = array(
|
||||||
|
'htmlspecialchars' =>
|
||||||
|
/**
|
||||||
|
* Runs the PHP function htmlspecialchars on the value passed.
|
||||||
|
*
|
||||||
|
* @param string $value the value to escape
|
||||||
|
*
|
||||||
|
* @return string the escaped value
|
||||||
|
*/
|
||||||
|
function ($value)
|
||||||
|
{
|
||||||
|
// Numbers and boolean values get turned into strings which can cause problems
|
||||||
|
// with type comparisons (e.g. === or is_int() etc).
|
||||||
|
return is_string($value) ? htmlspecialchars($value, ENT_QUOTES, Escaper::getCharset()) : $value;
|
||||||
|
},
|
||||||
|
|
||||||
|
'entities' =>
|
||||||
|
/**
|
||||||
|
* Runs the PHP function htmlentities on the value passed.
|
||||||
|
*
|
||||||
|
* @param string $value the value to escape
|
||||||
|
* @return string the escaped value
|
||||||
|
*/
|
||||||
|
function ($value)
|
||||||
|
{
|
||||||
|
// Numbers and boolean values get turned into strings which can cause problems
|
||||||
|
// with type comparisons (e.g. === or is_int() etc).
|
||||||
|
return is_string($value) ? htmlentities($value, ENT_QUOTES, Escaper::getCharset()) : $value;
|
||||||
|
},
|
||||||
|
|
||||||
|
'raw' =>
|
||||||
|
/**
|
||||||
|
* An identity function that merely returns that which it is given, the purpose
|
||||||
|
* being to be able to specify that the value is not to be escaped in any way.
|
||||||
|
*
|
||||||
|
* @param string $value the value to escape
|
||||||
|
* @return string the escaped value
|
||||||
|
*/
|
||||||
|
function ($value) { return $value; },
|
||||||
|
|
||||||
|
'js' =>
|
||||||
|
/**
|
||||||
|
* A function that c-escapes a string after applying (cf. entities). The
|
||||||
|
* assumption is that the value will be used to generate dynamic HTML in some
|
||||||
|
* way and the safest way to prevent mishap is to assume the value should have
|
||||||
|
* HTML entities set properly.
|
||||||
|
*
|
||||||
|
* The (cf. js_no_entities) method should be used to escape a string
|
||||||
|
* that is ultimately not going to end up as text in an HTML document.
|
||||||
|
*
|
||||||
|
* @param string $value the value to escape
|
||||||
|
* @return string the escaped value
|
||||||
|
*/
|
||||||
|
function ($value) { return str_replace(array("\\" , "\n" , "\r" , "\"" , "'" ), array("\\\\", "\\n" , "\\r", "\\\"", "\\'"), (is_string($value) ? htmlentities($value, ENT_QUOTES, Escaper::getCharset()) : $value)); },
|
||||||
|
|
||||||
|
'js_no_entities' =>
|
||||||
|
/**
|
||||||
|
* A function the c-escapes a string, making it suitable to be placed in a
|
||||||
|
* JavaScript string.
|
||||||
|
*
|
||||||
|
* @param string $value the value to escape
|
||||||
|
* @return string the escaped value
|
||||||
|
*/
|
||||||
|
function ($value) { return str_replace(array("\\" , "\n" , "\r" , "\"" , "'" ), array("\\\\", "\\n" , "\\r", "\\\"", "\\'"), $value); },
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,17 +41,17 @@ abstract class GetterDecorator extends Escaper
|
|||||||
* {@link getRaw()} method, escaped and the result returned.
|
* {@link getRaw()} method, escaped and the result returned.
|
||||||
*
|
*
|
||||||
* @param string $key The key to retieve
|
* @param string $key The key to retieve
|
||||||
* @param string $escapingMethod The escaping method (a PHP function) to use
|
* @param string $escaper The escaping method (a PHP function) to use
|
||||||
*
|
*
|
||||||
* @return mixed The escaped value
|
* @return mixed The escaped value
|
||||||
*/
|
*/
|
||||||
public function get($key, $escapingMethod = null)
|
public function get($key, $escaper = null)
|
||||||
{
|
{
|
||||||
if (!$escapingMethod)
|
if (!$escaper)
|
||||||
{
|
{
|
||||||
$escapingMethod = $this->escapingMethod;
|
$escaper = $this->escaper;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Escaper::escape($escapingMethod, $this->getRaw($key));
|
return Escaper::escape($escaper, $this->getRaw($key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,15 +35,15 @@ class IteratorDecorator extends ObjectDecorator implements \Iterator, \Countable
|
|||||||
/**
|
/**
|
||||||
* Constructs a new escaping iteratoror using the escaping method and value supplied.
|
* Constructs a new escaping iteratoror using the escaping method and value supplied.
|
||||||
*
|
*
|
||||||
* @param string $escapingMethod The escaping method to use
|
* @param string $escaper The escaping method to use
|
||||||
* @param \Traversable $value The iterator to escape
|
* @param \Traversable $value The iterator to escape
|
||||||
*/
|
*/
|
||||||
public function __construct($escapingMethod, \Traversable $value)
|
public function __construct($escaper, \Traversable $value)
|
||||||
{
|
{
|
||||||
// Set the original value for __call(). Set our own iterator because passing
|
// Set the original value for __call(). Set our own iterator because passing
|
||||||
// it to IteratorIterator will lose any other method calls.
|
// it to IteratorIterator will lose any other method calls.
|
||||||
|
|
||||||
parent::__construct($escapingMethod, $value);
|
parent::__construct($escaper, $value);
|
||||||
|
|
||||||
$this->iterator = new \IteratorIterator($value);
|
$this->iterator = new \IteratorIterator($value);
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ class IteratorDecorator extends ObjectDecorator implements \Iterator, \Countable
|
|||||||
*/
|
*/
|
||||||
public function current()
|
public function current()
|
||||||
{
|
{
|
||||||
return Escaper::escape($this->escapingMethod, $this->iterator->current());
|
return Escaper::escape($this->escaper, $this->iterator->current());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,7 +118,7 @@ class IteratorDecorator extends ObjectDecorator implements \Iterator, \Countable
|
|||||||
*/
|
*/
|
||||||
public function offsetGet($offset)
|
public function offsetGet($offset)
|
||||||
{
|
{
|
||||||
return Escaper::escape($this->escapingMethod, $this->value[$offset]);
|
return Escaper::escape($this->escaper, $this->value[$offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,15 +30,14 @@ class ObjectDecorator extends GetterDecorator
|
|||||||
* The calling of the method is changed slightly to accommodate passing a
|
* The calling of the method is changed slightly to accommodate passing a
|
||||||
* specific escaping strategy. An additional parameter is appended to the
|
* specific escaping strategy. An additional parameter is appended to the
|
||||||
* argument list which is the escaping strategy. The decorator will remove
|
* argument list which is the escaping strategy. The decorator will remove
|
||||||
* and use this parameter as the escaping strategy if it begins with 'esc_'
|
* and use this parameter as the escaping strategy if it begins with 'esc_'.
|
||||||
* (the prefix all escaping helper functions have).
|
|
||||||
*
|
*
|
||||||
* For example if an object, $o, implements methods a() and b($arg):
|
* For example if an object, $o, implements methods a() and b($arg):
|
||||||
*
|
*
|
||||||
* $o->a() // Escapes the return value of a()
|
* $o->a() // Escapes the return value of a()
|
||||||
* $o->a(ESC_RAW) // Uses the escaping method ESC_RAW with a()
|
* $o->a('esc_raw') // Uses the escaping strategy 'raw' with a()
|
||||||
* $o->b('a') // Escapes the return value of b('a')
|
* $o->b('a') // Escapes the return value of b('a')
|
||||||
* $o->b('a', ESC_RAW); // Uses the escaping method ESC_RAW with b('a')
|
* $o->b('a', 'esc_raw'); // Uses the escaping strategy 'raw' with b('a')
|
||||||
*
|
*
|
||||||
* @param string $method The method on the object to be called
|
* @param string $method The method on the object to be called
|
||||||
* @param array $args An array of arguments to be passed to the method
|
* @param array $args An array of arguments to be passed to the method
|
||||||
@ -49,24 +48,26 @@ class ObjectDecorator extends GetterDecorator
|
|||||||
{
|
{
|
||||||
if (count($args) > 0)
|
if (count($args) > 0)
|
||||||
{
|
{
|
||||||
$escapingMethod = $args[count($args) - 1];
|
$escaper = $args[count($args) - 1];
|
||||||
if (is_string($escapingMethod) && substr($escapingMethod, 0, 4) === 'esc_')
|
if (is_string($escaper) && 'esc_' === substr($escaper, 0, 4))
|
||||||
{
|
{
|
||||||
|
$escaper = substr($escaper, 4);
|
||||||
|
|
||||||
array_pop($args);
|
array_pop($args);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$escapingMethod = $this->escapingMethod;
|
$escaper = $this->escaper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$escapingMethod = $this->escapingMethod;
|
$escaper = $this->escaper;
|
||||||
}
|
}
|
||||||
|
|
||||||
$value = call_user_func_array(array($this->value, $method), $args);
|
$value = call_user_func_array(array($this->value, $method), $args);
|
||||||
|
|
||||||
return Escaper::escape($escapingMethod, $value);
|
return Escaper::escape($escaper, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,6 +99,6 @@ class ObjectDecorator extends GetterDecorator
|
|||||||
*/
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return $this->escape($this->escapingMethod, $this->value->__toString());
|
return $this->escape($this->escaper, $this->value->__toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,7 @@ namespace Symfony\Components\OutputEscaper;
|
|||||||
*/
|
*/
|
||||||
class Safe extends \ArrayIterator
|
class Safe extends \ArrayIterator
|
||||||
{
|
{
|
||||||
protected
|
protected $value;
|
||||||
$value = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
|
@ -1,111 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of the symfony package.
|
|
||||||
*
|
|
||||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The functions are primarily used by the output escaping component.
|
|
||||||
*
|
|
||||||
* Each function specifies a way for applying a transformation to a string
|
|
||||||
* passed to it. The purpose is for the string to be "escaped" so it is
|
|
||||||
* suitable for the format it is being displayed in.
|
|
||||||
*
|
|
||||||
* For example, the string: "It's required that you enter a username & password.\n"
|
|
||||||
* If this were to be displayed as HTML it would be sensible to turn the
|
|
||||||
* ampersand into '&' and the apostrophe into '&aps;'. However if it were
|
|
||||||
* going to be used as a string in JavaScript to be displayed in an alert box
|
|
||||||
* it would be right to leave the string as-is, but c-escape the apostrophe and
|
|
||||||
* the new line.
|
|
||||||
*
|
|
||||||
* For each function there is a define to avoid problems with strings being
|
|
||||||
* incorrectly specified.
|
|
||||||
*
|
|
||||||
* @package symfony
|
|
||||||
* @subpackage helper
|
|
||||||
* @author Mike Squire <mike@somosis.co.uk>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs the PHP function htmlentities on the value passed.
|
|
||||||
*
|
|
||||||
* @param string $value the value to escape
|
|
||||||
* @return string the escaped value
|
|
||||||
*/
|
|
||||||
function esc_entities($value)
|
|
||||||
{
|
|
||||||
// Numbers and boolean values get turned into strings which can cause problems
|
|
||||||
// with type comparisons (e.g. === or is_int() etc).
|
|
||||||
return is_string($value) ? htmlentities($value, ENT_QUOTES, Symfony\Components\OutputEscaper\Escaper::getCharset()) : $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
define('ESC_ENTITIES', 'esc_entities');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs the PHP function htmlspecialchars on the value passed.
|
|
||||||
*
|
|
||||||
* @param string $value the value to escape
|
|
||||||
* @return string the escaped value
|
|
||||||
*/
|
|
||||||
function esc_specialchars($value)
|
|
||||||
{
|
|
||||||
// Numbers and boolean values get turned into strings which can cause problems
|
|
||||||
// with type comparisons (e.g. === or is_int() etc).
|
|
||||||
return is_string($value) ? htmlspecialchars($value, ENT_QUOTES, Symfony\Components\OutputEscaper\Escaper::getCharset()) : $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
define('ESC_SPECIALCHARS', 'esc_specialchars');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An identity function that merely returns that which it is given, the purpose
|
|
||||||
* being to be able to specify that the value is not to be escaped in any way.
|
|
||||||
*
|
|
||||||
* @param string $value the value to escape
|
|
||||||
* @return string the escaped value
|
|
||||||
*/
|
|
||||||
function esc_raw($value)
|
|
||||||
{
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
define('ESC_RAW', 'esc_raw');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A function that c-escapes a string after applying {@link esc_entities()}. The
|
|
||||||
* assumption is that the value will be used to generate dynamic HTML in some
|
|
||||||
* way and the safest way to prevent mishap is to assume the value should have
|
|
||||||
* HTML entities set properly.
|
|
||||||
*
|
|
||||||
* The {@link esc_js_no_entities()} method should be used to escape a string
|
|
||||||
* that is ultimately not going to end up as text in an HTML document.
|
|
||||||
*
|
|
||||||
* @param string $value the value to escape
|
|
||||||
* @return string the escaped value
|
|
||||||
*/
|
|
||||||
function esc_js($value)
|
|
||||||
{
|
|
||||||
return esc_js_no_entities(esc_entities($value));
|
|
||||||
}
|
|
||||||
|
|
||||||
define('ESC_JS', 'esc_js');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A function the c-escapes a string, making it suitable to be placed in a
|
|
||||||
* JavaScript string.
|
|
||||||
*
|
|
||||||
* @param string $value the value to escape
|
|
||||||
* @return string the escaped value
|
|
||||||
*/
|
|
||||||
function esc_js_no_entities($value)
|
|
||||||
{
|
|
||||||
return str_replace(array("\\" , "\n" , "\r" , "\"" , "'" ),
|
|
||||||
array("\\\\", "\\n" , "\\r", "\\\"", "\\'"),
|
|
||||||
$value);
|
|
||||||
}
|
|
||||||
|
|
||||||
define('ESC_JS_NO_ENTITIES', 'esc_js_no_entities');
|
|
@ -16,7 +16,7 @@ use Symfony\Components\OutputEscaper\Escaper;
|
|||||||
$t = new LimeTest(11);
|
$t = new LimeTest(11);
|
||||||
|
|
||||||
$a = array('<strong>escaped!</strong>', 1, null, array(2, '<strong>escaped!</strong>'));
|
$a = array('<strong>escaped!</strong>', 1, null, array(2, '<strong>escaped!</strong>'));
|
||||||
$escaped = Escaper::escape('esc_entities', $a);
|
$escaped = Escaper::escape('entities', $a);
|
||||||
|
|
||||||
// ->getRaw()
|
// ->getRaw()
|
||||||
$t->diag('->getRaw()');
|
$t->diag('->getRaw()');
|
||||||
|
@ -43,23 +43,23 @@ class OutputEscaperTestClassChild extends OutputEscaperTestClass
|
|||||||
// ::escape()
|
// ::escape()
|
||||||
$t->diag('::escape()');
|
$t->diag('::escape()');
|
||||||
$t->diag('::escape() does not escape special values');
|
$t->diag('::escape() does not escape special values');
|
||||||
$t->ok(Escaper::escape('esc_entities', null) === null, '::escape() returns null if the value to escape is null');
|
$t->ok(Escaper::escape('entities', null) === null, '::escape() returns null if the value to escape is null');
|
||||||
$t->ok(Escaper::escape('esc_entities', false) === false, '::escape() returns false if the value to escape is false');
|
$t->ok(Escaper::escape('entities', false) === false, '::escape() returns false if the value to escape is false');
|
||||||
$t->ok(Escaper::escape('esc_entities', true) === true, '::escape() returns true if the value to escape is true');
|
$t->ok(Escaper::escape('entities', true) === true, '::escape() returns true if the value to escape is true');
|
||||||
|
|
||||||
$t->diag('::escape() does not escape a value when escaping method is ESC_RAW');
|
$t->diag('::escape() does not escape a value when escaping method is RAW');
|
||||||
$t->is(Escaper::escape('esc_raw', '<strong>escaped!</strong>'), '<strong>escaped!</strong>', '::escape() takes an escaping strategy function name as its first argument');
|
$t->is(Escaper::escape('raw', '<strong>escaped!</strong>'), '<strong>escaped!</strong>', '::escape() takes an escaping strategy function name as its first argument');
|
||||||
|
|
||||||
$t->diag('::escape() escapes strings');
|
$t->diag('::escape() escapes strings');
|
||||||
$t->is(Escaper::escape('esc_entities', '<strong>escaped!</strong>'), '<strong>escaped!</strong>', '::escape() returns an escaped string if the value to escape is a string');
|
$t->is(Escaper::escape('entities', '<strong>escaped!</strong>'), '<strong>escaped!</strong>', '::escape() returns an escaped string if the value to escape is a string');
|
||||||
$t->is(Escaper::escape('esc_entities', '<strong>échappé</strong>'), '<strong>échappé</strong>', '::escape() returns an escaped string if the value to escape is a string');
|
$t->is(Escaper::escape('entities', '<strong>échappé</strong>'), '<strong>échappé</strong>', '::escape() returns an escaped string if the value to escape is a string');
|
||||||
|
|
||||||
$t->diag('::escape() escapes arrays');
|
$t->diag('::escape() escapes arrays');
|
||||||
$input = array(
|
$input = array(
|
||||||
'foo' => '<strong>escaped!</strong>',
|
'foo' => '<strong>escaped!</strong>',
|
||||||
'bar' => array('foo' => '<strong>escaped!</strong>'),
|
'bar' => array('foo' => '<strong>escaped!</strong>'),
|
||||||
);
|
);
|
||||||
$output = Escaper::escape('esc_entities', $input);
|
$output = Escaper::escape('entities', $input);
|
||||||
$t->ok($output instanceof ArrayDecorator, '::escape() returns a ArrayDecorator object if the value to escape is an array');
|
$t->ok($output instanceof ArrayDecorator, '::escape() returns a ArrayDecorator object if the value to escape is an array');
|
||||||
$t->is($output['foo'], '<strong>escaped!</strong>', '::escape() escapes all elements of the original array');
|
$t->is($output['foo'], '<strong>escaped!</strong>', '::escape() escapes all elements of the original array');
|
||||||
$t->is($output['bar']['foo'], '<strong>escaped!</strong>', '::escape() is recursive');
|
$t->is($output['bar']['foo'], '<strong>escaped!</strong>', '::escape() is recursive');
|
||||||
@ -67,28 +67,28 @@ $t->is($output->getRawValue(), $input, '->getRawValue() returns the unescaped va
|
|||||||
|
|
||||||
$t->diag('::escape() escapes objects');
|
$t->diag('::escape() escapes objects');
|
||||||
$input = new OutputEscaperTestClass();
|
$input = new OutputEscaperTestClass();
|
||||||
$output = Escaper::escape('esc_entities', $input);
|
$output = Escaper::escape('entities', $input);
|
||||||
$t->ok($output instanceof ObjectDecorator, '::escape() returns a ObjectDecorator object if the value to escape is an object');
|
$t->ok($output instanceof ObjectDecorator, '::escape() returns a ObjectDecorator object if the value to escape is an object');
|
||||||
$t->is($output->getTitle(), '<strong>escaped!</strong>', '::escape() escapes all methods of the original object');
|
$t->is($output->getTitle(), '<strong>escaped!</strong>', '::escape() escapes all methods of the original object');
|
||||||
$t->is($output->title, '<strong>escaped!</strong>', '::escape() escapes all properties of the original object');
|
$t->is($output->title, '<strong>escaped!</strong>', '::escape() escapes all properties of the original object');
|
||||||
$t->is($output->getTitleTitle(), '<strong>escaped!</strong>', '::escape() is recursive');
|
$t->is($output->getTitleTitle(), '<strong>escaped!</strong>', '::escape() is recursive');
|
||||||
$t->is($output->getRawValue(), $input, '->getRawValue() returns the unescaped value');
|
$t->is($output->getRawValue(), $input, '->getRawValue() returns the unescaped value');
|
||||||
|
|
||||||
$t->is(Escaper::escape('esc_entities', $output)->getTitle(), '<strong>escaped!</strong>', '::escape() does not double escape an object');
|
$t->is(Escaper::escape('entities', $output)->getTitle(), '<strong>escaped!</strong>', '::escape() does not double escape an object');
|
||||||
$t->ok(Escaper::escape('esc_entities', new \DirectoryIterator('.')) instanceof IteratorDecorator, '::escape() returns a IteratorDecorator object if the value to escape is an object that implements the ArrayAccess interface');
|
$t->ok(Escaper::escape('entities', new \DirectoryIterator('.')) instanceof IteratorDecorator, '::escape() returns a IteratorDecorator object if the value to escape is an object that implements the ArrayAccess interface');
|
||||||
|
|
||||||
$t->diag('::escape() does not escape object marked as being safe');
|
$t->diag('::escape() does not escape object marked as being safe');
|
||||||
$t->ok(Escaper::escape('esc_entities', new Safe(new OutputEscaperTestClass())) instanceof OutputEscaperTestClass, '::escape() returns the original value if it is marked as being safe');
|
$t->ok(Escaper::escape('entities', new Safe(new OutputEscaperTestClass())) instanceof OutputEscaperTestClass, '::escape() returns the original value if it is marked as being safe');
|
||||||
|
|
||||||
Escaper::markClassAsSafe('OutputEscaperTestClass');
|
Escaper::markClassAsSafe('OutputEscaperTestClass');
|
||||||
$t->ok(Escaper::escape('esc_entities', new OutputEscaperTestClass()) instanceof OutputEscaperTestClass, '::escape() returns the original value if the object class is marked as being safe');
|
$t->ok(Escaper::escape('entities', new OutputEscaperTestClass()) instanceof OutputEscaperTestClass, '::escape() returns the original value if the object class is marked as being safe');
|
||||||
$t->ok(Escaper::escape('esc_entities', new OutputEscaperTestClassChild()) instanceof OutputEscaperTestClassChild, '::escape() returns the original value if one of the object parent class is marked as being safe');
|
$t->ok(Escaper::escape('entities', new OutputEscaperTestClassChild()) instanceof OutputEscaperTestClassChild, '::escape() returns the original value if one of the object parent class is marked as being safe');
|
||||||
|
|
||||||
$t->diag('::escape() cannot escape resources');
|
$t->diag('::escape() cannot escape resources');
|
||||||
$fh = fopen(__FILE__, 'r');
|
$fh = fopen(__FILE__, 'r');
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Escaper::escape('esc_entities', $fh);
|
Escaper::escape('entities', $fh);
|
||||||
$t->fail('::escape() throws an InvalidArgumentException if the value cannot be escaped');
|
$t->fail('::escape() throws an InvalidArgumentException if the value cannot be escaped');
|
||||||
}
|
}
|
||||||
catch (InvalidArgumentException $e)
|
catch (InvalidArgumentException $e)
|
||||||
@ -108,7 +108,7 @@ $t->is(Escaper::unescape('<strong>escaped!</strong>'), '<strong>esca
|
|||||||
$t->is(Escaper::unescape('<strong>échappé</strong>'), '<strong>échappé</strong>', '::unescape() returns an unescaped string if the value to unescape is a string');
|
$t->is(Escaper::unescape('<strong>échappé</strong>'), '<strong>échappé</strong>', '::unescape() returns an unescaped string if the value to unescape is a string');
|
||||||
|
|
||||||
$t->diag('::unescape() unescapes arrays');
|
$t->diag('::unescape() unescapes arrays');
|
||||||
$input = Escaper::escape('esc_entities', array(
|
$input = Escaper::escape('entities', array(
|
||||||
'foo' => '<strong>escaped!</strong>',
|
'foo' => '<strong>escaped!</strong>',
|
||||||
'bar' => array('foo' => '<strong>escaped!</strong>'),
|
'bar' => array('foo' => '<strong>escaped!</strong>'),
|
||||||
));
|
));
|
||||||
@ -119,21 +119,21 @@ $t->is($output['bar']['foo'], '<strong>escaped!</strong>', '::unescape() is recu
|
|||||||
|
|
||||||
$t->diag('::unescape() unescapes objects');
|
$t->diag('::unescape() unescapes objects');
|
||||||
$object = new OutputEscaperTestClass();
|
$object = new OutputEscaperTestClass();
|
||||||
$input = Escaper::escape('esc_entities', $object);
|
$input = Escaper::escape('entities', $object);
|
||||||
$output = Escaper::unescape($input);
|
$output = Escaper::unescape($input);
|
||||||
$t->ok($output instanceof OutputEscaperTestClass, '::unescape() returns the original object when a ObjectDecorator object is passed');
|
$t->ok($output instanceof OutputEscaperTestClass, '::unescape() returns the original object when a ObjectDecorator object is passed');
|
||||||
$t->is($output->getTitle(), '<strong>escaped!</strong>', '::unescape() unescapes all methods of the original object');
|
$t->is($output->getTitle(), '<strong>escaped!</strong>', '::unescape() unescapes all methods of the original object');
|
||||||
$t->is($output->title, '<strong>escaped!</strong>', '::unescape() unescapes all properties of the original object');
|
$t->is($output->title, '<strong>escaped!</strong>', '::unescape() unescapes all properties of the original object');
|
||||||
$t->is($output->getTitleTitle(), '<strong>escaped!</strong>', '::unescape() is recursive');
|
$t->is($output->getTitleTitle(), '<strong>escaped!</strong>', '::unescape() is recursive');
|
||||||
|
|
||||||
$t->ok(IteratorDecorator::unescape(Escaper::escape('esc_entities', new DirectoryIterator('.'))) instanceof DirectoryIterator, '::unescape() unescapes IteratorDecorator objects');
|
$t->ok(IteratorDecorator::unescape(Escaper::escape('entities', new DirectoryIterator('.'))) instanceof DirectoryIterator, '::unescape() unescapes IteratorDecorator objects');
|
||||||
|
|
||||||
$t->diag('::unescape() does not unescape object marked as being safe');
|
$t->diag('::unescape() does not unescape object marked as being safe');
|
||||||
$t->ok(Escaper::unescape(Escaper::escape('esc_entities', new Safe(new OutputEscaperTestClass()))) instanceof OutputEscaperTestClass, '::unescape() returns the original value if it is marked as being safe');
|
$t->ok(Escaper::unescape(Escaper::escape('entities', new Safe(new OutputEscaperTestClass()))) instanceof OutputEscaperTestClass, '::unescape() returns the original value if it is marked as being safe');
|
||||||
|
|
||||||
Escaper::markClassAsSafe('OutputEscaperTestClass');
|
Escaper::markClassAsSafe('OutputEscaperTestClass');
|
||||||
$t->ok(Escaper::unescape(Escaper::escape('esc_entities', new OutputEscaperTestClass())) instanceof OutputEscaperTestClass, '::unescape() returns the original value if the object class is marked as being safe');
|
$t->ok(Escaper::unescape(Escaper::escape('entities', new OutputEscaperTestClass())) instanceof OutputEscaperTestClass, '::unescape() returns the original value if the object class is marked as being safe');
|
||||||
$t->ok(Escaper::unescape(Escaper::escape('esc_entities', new OutputEscaperTestClassChild())) instanceof OutputEscaperTestClassChild, '::unescape() returns the original value if one of the object parent class is marked as being safe');
|
$t->ok(Escaper::unescape(Escaper::escape('entities', new OutputEscaperTestClassChild())) instanceof OutputEscaperTestClassChild, '::unescape() returns the original value if one of the object parent class is marked as being safe');
|
||||||
|
|
||||||
$t->diag('::unescape() do nothing to resources');
|
$t->diag('::unescape() do nothing to resources');
|
||||||
$fh = fopen(__FILE__, 'r');
|
$fh = fopen(__FILE__, 'r');
|
||||||
@ -143,8 +143,8 @@ $t->diag('::unescape() unescapes mixed arrays');
|
|||||||
$object = new OutputEscaperTestClass();
|
$object = new OutputEscaperTestClass();
|
||||||
$input = array(
|
$input = array(
|
||||||
'foo' => 'bar',
|
'foo' => 'bar',
|
||||||
'bar' => Escaper::escape('esc_entities', '<strong>bar</strong>'),
|
'bar' => Escaper::escape('entities', '<strong>bar</strong>'),
|
||||||
'foobar' => Escaper::escape('esc_entities', $object),
|
'foobar' => Escaper::escape('entities', $object),
|
||||||
);
|
);
|
||||||
$output = array(
|
$output = array(
|
||||||
'foo' => 'bar',
|
'foo' => 'bar',
|
||||||
|
@ -34,7 +34,7 @@ class OutputEscaperTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
$object = new OutputEscaperTest();
|
$object = new OutputEscaperTest();
|
||||||
$escaped = Escaper::escape('esc_entities', $object);
|
$escaped = Escaper::escape('entities', $object);
|
||||||
|
|
||||||
$t->is($escaped->getTitle(), '<strong>escaped!</strong>', 'The escaped object behaves like the real object');
|
$t->is($escaped->getTitle(), '<strong>escaped!</strong>', 'The escaped object behaves like the real object');
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user