diff options
| author | Greg Roach <fisharebest@webtrees.net> | 2018-07-27 12:26:34 +0100 |
|---|---|---|
| committer | Greg Roach <fisharebest@webtrees.net> | 2018-07-27 12:26:34 +0100 |
| commit | 5809450f8c7aee50cbf34aa45eb24752d4ec0285 (patch) | |
| tree | 749f9e74e7a3deca749ed0c4d39d81b636710663 /vendor/symfony/expression-language/Node | |
| parent | b646d0aa207ec67f8385350355eef400d32cbaec (diff) | |
| download | webtrees-5809450f8c7aee50cbf34aa45eb24752d4ec0285.tar.gz webtrees-5809450f8c7aee50cbf34aa45eb24752d4ec0285.tar.bz2 webtrees-5809450f8c7aee50cbf34aa45eb24752d4ec0285.zip | |
eval() is evil
Diffstat (limited to 'vendor/symfony/expression-language/Node')
10 files changed, 859 insertions, 0 deletions
diff --git a/vendor/symfony/expression-language/Node/ArgumentsNode.php b/vendor/symfony/expression-language/Node/ArgumentsNode.php new file mode 100644 index 0000000000..1c78d8054b --- /dev/null +++ b/vendor/symfony/expression-language/Node/ArgumentsNode.php @@ -0,0 +1,40 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier <fabien@symfony.com> + * + * @internal + */ +class ArgumentsNode extends ArrayNode +{ + public function compile(Compiler $compiler) + { + $this->compileArguments($compiler, false); + } + + public function toArray() + { + $array = array(); + + foreach ($this->getKeyValuePairs() as $pair) { + $array[] = $pair['value']; + $array[] = ', '; + } + array_pop($array); + + return $array; + } +} diff --git a/vendor/symfony/expression-language/Node/ArrayNode.php b/vendor/symfony/expression-language/Node/ArrayNode.php new file mode 100644 index 0000000000..e1a2f2e904 --- /dev/null +++ b/vendor/symfony/expression-language/Node/ArrayNode.php @@ -0,0 +1,118 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier <fabien@symfony.com> + * + * @internal + */ +class ArrayNode extends Node +{ + protected $index; + + public function __construct() + { + $this->index = -1; + } + + public function addElement(Node $value, Node $key = null) + { + if (null === $key) { + $key = new ConstantNode(++$this->index); + } + + array_push($this->nodes, $key, $value); + } + + /** + * Compiles the node to PHP. + */ + public function compile(Compiler $compiler) + { + $compiler->raw('array('); + $this->compileArguments($compiler); + $compiler->raw(')'); + } + + public function evaluate($functions, $values) + { + $result = array(); + foreach ($this->getKeyValuePairs() as $pair) { + $result[$pair['key']->evaluate($functions, $values)] = $pair['value']->evaluate($functions, $values); + } + + return $result; + } + + public function toArray() + { + $value = array(); + foreach ($this->getKeyValuePairs() as $pair) { + $value[$pair['key']->attributes['value']] = $pair['value']; + } + + $array = array(); + + if ($this->isHash($value)) { + foreach ($value as $k => $v) { + $array[] = ', '; + $array[] = new ConstantNode($k); + $array[] = ': '; + $array[] = $v; + } + $array[0] = '{'; + $array[] = '}'; + } else { + foreach ($value as $v) { + $array[] = ', '; + $array[] = $v; + } + $array[0] = '['; + $array[] = ']'; + } + + return $array; + } + + protected function getKeyValuePairs() + { + $pairs = array(); + foreach (array_chunk($this->nodes, 2) as $pair) { + $pairs[] = array('key' => $pair[0], 'value' => $pair[1]); + } + + return $pairs; + } + + protected function compileArguments(Compiler $compiler, $withKeys = true) + { + $first = true; + foreach ($this->getKeyValuePairs() as $pair) { + if (!$first) { + $compiler->raw(', '); + } + $first = false; + + if ($withKeys) { + $compiler + ->compile($pair['key']) + ->raw(' => ') + ; + } + + $compiler->compile($pair['value']); + } + } +} diff --git a/vendor/symfony/expression-language/Node/BinaryNode.php b/vendor/symfony/expression-language/Node/BinaryNode.php new file mode 100644 index 0000000000..33b4c8f089 --- /dev/null +++ b/vendor/symfony/expression-language/Node/BinaryNode.php @@ -0,0 +1,162 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier <fabien@symfony.com> + * + * @internal + */ +class BinaryNode extends Node +{ + private static $operators = array( + '~' => '.', + 'and' => '&&', + 'or' => '||', + ); + + private static $functions = array( + '**' => 'pow', + '..' => 'range', + 'in' => 'in_array', + 'not in' => '!in_array', + ); + + public function __construct($operator, Node $left, Node $right) + { + parent::__construct( + array('left' => $left, 'right' => $right), + array('operator' => $operator) + ); + } + + public function compile(Compiler $compiler) + { + $operator = $this->attributes['operator']; + + if ('matches' == $operator) { + $compiler + ->raw('preg_match(') + ->compile($this->nodes['right']) + ->raw(', ') + ->compile($this->nodes['left']) + ->raw(')') + ; + + return; + } + + if (isset(self::$functions[$operator])) { + $compiler + ->raw(sprintf('%s(', self::$functions[$operator])) + ->compile($this->nodes['left']) + ->raw(', ') + ->compile($this->nodes['right']) + ->raw(')') + ; + + return; + } + + if (isset(self::$operators[$operator])) { + $operator = self::$operators[$operator]; + } + + $compiler + ->raw('(') + ->compile($this->nodes['left']) + ->raw(' ') + ->raw($operator) + ->raw(' ') + ->compile($this->nodes['right']) + ->raw(')') + ; + } + + public function evaluate($functions, $values) + { + $operator = $this->attributes['operator']; + $left = $this->nodes['left']->evaluate($functions, $values); + + if (isset(self::$functions[$operator])) { + $right = $this->nodes['right']->evaluate($functions, $values); + + if ('not in' === $operator) { + return !in_array($left, $right); + } + $f = self::$functions[$operator]; + + return $f($left, $right); + } + + switch ($operator) { + case 'or': + case '||': + return $left || $this->nodes['right']->evaluate($functions, $values); + case 'and': + case '&&': + return $left && $this->nodes['right']->evaluate($functions, $values); + } + + $right = $this->nodes['right']->evaluate($functions, $values); + + switch ($operator) { + case '|': + return $left | $right; + case '^': + return $left ^ $right; + case '&': + return $left & $right; + case '==': + return $left == $right; + case '===': + return $left === $right; + case '!=': + return $left != $right; + case '!==': + return $left !== $right; + case '<': + return $left < $right; + case '>': + return $left > $right; + case '>=': + return $left >= $right; + case '<=': + return $left <= $right; + case 'not in': + return !in_array($left, $right); + case 'in': + return in_array($left, $right); + case '+': + return $left + $right; + case '-': + return $left - $right; + case '~': + return $left.$right; + case '*': + return $left * $right; + case '/': + return $left / $right; + case '%': + return $left % $right; + case 'matches': + return preg_match($right, $left); + } + } + + public function toArray() + { + return array('(', $this->nodes['left'], ' '.$this->attributes['operator'].' ', $this->nodes['right'], ')'); + } +} diff --git a/vendor/symfony/expression-language/Node/ConditionalNode.php b/vendor/symfony/expression-language/Node/ConditionalNode.php new file mode 100644 index 0000000000..9db0f931aa --- /dev/null +++ b/vendor/symfony/expression-language/Node/ConditionalNode.php @@ -0,0 +1,56 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier <fabien@symfony.com> + * + * @internal + */ +class ConditionalNode extends Node +{ + public function __construct(Node $expr1, Node $expr2, Node $expr3) + { + parent::__construct( + array('expr1' => $expr1, 'expr2' => $expr2, 'expr3' => $expr3) + ); + } + + public function compile(Compiler $compiler) + { + $compiler + ->raw('((') + ->compile($this->nodes['expr1']) + ->raw(') ? (') + ->compile($this->nodes['expr2']) + ->raw(') : (') + ->compile($this->nodes['expr3']) + ->raw('))') + ; + } + + public function evaluate($functions, $values) + { + if ($this->nodes['expr1']->evaluate($functions, $values)) { + return $this->nodes['expr2']->evaluate($functions, $values); + } + + return $this->nodes['expr3']->evaluate($functions, $values); + } + + public function toArray() + { + return array('(', $this->nodes['expr1'], ' ? ', $this->nodes['expr2'], ' : ', $this->nodes['expr3'], ')'); + } +} diff --git a/vendor/symfony/expression-language/Node/ConstantNode.php b/vendor/symfony/expression-language/Node/ConstantNode.php new file mode 100644 index 0000000000..733d481b28 --- /dev/null +++ b/vendor/symfony/expression-language/Node/ConstantNode.php @@ -0,0 +1,81 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier <fabien@symfony.com> + * + * @internal + */ +class ConstantNode extends Node +{ + private $isIdentifier; + + public function __construct($value, $isIdentifier = false) + { + $this->isIdentifier = $isIdentifier; + parent::__construct( + array(), + array('value' => $value) + ); + } + + public function compile(Compiler $compiler) + { + $compiler->repr($this->attributes['value']); + } + + public function evaluate($functions, $values) + { + return $this->attributes['value']; + } + + public function toArray() + { + $array = array(); + $value = $this->attributes['value']; + + if ($this->isIdentifier) { + $array[] = $value; + } elseif (true === $value) { + $array[] = 'true'; + } elseif (false === $value) { + $array[] = 'false'; + } elseif (null === $value) { + $array[] = 'null'; + } elseif (is_numeric($value)) { + $array[] = $value; + } elseif (!is_array($value)) { + $array[] = $this->dumpString($value); + } elseif ($this->isHash($value)) { + foreach ($value as $k => $v) { + $array[] = ', '; + $array[] = new self($k); + $array[] = ': '; + $array[] = new self($v); + } + $array[0] = '{'; + $array[] = '}'; + } else { + foreach ($value as $v) { + $array[] = ', '; + $array[] = new self($v); + } + $array[0] = '['; + $array[] = ']'; + } + + return $array; + } +} diff --git a/vendor/symfony/expression-language/Node/FunctionNode.php b/vendor/symfony/expression-language/Node/FunctionNode.php new file mode 100644 index 0000000000..13928c8d4f --- /dev/null +++ b/vendor/symfony/expression-language/Node/FunctionNode.php @@ -0,0 +1,67 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier <fabien@symfony.com> + * + * @internal + */ +class FunctionNode extends Node +{ + public function __construct($name, Node $arguments) + { + parent::__construct( + array('arguments' => $arguments), + array('name' => $name) + ); + } + + public function compile(Compiler $compiler) + { + $arguments = array(); + foreach ($this->nodes['arguments']->nodes as $node) { + $arguments[] = $compiler->subcompile($node); + } + + $function = $compiler->getFunction($this->attributes['name']); + + $compiler->raw(call_user_func_array($function['compiler'], $arguments)); + } + + public function evaluate($functions, $values) + { + $arguments = array($values); + foreach ($this->nodes['arguments']->nodes as $node) { + $arguments[] = $node->evaluate($functions, $values); + } + + return call_user_func_array($functions[$this->attributes['name']]['evaluator'], $arguments); + } + + public function toArray() + { + $array = array(); + $array[] = $this->attributes['name']; + + foreach ($this->nodes['arguments']->nodes as $node) { + $array[] = ', '; + $array[] = $node; + } + $array[1] = '('; + $array[] = ')'; + + return $array; + } +} diff --git a/vendor/symfony/expression-language/Node/GetAttrNode.php b/vendor/symfony/expression-language/Node/GetAttrNode.php new file mode 100644 index 0000000000..2ecba97f7f --- /dev/null +++ b/vendor/symfony/expression-language/Node/GetAttrNode.php @@ -0,0 +1,114 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier <fabien@symfony.com> + * + * @internal + */ +class GetAttrNode extends Node +{ + const PROPERTY_CALL = 1; + const METHOD_CALL = 2; + const ARRAY_CALL = 3; + + public function __construct(Node $node, Node $attribute, ArrayNode $arguments, $type) + { + parent::__construct( + array('node' => $node, 'attribute' => $attribute, 'arguments' => $arguments), + array('type' => $type) + ); + } + + public function compile(Compiler $compiler) + { + switch ($this->attributes['type']) { + case self::PROPERTY_CALL: + $compiler + ->compile($this->nodes['node']) + ->raw('->') + ->raw($this->nodes['attribute']->attributes['value']) + ; + break; + + case self::METHOD_CALL: + $compiler + ->compile($this->nodes['node']) + ->raw('->') + ->raw($this->nodes['attribute']->attributes['value']) + ->raw('(') + ->compile($this->nodes['arguments']) + ->raw(')') + ; + break; + + case self::ARRAY_CALL: + $compiler + ->compile($this->nodes['node']) + ->raw('[') + ->compile($this->nodes['attribute'])->raw(']') + ; + break; + } + } + + public function evaluate($functions, $values) + { + switch ($this->attributes['type']) { + case self::PROPERTY_CALL: + $obj = $this->nodes['node']->evaluate($functions, $values); + if (!is_object($obj)) { + throw new \RuntimeException('Unable to get a property on a non-object.'); + } + + $property = $this->nodes['attribute']->attributes['value']; + + return $obj->$property; + + case self::METHOD_CALL: + $obj = $this->nodes['node']->evaluate($functions, $values); + if (!is_object($obj)) { + throw new \RuntimeException('Unable to get a property on a non-object.'); + } + if (!is_callable($toCall = array($obj, $this->nodes['attribute']->attributes['value']))) { + throw new \RuntimeException(sprintf('Unable to call method "%s" of object "%s".', $this->nodes['attribute']->attributes['value'], get_class($obj))); + } + + return call_user_func_array($toCall, $this->nodes['arguments']->evaluate($functions, $values)); + + case self::ARRAY_CALL: + $array = $this->nodes['node']->evaluate($functions, $values); + if (!is_array($array) && !$array instanceof \ArrayAccess) { + throw new \RuntimeException('Unable to get an item on a non-array.'); + } + + return $array[$this->nodes['attribute']->evaluate($functions, $values)]; + } + } + + public function toArray() + { + switch ($this->attributes['type']) { + case self::PROPERTY_CALL: + return array($this->nodes['node'], '.', $this->nodes['attribute']); + + case self::METHOD_CALL: + return array($this->nodes['node'], '.', $this->nodes['attribute'], '(', $this->nodes['arguments'], ')'); + + case self::ARRAY_CALL: + return array($this->nodes['node'], '[', $this->nodes['attribute'], ']'); + } + } +} diff --git a/vendor/symfony/expression-language/Node/NameNode.php b/vendor/symfony/expression-language/Node/NameNode.php new file mode 100644 index 0000000000..9e1462f2c6 --- /dev/null +++ b/vendor/symfony/expression-language/Node/NameNode.php @@ -0,0 +1,45 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier <fabien@symfony.com> + * + * @internal + */ +class NameNode extends Node +{ + public function __construct($name) + { + parent::__construct( + array(), + array('name' => $name) + ); + } + + public function compile(Compiler $compiler) + { + $compiler->raw('$'.$this->attributes['name']); + } + + public function evaluate($functions, $values) + { + return $values[$this->attributes['name']]; + } + + public function toArray() + { + return array($this->attributes['name']); + } +} diff --git a/vendor/symfony/expression-language/Node/Node.php b/vendor/symfony/expression-language/Node/Node.php new file mode 100644 index 0000000000..1db4e85280 --- /dev/null +++ b/vendor/symfony/expression-language/Node/Node.php @@ -0,0 +1,110 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * Represents a node in the AST. + * + * @author Fabien Potencier <fabien@symfony.com> + */ +class Node +{ + public $nodes = array(); + public $attributes = array(); + + /** + * @param array $nodes An array of nodes + * @param array $attributes An array of attributes + */ + public function __construct(array $nodes = array(), array $attributes = array()) + { + $this->nodes = $nodes; + $this->attributes = $attributes; + } + + public function __toString() + { + $attributes = array(); + foreach ($this->attributes as $name => $value) { + $attributes[] = sprintf('%s: %s', $name, str_replace("\n", '', var_export($value, true))); + } + + $repr = array(str_replace('Symfony\Component\ExpressionLanguage\Node\\', '', get_class($this)).'('.implode(', ', $attributes)); + + if (count($this->nodes)) { + foreach ($this->nodes as $node) { + foreach (explode("\n", (string) $node) as $line) { + $repr[] = ' '.$line; + } + } + + $repr[] = ')'; + } else { + $repr[0] .= ')'; + } + + return implode("\n", $repr); + } + + public function compile(Compiler $compiler) + { + foreach ($this->nodes as $node) { + $node->compile($compiler); + } + } + + public function evaluate($functions, $values) + { + $results = array(); + foreach ($this->nodes as $node) { + $results[] = $node->evaluate($functions, $values); + } + + return $results; + } + + public function toArray() + { + throw new \BadMethodCallException(sprintf('Dumping a "%s" instance is not supported yet.', get_class($this))); + } + + public function dump() + { + $dump = ''; + + foreach ($this->toArray() as $v) { + $dump .= is_scalar($v) ? $v : $v->dump(); + } + + return $dump; + } + + protected function dumpString($value) + { + return sprintf('"%s"', addcslashes($value, "\0\t\"\\")); + } + + protected function isHash(array $value) + { + $expectedKey = 0; + + foreach ($value as $key => $val) { + if ($key !== $expectedKey++) { + return true; + } + } + + return false; + } +} diff --git a/vendor/symfony/expression-language/Node/UnaryNode.php b/vendor/symfony/expression-language/Node/UnaryNode.php new file mode 100644 index 0000000000..583103217a --- /dev/null +++ b/vendor/symfony/expression-language/Node/UnaryNode.php @@ -0,0 +1,66 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier <fabien@symfony.com> + * + * @internal + */ +class UnaryNode extends Node +{ + private static $operators = array( + '!' => '!', + 'not' => '!', + '+' => '+', + '-' => '-', + ); + + public function __construct($operator, Node $node) + { + parent::__construct( + array('node' => $node), + array('operator' => $operator) + ); + } + + public function compile(Compiler $compiler) + { + $compiler + ->raw('(') + ->raw(self::$operators[$this->attributes['operator']]) + ->compile($this->nodes['node']) + ->raw(')') + ; + } + + public function evaluate($functions, $values) + { + $value = $this->nodes['node']->evaluate($functions, $values); + switch ($this->attributes['operator']) { + case 'not': + case '!': + return !$value; + case '-': + return -$value; + } + + return $value; + } + + public function toArray() + { + return array('(', $this->attributes['operator'].' ', $this->nodes['node'], ')'); + } +} |
