/** * Determines at compile time whether the generated URL will be safe and thus * saving the unneeded automatic escaping for performance reasons. * * The URL generation process percent encodes non-alphanumeric characters. So there is no risk * that malicious/invalid characters are part of the URL. The only character within an URL that * must be escaped in html is the ampersand ("&") which separates query params. So we cannot mark * the URL generation as always safe, but only when we are sure there won't be multiple query * params. This is the case when there are none or only one constant parameter given. * E.g. we know beforehand this will be safe: * - path('route') * - path('route', {'param': 'value'}) * But the following may not: * - path('route', var) * - path('route', {'param': ['val1', 'val2'] }) // a sub-array * - path('route', {'param1': 'value1', 'param2': 'value2'}) * If param1 and param2 reference placeholder in the route, it would still be safe. But we don't know. * * @param \Twig_Node $argsNode The arguments of the path/url function * * @return array An array with the contexts the URL is safe */ public function isUrlGenerationSafe(\Twig_Node $argsNode) { // support named arguments $paramsNode = $argsNode->hasNode('parameters') ? $argsNode->getNode('parameters') : ($argsNode->hasNode(1) ? $argsNode->getNode(1) : null); if (null === $paramsNode || $paramsNode instanceof \Twig_Node_Expression_Array && count($paramsNode) <= 2 && (!$paramsNode->hasNode(1) || $paramsNode->getNode(1) instanceof \Twig_Node_Expression_Constant)) { return array('html'); } return array(); }
/** * @param \Twig_Node $arguments * @param int $index * * @return string|null */ private function getReadDomainFromArguments(\Twig_Node $arguments, $index) { if ($arguments->hasNode('domain')) { $argument = $arguments->getNode('domain'); } elseif ($arguments->hasNode($index)) { $argument = $arguments->getNode($index); } else { return null; } return $this->getReadDomainFromNode($argument); }
protected function doLeaveNode(\Twig_Node $node, \Twig_Environment $env) { if ($node instanceof \Twig_Node_Include) { if ($node->hasNode('expr') && $node->getNode('expr')->hasAttribute('value')) { $patternStoreKey = $node->getNode('expr')->getAttribute('value'); $data = Data::getPatternSpecificData($patternStoreKey); $dataNode = new PatternDataIncludeNode($node, $data); return $dataNode; } } return $node; }
protected function doLeaveNode(\Twig_Node $node, \Twig_Environment $env) { if ($node instanceof \Twig_Node_Include) { if ($node->hasNode('expr') && $node->getNode('expr')->hasAttribute('value')) { $patternStoreKey = $node->getNode('expr')->getAttribute('value'); $data = $this->dt->getProcessedPatternSpecificData($patternStoreKey); if ($node instanceof \Twig_Node_Embed) { $dataNode = new PatternDataEmbedNode($node, $data); } else { $dataNode = new PatternDataIncludeNode($node, $data); } return $dataNode; } } return $node; }
public function parse(\Twig_Token $token) { $lineno = $token->getLine(); $expression = $this->parser->getExpressionParser()->parseExpression(); $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE); $this->parser->subparse(array($this, 'decideCaseFork')); $cases = new \Twig_Node(); $default = null; $end = false; $i = 0; while (!$end) { switch ($tag = $this->parser->getStream()->next()->getValue()) { case 'case': $i++; $expr = $this->parser->getExpressionParser()->parseExpression(); $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE); $body = $this->parser->subparse(array($this, 'decideCaseFork')); $cases->setNode($i, new \Twig_Node(array('expression' => $expr, 'body' => $body))); break; case 'default': $i = null; $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE); $body = $this->parser->subparse(array($this, 'decideCaseFork')); $default = $body; break; case 'break': $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE); $this->parser->subparse(array($this, 'decideCaseFork')); if ($cases->hasNode($i)) { $cases->getNode($i)->setAttribute('break', true); } break; case 'endswitch': $end = true; break; default: throw new \Twig_Error_Syntax(sprintf('Unexpected end of template at line %d' . $tag, $lineno), -1); } } $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE); return new SwitchNode($cases, $default, $expression, $lineno, $this->getTag()); }
/** * {@inheritdoc} */ protected function doEnterNode(\Twig_Node $node, \Twig_Environment $env) { if ($node instanceof \Twig_Node_Block || $node instanceof \Twig_Node_Module) { $this->scope = $this->scope->enter(); } if ($node instanceof TransDefaultDomainNode) { if ($node->getNode('expr') instanceof \Twig_Node_Expression_Constant) { $this->scope->set('domain', $node->getNode('expr')); return $node; } else { $var = $env->getParser()->getVarName(); $name = new \Twig_Node_Expression_AssignName($var, $node->getLine()); $this->scope->set('domain', new \Twig_Node_Expression_Name($var, $node->getLine())); return new \Twig_Node_Set(false, new \Twig_Node(array($name)), new \Twig_Node(array($node->getNode('expr'))), $node->getLine()); } } if (!$this->scope->has('domain')) { return $node; } if ($node instanceof \Twig_Node_Expression_Filter && in_array($node->getNode('filter')->getAttribute('value'), array('trans', 'transchoice'))) { $arguments = $node->getNode('arguments'); $ind = 'trans' === $node->getNode('filter')->getAttribute('value') ? 1 : 2; if ($this->isNamedArguments($arguments)) { if (!$arguments->hasNode('domain') && !$arguments->hasNode($ind)) { $arguments->setNode('domain', $this->scope->get('domain')); } } else { if (!$arguments->hasNode($ind)) { if (!$arguments->hasNode($ind - 1)) { $arguments->setNode($ind - 1, new \Twig_Node_Expression_Array(array(), $node->getLine())); } $arguments->setNode($ind, $this->scope->get('domain')); } } } elseif ($node instanceof TransNode) { if (!$node->hasNode('domain')) { $node->setNode('domain', $this->scope->get('domain')); } } return $node; }
/** * Determines at compile time whether the generated URL will be safe. * * Saves the unneeded automatic escaping for performance reasons. * * The URL generation process percent encodes non-alphanumeric characters. * Thus, the only character within a URL that must be escaped in HTML is the * ampersand ("&") which separates query params. Thus we cannot mark * the generated URL as always safe, but only when we are sure there won't be * multiple query params. This is the case when there are none or only one * constant parameter given. For instance, we know beforehand this will not * need to be escaped: * - path('route') * - path('route', {'param': 'value'}) * But the following may need to be escaped: * - path('route', var) * - path('route', {'param': ['val1', 'val2'] }) // a sub-array * - path('route', {'param1': 'value1', 'param2': 'value2'}) * If param1 and param2 reference placeholders in the route, it would not * need to be escaped, but we don't know that in advance. * * @param \Twig_Node $args_node * The arguments of the path/url functions. * * @return array * An array with the contexts the URL is safe */ public function isUrlGenerationSafe(\Twig_Node $args_node) { // Support named arguments. $parameter_node = $args_node->hasNode('parameters') ? $args_node->getNode('parameters') : ($args_node->hasNode(1) ? $args_node->getNode(1) : NULL); if (!isset($parameter_node) || $parameter_node instanceof \Twig_Node_Expression_Array && count($parameter_node) <= 2 && (!$parameter_node->hasNode(1) || $parameter_node->getNode(1) instanceof \Twig_Node_Expression_Constant)) { return array('html'); } return array(); }
/** * Extract a message from a \Twig_Node_Print * Return null if not a constant message * * @param \Twig_Node $node */ private function _extractMessage(\Twig_Node $node) { if($node->hasNode('node')) { return $this->_extractMessage($node->getNode ('node')); } if($node instanceof \Twig_Node_Expression_Constant) { return $node->getAttribute('value'); } return null; }
/** * @param \Twig_Node $node * @param $name * @return null|\Twig_Node */ public function getNode(\Twig_Node $node, $name) { return $node->hasNode($name) ? $node->getNode($name) : null; }