HTMLPurifier/URIFilter/MakeAbsolute.php Quellcode

MakeAbsolute.php
gehe zur Dokumentation dieser Datei
1 <?php
2 
3 // does not support network paths
4 
6 {
10  public $name = 'MakeAbsolute';
11 
15  protected $base;
16 
20  protected $basePathStack = array();
21 
26  public function prepare($config)
27  {
28  $def = $config->getDefinition('URI');
29  $this->base = $def->base;
30  if (is_null($this->base)) {
31  trigger_error(
32  'URI.MakeAbsolute is being ignored due to lack of ' .
33  'value for URI.Base configuration',
34  E_USER_WARNING
35  );
36  return false;
37  }
38  $this->base->fragment = null; // fragment is invalid for base URI
39  $stack = explode('/', $this->base->path);
40  array_pop($stack); // discard last segment
41  $stack = $this->_collapseStack($stack); // do pre-parsing
42  $this->basePathStack = $stack;
43  return true;
44  }
45 
52  public function filter(&$uri, $config, $context)
53  {
54  if (is_null($this->base)) {
55  return true;
56  } // abort early
57  if ($uri->path === '' && is_null($uri->scheme) &&
58  is_null($uri->host) && is_null($uri->query) && is_null($uri->fragment)) {
59  // reference to current document
60  $uri = clone $this->base;
61  return true;
62  }
63  if (!is_null($uri->scheme)) {
64  // absolute URI already: don't change
65  if (!is_null($uri->host)) {
66  return true;
67  }
68  $scheme_obj = $uri->getSchemeObj($config, $context);
69  if (!$scheme_obj) {
70  // scheme not recognized
71  return false;
72  }
73  if (!$scheme_obj->hierarchical) {
74  // non-hierarchal URI with explicit scheme, don't change
75  return true;
76  }
77  // special case: had a scheme but always is hierarchical and had no authority
78  }
79  if (!is_null($uri->host)) {
80  // network path, don't bother
81  return true;
82  }
83  if ($uri->path === '') {
84  $uri->path = $this->base->path;
85  } elseif ($uri->path[0] !== '/') {
86  // relative path, needs more complicated processing
87  $stack = explode('/', $uri->path);
88  $new_stack = array_merge($this->basePathStack, $stack);
89  if ($new_stack[0] !== '' && !is_null($this->base->host)) {
90  array_unshift($new_stack, '');
91  }
92  $new_stack = $this->_collapseStack($new_stack);
93  $uri->path = implode('/', $new_stack);
94  } else {
95  // absolute path, but still we should collapse
96  $uri->path = implode('/', $this->_collapseStack(explode('/', $uri->path)));
97  }
98  // re-combine
99  $uri->scheme = $this->base->scheme;
100  if (is_null($uri->userinfo)) {
101  $uri->userinfo = $this->base->userinfo;
102  }
103  if (is_null($uri->host)) {
104  $uri->host = $this->base->host;
105  }
106  if (is_null($uri->port)) {
107  $uri->port = $this->base->port;
108  }
109  return true;
110  }
111 
117  private function _collapseStack($stack)
118  {
119  $result = array();
120  $is_folder = false;
121  for ($i = 0; isset($stack[$i]); $i++) {
122  $is_folder = false;
123  // absorb an internally duplicated slash
124  if ($stack[$i] == '' && $i && isset($stack[$i + 1])) {
125  continue;
126  }
127  if ($stack[$i] == '..') {
128  if (!empty($result)) {
129  $segment = array_pop($result);
130  if ($segment === '' && empty($result)) {
131  // error case: attempted to back out too far:
132  // restore the leading slash
133  $result[] = '';
134  } elseif ($segment === '..') {
135  $result[] = '..'; // cannot remove .. with ..
136  }
137  } else {
138  // relative path, preserve the double-dots
139  $result[] = '..';
140  }
141  $is_folder = true;
142  continue;
143  }
144  if ($stack[$i] == '.') {
145  // silently absorb
146  $is_folder = true;
147  continue;
148  }
149  $result[] = $stack[$i];
150  }
151  if ($is_folder) {
152  $result[] = '';
153  }
154  return $result;
155  }
156 }
157 
158 // vim: et sw=4 sts=4




Korrekturen, Hinweise und Ergänzungen

Bitte scheuen Sie sich nicht und melden Sie, was auf dieser Seite sachlich falsch oder irreführend ist, was ergänzt werden sollte, was fehlt usw. Dazu bitte oben aus dem Menü Seite den Eintrag Support Forum wählen. Es ist eine kostenlose Anmeldung erforderlich, um Anmerkungen zu posten. Unpassende Postings, Spam usw. werden kommentarlos entfernt.