Project

General

Profile

1
<?php
2

    
3
/*
4
 * This file is part of Twig.
5
 *
6
 * (c) 2009 Fabien Potencier
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

    
12
/**
13
 * Twig_NodeVisitor_Sandbox implements sandboxing.
14
 *
15
 * @package    twig
16
 * @author     Fabien Potencier <fabien@symfony.com>
17
 */
18
class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface
19
{
20
    protected $inAModule = false;
21
    protected $tags;
22
    protected $filters;
23
    protected $functions;
24

    
25
    /**
26
     * Called before child nodes are visited.
27
     *
28
     * @param Twig_NodeInterface $node The node to visit
29
     * @param Twig_Environment   $env  The Twig environment instance
30
     *
31
     * @return Twig_NodeInterface The modified node
32
     */
33
    public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
34
    {
35
        // in a sandbox tag, only include tags are allowed
36
        if ($node instanceof Twig_Node_Sandbox && !$node->getNode('body') instanceof Twig_Node_Include) {
37
            foreach ($node->getNode('body') as $n) {
38
                if ($n instanceof Twig_Node_Text && ctype_space($n->getAttribute('data'))) {
39
                    continue;
40
                }
41

    
42
                if (!$n instanceof Twig_Node_Include) {
43
                    throw new Twig_Error_Syntax('Only "include" tags are allowed within a "sandbox" section', $n->getLine());
44
                }
45
            }
46
        }
47

    
48
        if ($node instanceof Twig_Node_Module) {
49
            $this->inAModule = true;
50
            $this->tags = array();
51
            $this->filters = array();
52
            $this->functions = array();
53

    
54
            return $node;
55
        } elseif ($this->inAModule) {
56
            // look for tags
57
            if ($node->getNodeTag()) {
58
                $this->tags[] = $node->getNodeTag();
59
            }
60

    
61
            // look for filters
62
            if ($node instanceof Twig_Node_Expression_Filter) {
63
                $this->filters[] = $node->getNode('filter')->getAttribute('value');
64
            }
65

    
66
            // look for functions
67
            if ($node instanceof Twig_Node_Expression_Function) {
68
                $this->functions[] = $node->getAttribute('name');
69
            }
70

    
71
            // wrap print to check __toString() calls
72
            if ($node instanceof Twig_Node_Print) {
73
                return new Twig_Node_SandboxedPrint($node->getNode('expr'), $node->getLine(), $node->getNodeTag());
74
            }
75
        }
76

    
77
        return $node;
78
    }
79

    
80
    /**
81
     * Called after child nodes are visited.
82
     *
83
     * @param Twig_NodeInterface $node The node to visit
84
     * @param Twig_Environment   $env  The Twig environment instance
85
     *
86
     * @return Twig_NodeInterface The modified node
87
     */
88
    public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
89
    {
90
        if ($node instanceof Twig_Node_Module) {
91
            $this->inAModule = false;
92

    
93
            return new Twig_Node_SandboxedModule($node, array_unique($this->filters), array_unique($this->tags), array_unique($this->functions));
94
        }
95

    
96
        return $node;
97
    }
98

    
99
    /**
100
     * {@inheritdoc}
101
     */
102
    public function getPriority()
103
    {
104
        return 0;
105
    }
106
}
(4-4/5)