protected function initializeBuiltInEscapers() { $that = $this; $this->escapers = ['html' => function ($value) use($that) { // 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 | ENT_SUBSTITUTE, $that->getCharset(), false) : $value; }, 'js' => function ($value) use($that) { if ('UTF-8' != $that->getCharset()) { $value = $that->convertEncoding($value, 'UTF-8', $that->getCharset()); } $callback = function ($matches) use($that) { $char = $matches[0]; // \xHH if (!isset($char[1])) { return '\\x' . substr('00' . bin2hex($char), -2); } // \uHHHH $char = $that->convertEncoding($char, 'UTF-16BE', 'UTF-8'); return '\\u' . substr('0000' . bin2hex($char), -4); }; if (null === ($value = preg_replace_callback('#[^\\p{L}\\p{N} ]#u', $callback, $value))) { throw new \InvalidArgumentException('The string to escape is not a valid UTF-8 string.'); } if ('UTF-8' != $that->getCharset()) { $value = $that->convertEncoding($value, $that->getCharset(), 'UTF-8'); } return $value; }]; self::$cached = []; }
/** * Returns the escaped value associated with the key supplied. * * Typically (using this implementation) the raw value is obtained using the * {@link getRaw()} method, escaped and the result returned. * * @param string $key The key to retieve * @param string $escapingMethod The escaping method (a PHP function) to use * * @return mixed The escaped value */ public function get($key, $escapingMethod = null) { if (!$escapingMethod) { $escapingMethod = $this->escapingMethod; } return Escaper::escape($escapingMethod, $this->getRaw($key)); }
/** * Magic PHP method that intercepts method calls, calls them on the objects * that is being escaped and escapes the result. * * The calling of the method is changed slightly to accommodate passing a * specific escaping strategy. An additional parameter is appended to the * argument list which is the escaping strategy. The decorator will remove * and use this parameter as the escaping strategy if it begins with 'esc_'. * * For example if an object, $o, implements methods a() and b($arg): * * $o->a() // Escapes the return value of 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', 'esc_raw'); // Uses the escaping strategy 'raw' with b('a') * * @param string $method The method on the object to be called * @param array $args An array of arguments to be passed to the method * * @return mixed The escaped value returned by the method */ public function __call($method, $args) { if (count($args) > 0) { $escaper = $args[count($args) - 1]; if (is_string($escaper) && 'esc_' === substr($escaper, 0, 4)) { $escaper = substr($escaper, 4); array_pop($args); } else { $escaper = $this->escaper; } } else { $escaper = $this->escaper; } $value = call_user_func_array(array($this->value, $method), $args); return Escaper::escape($escaper, $value); }
public function test_j() { $chars = array('<' => '\\x3C', '>' => '\\x3E', '\'' => '\\x27', '"' => '\\x22', '&' => '\\x26', 'Ä€' => '\\u0100', ',' => ',', '.' => '.', '_' => '_', 'a' => 'a', 'A' => 'A', 'z' => 'z', 'Z' => 'Z', '0' => '0', '9' => '9', "\r" => '\\x0D', "\n" => '\\x0A', "\t" => '\\x09', "" => '\\x00', ' ' => '\\x20'); foreach ($chars as $key => $val) { $this->assertEquals($val, Escaper::j($key), 'Failed to escape: ' . $key); } }
/** * Returns the escaped value associated with the key supplied. * * Typically (using this implementation) the raw value is obtained using the * {@link getRaw()} method, escaped and the result returned. * * @param string $key The key to retrieve * @param string $escaper The escaping method (a PHP function) to use * * @return mixed The escaped value */ public function get($key, $escaper = null) { if (!$escaper) { $escaper = $this->escaper; } return Escaper::escape($escaper, $this->getRaw($key)); }
/** * Magic PHP method that intercepts method calls, calls them on the objects * that is being escaped and escapes the result. * * The calling of the method is changed slightly to accommodate passing a * specific escaping strategy. An additional parameter is appended to the * argument list which is the escaping strategy. The decorator will remove * 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): * * $o->a() // Escapes the return value of a() * $o->a(ESC_RAW) // Uses the escaping method ESC_RAW with 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') * * @param string $method The method on the object to be called * @param array $args An array of arguments to be passed to the method * * @return mixed The escaped value returned by the method */ public function __call($method, $args) { if (count($args) > 0) { $escapingMethod = $args[count($args) - 1]; if (is_string($escapingMethod) && substr($escapingMethod, 0, 4) === 'esc_') { array_pop($args); } else { $escapingMethod = $this->escapingMethod; } } else { $escapingMethod = $this->escapingMethod; } $value = call_user_func_array(array($this->value, $method), $args); return Escaper::escape($escapingMethod, $value); }
/** * Executes command from GET-filter. * Command must be represented as method of this class named as "command".$commandName * This method MUST return String WHERE-clause for passed arguments * @param $command * @param $field * @param $arguments * @return string * @throws \Exception */ protected function exec($command, $field, $arguments) { $method = 'command' . ucfirst($command); if (method_exists($this, $method)) { if (is_array($field)) { $field = implode(self::CMD_SEPARATOR, $field); } $field = $this->escaper->field($field); if (is_array($arguments)) { for ($i = 0; $i < count($arguments); $i++) { $arguments[$i] = $this->escaper->value($arguments[$i]); } } else { $arguments = $this->escaper->value($arguments); } return '(' . $this->{$method}($this->table . '.' . $field, $arguments) . ')'; } else { // TODO: throw valid Exception throw new \Exception("Filter " . $command . " not supported"); } }
/** * Dumps a given PHP variable to a YAML string. * * @param mixed $value The PHP variable to convert * * @return string The YAML string representing the PHP array * * @throws Exception When trying to dump PHP resource */ public static function dump($value) { $trueValues = '1.1' == Yaml::getSpecVersion() ? array('true', 'on', '+', 'yes', 'y') : array('true'); $falseValues = '1.1' == Yaml::getSpecVersion() ? array('false', 'off', '-', 'no', 'n') : array('false'); switch (true) { case is_resource($value): throw new Exception('Unable to dump PHP resources in a YAML file.'); case is_object($value): return '!!php/object:' . serialize($value); case is_array($value): return self::dumpArray($value); case null === $value: return 'null'; case true === $value: return 'true'; case false === $value: return 'false'; case ctype_digit($value): return is_string($value) ? "'{$value}'" : (int) $value; case is_numeric($value): return is_infinite($value) ? str_ireplace('INF', '.Inf', strval($value)) : (is_string($value) ? "'{$value}'" : $value); case Escaper::requiresDoubleQuoting($value): return Escaper::escapeWithDoubleQuotes($value); case Escaper::requiresSingleQuoting($value): return Escaper::escapeWithSingleQuotes($value); case '' == $value: return "''"; case preg_match(self::getTimestampRegex(), $value): return "'{$value}'"; case in_array(strtolower($value), $trueValues): return "'{$value}'"; case in_array(strtolower($value), $falseValues): return "'{$value}'"; case in_array(strtolower($value), array('null', '~')): return "'{$value}'"; default: return $value; } }
/** * 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' => 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' => 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' => function ($value) { return $value; }, 'js' => function ($value) { return str_replace(array("\\", "\n", "\r", "\"", "'"), array("\\\\", "\\n", "\\r", "\\\"", "\\'"), is_string($value) ? htmlentities($value, ENT_QUOTES, Escaper::getCharset()) : $value); }, 'js_no_entities' => function ($value) { return str_replace(array("\\", "\n", "\r", "\"", "'"), array("\\\\", "\\n", "\\r", "\\\"", "\\'"), $value); }); }
/** * Register autoescaping on template variables. * * @param \greebo\essence\Event $event */ static function register(\greebo\essence\Event $event) { $event->connect('template.slots', function ($template, $slots) { foreach ($slots as $name => $slot) { $slots[$name] = Escaper::escape($slot, $template->escaper()); } return $slots; }); }
/** * Returns the element associated with the offset supplied (as required by the ArrayAccess interface). * * @param string $offset The offset of the value to get * * @return mixed The escaped value */ public function offsetGet($offset) { return Escaper::escape($this->escaper, $this->value[$offset]); }
/** * Escapes a key from the array using the specified escaper. * * @param string $key The array key * @param string $escaper The escaping strategy prefixed with esc_ (see __call()) */ public function getEscapedKey($key, $escaper) { return Escaper::escape(substr($escaper, 4), $this->value[$key]); }
/** * Object method call. * * Return the escaped value of the property. * * @param string $name * @return mixed */ function __call($method, $args) { return Escaper::escape(call_user_func_array(array($this->value, $method), $args), $this->escaper); }
/** * Dumps a given PHP variable to a YAML string * * @param mixed $value The PHP variable to convert * * @return string The YAML string representing the PHP array */ public static function dumpInline($value) { if (is_resource($value)) { return "null"; } elseif (is_object($value)) { return "!!php/object:" . serialize($value); } elseif (is_array($value)) { return self::dumpInlineArray($value); } elseif ($value === null) { return "null"; } elseif ($value === true) { return "true"; } elseif ($value === false) { return "false"; } elseif (ctype_digit($value)) { return is_string($value) ? "\"{$value}\"" : (int) $value; } elseif (is_numeric($value)) { $locale = setlocale(LC_NUMERIC, 0); if ($locale !== false) { setlocale(LC_NUMERIC, "C"); } if (is_float($value)) { $repr = (string) $value; if (is_infinite($value)) { $repr = str_ireplace("INF", ".Inf", $repr); } elseif (floor($value) == $value && $repr == $value) { // Preserve float data type since storing a whole number will result in integer value. $repr = "!!float {$repr}"; } } elseif (is_string($value)) { $repr = "'{$value}'"; } else { $repr = (string) $value; } if ($locale !== false) { setlocale(LC_NUMERIC, $locale); } return $repr; } elseif ($value === "") { return "''"; } elseif (strstr($value, "\n") !== false) { return "|\n " . preg_replace("/\\n/", "\n ", $value); } elseif (Escaper::requiresDoubleQuoting($value)) { return Escaper::escapeWithDoubleQuotes($value); } elseif (Escaper::requiresSingleQuoting($value) || preg_match(Inline::getHexRegex(), $value) || preg_match(Inline::getTimestampRegex(), $value)) { return Escaper::escapeWithSingleQuotes($value); } else { return $value; } }
/** * 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); }, ); }
/** * 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' => 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(), false) : $value; }, 'entities' => 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(), false) : $value; }, 'raw' => function ($value) { return $value; }, 'js' => function ($value) { if ('UTF-8' != Escaper::getCharset()) { $string = Escaper::convertEncoding($string, 'UTF-8', Escaper::getCharset()); } $callback = function ($matches) { $char = $matches[0]; // \xHH if (!isset($char[1])) { return '\\x' . substr('00' . bin2hex($char), -2); } // \uHHHH $char = Escaper::convertEncoding($char, 'UTF-16BE', 'UTF-8'); return '\\u' . substr('0000' . bin2hex($char), -4); }; if (null === ($string = preg_replace_callback('#[^\\p{L}\\p{N} ]#u', $callback, $string))) { throw new InvalidArgumentException('The string to escape is not a valid UTF-8 string.'); } if ('UTF-8' != Escaper::getCharset()) { $string = Escaper::convertEncoding($string, Escaper::getCharset(), 'UTF-8'); } return $string; }); }
public function __construct(string $text, Escaper $escaper) { $this->text = $escaper->escapeHtml($text); }
/** * Escapes and gets the current element (as required by the Iterator interface). * * @return mixed The escaped value */ public function current() { return Escaper::escape($this->escaper, $this->iterator->current()); }