Skip to content

Commit

Permalink
Fix compatibility with twig 3.9 and yielding
Browse files Browse the repository at this point in the history
  • Loading branch information
jderusse committed Apr 22, 2024
1 parent 6a6c75e commit d1b8f05
Showing 1 changed file with 31 additions and 11 deletions.
42 changes: 31 additions & 11 deletions src/Twig/Node/CSPNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,40 +22,60 @@
* file that was distributed with this source code.
*/

use Twig\Attribute\YieldReady;
use Twig\Compiler;
use Twig\Node\CaptureNode;
use Twig\Node\Node;

#[YieldReady]
final class CSPNode extends Node
{
private ?string $sha;
private string $directive;

public function __construct(Node $body, int $lineno, string $tag, string $directive, ?string $sha = null)
{
if (class_exists(CaptureNode::class)) {
$body = new CaptureNode($body, $lineno, $tag);
$body->setAttribute('raw', true);
}

parent::__construct(['body' => $body], [], $lineno, $tag);
$this->sha = $sha;
$this->directive = $directive;
}

public function compile(Compiler $compiler): void
{
$body = $this->getNode('body');
if (class_exists(CaptureNode::class)) {
$compiler
->addDebugInfo($this)
->indent()
->write("\$content = ")
->subcompile($this->getNode('body'))
->raw("\n")
->outdent()
;
} else {
$compiler
->addDebugInfo($this)
->indent()
->write("ob_start();\n")
->subcompile($this->getNode('body'))
->outdent()
->write("\$output = ob_get_clean();\n")
;
}

if (null !== $this->sha) {
$output = "\$this->env->getRuntime('Nelmio\SecurityBundle\Twig\CSPRuntime')->getListener()->addSha('{$this->directive}', '{$this->sha}');\necho ob_get_clean();\n";
$compiler->write("\$this->env->getRuntime('Nelmio\SecurityBundle\Twig\CSPRuntime')->getListener()->addSha('{$this->directive}', '{$this->sha}');\n");
} elseif ('script-src' === $this->directive) {
$output = "\$script = ob_get_clean();\n\$this->env->getRuntime('Nelmio\SecurityBundle\Twig\CSPRuntime')->getListener()->addScript(\$script);\necho \$script;\n";
$compiler->write("\$this->env->getRuntime('Nelmio\SecurityBundle\Twig\CSPRuntime')->getListener()->addScript(\$content);\n");
} elseif ('style-src' === $this->directive) {
$output = "\$style = ob_get_clean();\n\$this->env->getRuntime('Nelmio\SecurityBundle\Twig\CSPRuntime')->getListener()->addStyle(\$style);\necho \$style;\n";
$compiler->write("\$this->env->getRuntime('Nelmio\SecurityBundle\Twig\CSPRuntime')->getListener()->addStyle(\$content);\n");
} else {
throw new \InvalidArgumentException(sprintf('Unable to compile for directive "%s"', $this->directive));
}

$compiler
->addDebugInfo($this)
->write("ob_start();\n")
->subcompile($body)
->write($output)
;
$compiler->write("echo \$content;\n");
}
}

0 comments on commit d1b8f05

Please sign in to comment.