CheckSecurityNode.php 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. <?php
  2. /*
  3. * This file is part of Twig.
  4. *
  5. * (c) Fabien Potencier
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Twig\Node;
  11. use Twig\Compiler;
  12. /**
  13. * @author Fabien Potencier <fabien@symfony.com>
  14. */
  15. class CheckSecurityNode extends Node
  16. {
  17. private $usedFilters;
  18. private $usedTags;
  19. private $usedFunctions;
  20. public function __construct(array $usedFilters, array $usedTags, array $usedFunctions)
  21. {
  22. $this->usedFilters = $usedFilters;
  23. $this->usedTags = $usedTags;
  24. $this->usedFunctions = $usedFunctions;
  25. parent::__construct();
  26. }
  27. public function compile(Compiler $compiler): void
  28. {
  29. $tags = $filters = $functions = [];
  30. foreach (['tags', 'filters', 'functions'] as $type) {
  31. foreach ($this->{'used'.ucfirst($type)} as $name => $node) {
  32. if ($node instanceof Node) {
  33. ${$type}[$name] = $node->getTemplateLine();
  34. } else {
  35. ${$type}[$node] = null;
  36. }
  37. }
  38. }
  39. $compiler
  40. ->write("\n")
  41. ->write("public function checkSecurity()\n")
  42. ->write("{\n")
  43. ->indent()
  44. ->write('static $tags = ')->repr(array_filter($tags))->raw(";\n")
  45. ->write('static $filters = ')->repr(array_filter($filters))->raw(";\n")
  46. ->write('static $functions = ')->repr(array_filter($functions))->raw(";\n\n")
  47. ->write("try {\n")
  48. ->indent()
  49. ->write("\$this->sandbox->checkSecurity(\n")
  50. ->indent()
  51. ->write(!$tags ? "[],\n" : "['".implode("', '", array_keys($tags))."'],\n")
  52. ->write(!$filters ? "[],\n" : "['".implode("', '", array_keys($filters))."'],\n")
  53. ->write(!$functions ? "[]\n" : "['".implode("', '", array_keys($functions))."']\n")
  54. ->outdent()
  55. ->write(");\n")
  56. ->outdent()
  57. ->write("} catch (SecurityError \$e) {\n")
  58. ->indent()
  59. ->write("\$e->setSourceContext(\$this->source);\n\n")
  60. ->write("if (\$e instanceof SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n")
  61. ->indent()
  62. ->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n")
  63. ->outdent()
  64. ->write("} elseif (\$e instanceof SecurityNotAllowedFilterError && isset(\$filters[\$e->getFilterName()])) {\n")
  65. ->indent()
  66. ->write("\$e->setTemplateLine(\$filters[\$e->getFilterName()]);\n")
  67. ->outdent()
  68. ->write("} elseif (\$e instanceof SecurityNotAllowedFunctionError && isset(\$functions[\$e->getFunctionName()])) {\n")
  69. ->indent()
  70. ->write("\$e->setTemplateLine(\$functions[\$e->getFunctionName()]);\n")
  71. ->outdent()
  72. ->write("}\n\n")
  73. ->write("throw \$e;\n")
  74. ->outdent()
  75. ->write("}\n\n")
  76. ->outdent()
  77. ->write("}\n")
  78. ;
  79. }
  80. }