HTMLPurifier/URI.php Quellcode

URI.php
gehe zur Dokumentation dieser Datei
1 <?php
2 
12 {
16  public $scheme;
17 
21  public $userinfo;
22 
26  public $host;
27 
31  public $port;
32 
36  public $path;
37 
41  public $query;
42 
46  public $fragment;
47 
59  {
60  $this->scheme = is_null($scheme) || ctype_lower($scheme) ? $scheme : strtolower($scheme);
61  $this->userinfo = $userinfo;
62  $this->host = $host;
63  $this->port = is_null($port) ? $port : (int)$port;
64  $this->path = $path;
65  $this->query = $query;
66  $this->fragment = $fragment;
67  }
68 
75  public function getSchemeObj($config, $context)
76  {
78  if ($this->scheme !== null) {
79  $scheme_obj = $registry->getScheme($this->scheme, $config, $context);
80  if (!$scheme_obj) {
81  return false;
82  } // invalid scheme, clean it out
83  } else {
84  // no scheme: retrieve the default one
85  $def = $config->getDefinition('URI');
86  $scheme_obj = $def->getDefaultScheme($config, $context);
87  if (!$scheme_obj) {
88  // something funky happened to the default scheme object
89  trigger_error(
90  'Default scheme object "' . $def->defaultScheme . '" was not readable',
91  E_USER_WARNING
92  );
93  return false;
94  }
95  }
96  return $scheme_obj;
97  }
98 
106  public function validate($config, $context)
107  {
108  // ABNF definitions from RFC 3986
109  $chars_sub_delims = '!$&\'()*+,;=';
110  $chars_gen_delims = ':/?#[]@';
111  $chars_pchar = $chars_sub_delims . ':@';
112 
113  // validate host
114  if (!is_null($this->host)) {
115  $host_def = new HTMLPurifier_AttrDef_URI_Host();
116  $this->host = $host_def->validate($this->host, $config, $context);
117  if ($this->host === false) {
118  $this->host = null;
119  }
120  }
121 
122  // validate scheme
123  // NOTE: It's not appropriate to check whether or not this
124  // scheme is in our registry, since a URIFilter may convert a
125  // URI that we don't allow into one we do. So instead, we just
126  // check if the scheme can be dropped because there is no host
127  // and it is our default scheme.
128  if (!is_null($this->scheme) && is_null($this->host) || $this->host === '') {
129  // support for relative paths is pretty abysmal when the
130  // scheme is present, so axe it when possible
131  $def = $config->getDefinition('URI');
132  if ($def->defaultScheme === $this->scheme) {
133  $this->scheme = null;
134  }
135  }
136 
137  // validate username
138  if (!is_null($this->userinfo)) {
139  $encoder = new HTMLPurifier_PercentEncoder($chars_sub_delims . ':');
140  $this->userinfo = $encoder->encode($this->userinfo);
141  }
142 
143  // validate port
144  if (!is_null($this->port)) {
145  if ($this->port < 1 || $this->port > 65535) {
146  $this->port = null;
147  }
148  }
149 
150  // validate path
151  $segments_encoder = new HTMLPurifier_PercentEncoder($chars_pchar . '/');
152  if (!is_null($this->host)) { // this catches $this->host === ''
153  // path-abempty (hier and relative)
154  // http://www.example.com/my/path
155  // //www.example.com/my/path (looks odd, but works, and
156  // recognized by most browsers)
157  // (this set is valid or invalid on a scheme by scheme
158  // basis, so we'll deal with it later)
159  // file:///my/path
160  // ///my/path
161  $this->path = $segments_encoder->encode($this->path);
162  } elseif ($this->path !== '') {
163  if ($this->path[0] === '/') {
164  // path-absolute (hier and relative)
165  // http:/my/path
166  // /my/path
167  if (strlen($this->path) >= 2 && $this->path[1] === '/') {
168  // This could happen if both the host gets stripped
169  // out
170  // http://my/path
171  // //my/path
172  $this->path = '';
173  } else {
174  $this->path = $segments_encoder->encode($this->path);
175  }
176  } elseif (!is_null($this->scheme)) {
177  // path-rootless (hier)
178  // http:my/path
179  // Short circuit evaluation means we don't need to check nz
180  $this->path = $segments_encoder->encode($this->path);
181  } else {
182  // path-noscheme (relative)
183  // my/path
184  // (once again, not checking nz)
185  $segment_nc_encoder = new HTMLPurifier_PercentEncoder($chars_sub_delims . '@');
186  $c = strpos($this->path, '/');
187  if ($c !== false) {
188  $this->path =
189  $segment_nc_encoder->encode(substr($this->path, 0, $c)) .
190  $segments_encoder->encode(substr($this->path, $c));
191  } else {
192  $this->path = $segment_nc_encoder->encode($this->path);
193  }
194  }
195  } else {
196  // path-empty (hier and relative)
197  $this->path = ''; // just to be safe
198  }
199 
200  // qf = query and fragment
201  $qf_encoder = new HTMLPurifier_PercentEncoder($chars_pchar . '/?');
202 
203  if (!is_null($this->query)) {
204  $this->query = $qf_encoder->encode($this->query);
205  }
206 
207  if (!is_null($this->fragment)) {
208  $this->fragment = $qf_encoder->encode($this->fragment);
209  }
210  return true;
211  }
212 
217  public function toString()
218  {
219  // reconstruct authority
220  $authority = null;
221  // there is a rendering difference between a null authority
222  // (http:foo-bar) and an empty string authority
223  // (http:///foo-bar).
224  if (!is_null($this->host)) {
225  $authority = '';
226  if (!is_null($this->userinfo)) {
227  $authority .= $this->userinfo . '@';
228  }
229  $authority .= $this->host;
230  if (!is_null($this->port)) {
231  $authority .= ':' . $this->port;
232  }
233  }
234 
235  // Reconstruct the result
236  // One might wonder about parsing quirks from browsers after
237  // this reconstruction. Unfortunately, parsing behavior depends
238  // on what *scheme* was employed (file:///foo is handled *very*
239  // differently than http:///foo), so unfortunately we have to
240  // defer to the schemes to do the right thing.
241  $result = '';
242  if (!is_null($this->scheme)) {
243  $result .= $this->scheme . ':';
244  }
245  if (!is_null($authority)) {
246  $result .= '//' . $authority;
247  }
248  $result .= $this->path;
249  if (!is_null($this->query)) {
250  $result .= '?' . $this->query;
251  }
252  if (!is_null($this->fragment)) {
253  $result .= '#' . $this->fragment;
254  }
255 
256  return $result;
257  }
258 
271  public function isLocal($config, $context)
272  {
273  if ($this->host === null) {
274  return true;
275  }
276  $uri_def = $config->getDefinition('URI');
277  if ($uri_def->host === $this->host) {
278  return true;
279  }
280  return false;
281  }
282 
293  public function isBenign($config, $context)
294  {
295  if (!$this->isLocal($config, $context)) {
296  return false;
297  }
298 
299  $scheme_obj = $this->getSchemeObj($config, $context);
300  if (!$scheme_obj) {
301  return false;
302  } // conservative approach
303 
304  $current_scheme_obj = $config->getDefinition('URI')->getDefaultScheme($config, $context);
305  if ($current_scheme_obj->secure) {
306  if (!$scheme_obj->secure) {
307  return false;
308  }
309  }
310  return true;
311  }
312 }
313 
314 // 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.