Blame view

vendor/ezyang/htmlpurifier/library/HTMLPurifier/Injector/SafeObject.php 3.66 KB
70f4f18b   Administrator   first_commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
  <?php
  
  /**
   * Adds important param elements to inside of object in order to make
   * things safe.
   */
  class HTMLPurifier_Injector_SafeObject extends HTMLPurifier_Injector
  {
      /**
       * @type string
       */
      public $name = 'SafeObject';
  
      /**
       * @type array
       */
      public $needed = array('object', 'param');
  
      /**
       * @type array
       */
      protected $objectStack = array();
  
      /**
       * @type array
       */
      protected $paramStack = array();
  
      /**
       * Keep this synchronized with AttrTransform/SafeParam.php.
       * @type array
       */
      protected $addParam = array(
          'allowScriptAccess' => 'never',
          'allowNetworking' => 'internal',
      );
  
      /**
       * @type array
       */
      protected $allowedParam = array(
          'wmode' => true,
          'movie' => true,
          'flashvars' => true,
          'src' => true,
          'allowFullScreen' => true, // if omitted, assume to be 'false'
      );
  
      /**
       * @param HTMLPurifier_Config $config
       * @param HTMLPurifier_Context $context
       * @return void
       */
      public function prepare($config, $context)
      {
          parent::prepare($config, $context);
      }
  
      /**
       * @param HTMLPurifier_Token $token
       */
      public function handleElement(&$token)
      {
          if ($token->name == 'object') {
              $this->objectStack[] = $token;
              $this->paramStack[] = array();
              $new = array($token);
              foreach ($this->addParam as $name => $value) {
                  $new[] = new HTMLPurifier_Token_Empty('param', array('name' => $name, 'value' => $value));
              }
              $token = $new;
          } elseif ($token->name == 'param') {
              $nest = count($this->currentNesting) - 1;
              if ($nest >= 0 && $this->currentNesting[$nest]->name === 'object') {
                  $i = count($this->objectStack) - 1;
                  if (!isset($token->attr['name'])) {
                      $token = false;
                      return;
                  }
                  $n = $token->attr['name'];
                  // We need this fix because YouTube doesn't supply a data
                  // attribute, which we need if a type is specified. This is
                  // *very* Flash specific.
                  if (!isset($this->objectStack[$i]->attr['data']) &&
                      ($token->attr['name'] == 'movie' || $token->attr['name'] == 'src')
                  ) {
                      $this->objectStack[$i]->attr['data'] = $token->attr['value'];
                  }
                  // Check if the parameter is the correct value but has not
                  // already been added
                  if (!isset($this->paramStack[$i][$n]) &&
                      isset($this->addParam[$n]) &&
                      $token->attr['name'] === $this->addParam[$n]) {
                      // keep token, and add to param stack
                      $this->paramStack[$i][$n] = true;
                  } elseif (isset($this->allowedParam[$n])) {
                      // keep token, don't do anything to it
                      // (could possibly check for duplicates here)
                  } else {
                      $token = false;
                  }
              } else {
                  // not directly inside an object, DENY!
                  $token = false;
              }
          }
      }
  
      public function handleEnd(&$token)
      {
          // This is the WRONG way of handling the object and param stacks;
          // we should be inserting them directly on the relevant object tokens
          // so that the global stack handling handles it.
          if ($token->name == 'object') {
              array_pop($this->objectStack);
              array_pop($this->paramStack);
          }
      }
  }
  
  // vim: et sw=4 sts=4