ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
URI.php
Go to the documentation of this file.
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  if ($def->defaultScheme !== null) {
89  // something funky happened to the default scheme object
90  trigger_error(
91  'Default scheme object "' . $def->defaultScheme . '" was not readable',
92  E_USER_WARNING
93  );
94  } // suppress error if it's null
95  return false;
96  }
97  }
98  return $scheme_obj;
99  }
100 
108  public function validate($config, $context)
109  {
110  // ABNF definitions from RFC 3986
111  $chars_sub_delims = '!$&\'()*+,;=';
112  $chars_gen_delims = ':/?#[]@';
113  $chars_pchar = $chars_sub_delims . ':@';
114 
115  // validate host
116  if (!is_null($this->host)) {
117  $host_def = new HTMLPurifier_AttrDef_URI_Host();
118  $this->host = $host_def->validate($this->host, $config, $context);
119  if ($this->host === false) {
120  $this->host = null;
121  }
122  }
123 
124  // validate scheme
125  // NOTE: It's not appropriate to check whether or not this
126  // scheme is in our registry, since a URIFilter may convert a
127  // URI that we don't allow into one we do. So instead, we just
128  // check if the scheme can be dropped because there is no host
129  // and it is our default scheme.
130  if (!is_null($this->scheme) && is_null($this->host) || $this->host === '') {
131  // support for relative paths is pretty abysmal when the
132  // scheme is present, so axe it when possible
133  $def = $config->getDefinition('URI');
134  if ($def->defaultScheme === $this->scheme) {
135  $this->scheme = null;
136  }
137  }
138 
139  // validate username
140  if (!is_null($this->userinfo)) {
141  $encoder = new HTMLPurifier_PercentEncoder($chars_sub_delims . ':');
142  $this->userinfo = $encoder->encode($this->userinfo);
143  }
144 
145  // validate port
146  if (!is_null($this->port)) {
147  if ($this->port < 1 || $this->port > 65535) {
148  $this->port = null;
149  }
150  }
151 
152  // validate path
153  $segments_encoder = new HTMLPurifier_PercentEncoder($chars_pchar . '/');
154  if (!is_null($this->host)) { // this catches $this->host === ''
155  // path-abempty (hier and relative)
156  // http://www.example.com/my/path
157  // //www.example.com/my/path (looks odd, but works, and
158  // recognized by most browsers)
159  // (this set is valid or invalid on a scheme by scheme
160  // basis, so we'll deal with it later)
161  // file:///my/path
162  // ///my/path
163  $this->path = $segments_encoder->encode($this->path);
164  } elseif ($this->path !== '') {
165  if ($this->path[0] === '/') {
166  // path-absolute (hier and relative)
167  // http:/my/path
168  // /my/path
169  if (strlen($this->path) >= 2 && $this->path[1] === '/') {
170  // This could happen if both the host gets stripped
171  // out
172  // http://my/path
173  // //my/path
174  $this->path = '';
175  } else {
176  $this->path = $segments_encoder->encode($this->path);
177  }
178  } elseif (!is_null($this->scheme)) {
179  // path-rootless (hier)
180  // http:my/path
181  // Short circuit evaluation means we don't need to check nz
182  $this->path = $segments_encoder->encode($this->path);
183  } else {
184  // path-noscheme (relative)
185  // my/path
186  // (once again, not checking nz)
187  $segment_nc_encoder = new HTMLPurifier_PercentEncoder($chars_sub_delims . '@');
188  $c = strpos($this->path, '/');
189  if ($c !== false) {
190  $this->path =
191  $segment_nc_encoder->encode(substr($this->path, 0, $c)) .
192  $segments_encoder->encode(substr($this->path, $c));
193  } else {
194  $this->path = $segment_nc_encoder->encode($this->path);
195  }
196  }
197  } else {
198  // path-empty (hier and relative)
199  $this->path = ''; // just to be safe
200  }
201 
202  // qf = query and fragment
203  $qf_encoder = new HTMLPurifier_PercentEncoder($chars_pchar . '/?');
204 
205  if (!is_null($this->query)) {
206  $this->query = $qf_encoder->encode($this->query);
207  }
208 
209  if (!is_null($this->fragment)) {
210  $this->fragment = $qf_encoder->encode($this->fragment);
211  }
212  return true;
213  }
214 
219  public function toString()
220  {
221  // reconstruct authority
222  $authority = null;
223  // there is a rendering difference between a null authority
224  // (http:foo-bar) and an empty string authority
225  // (http:///foo-bar).
226  if (!is_null($this->host)) {
227  $authority = '';
228  if (!is_null($this->userinfo)) {
229  $authority .= $this->userinfo . '@';
230  }
232  if (!is_null($this->port)) {
233  $authority .= ':' . $this->port;
234  }
235  }
236 
237  // Reconstruct the result
238  // One might wonder about parsing quirks from browsers after
239  // this reconstruction. Unfortunately, parsing behavior depends
240  // on what *scheme* was employed (file:///foo is handled *very*
241  // differently than http:///foo), so unfortunately we have to
242  // defer to the schemes to do the right thing.
243  $result = '';
244  if (!is_null($this->scheme)) {
245  $result .= $this->scheme . ':';
246  }
247  if (!is_null($authority)) {
248  $result .= '//' . $authority;
249  }
250  $result .= $this->path;
251  if (!is_null($this->query)) {
252  $result .= '?' . $this->query;
253  }
254  if (!is_null($this->fragment)) {
255  $result .= '#' . $this->fragment;
256  }
257 
258  return $result;
259  }
260 
273  public function isLocal($config, $context)
274  {
275  if ($this->host === null) {
276  return true;
277  }
278  $uri_def = $config->getDefinition('URI');
279  if ($uri_def->host === $this->host) {
280  return true;
281  }
282  return false;
283  }
284 
295  public function isBenign($config, $context)
296  {
297  if (!$this->isLocal($config, $context)) {
298  return false;
299  }
300 
301  $scheme_obj = $this->getSchemeObj($config, $context);
302  if (!$scheme_obj) {
303  return false;
304  } // conservative approach
305 
306  $current_scheme_obj = $config->getDefinition('URI')->getDefaultScheme($config, $context);
307  if ($current_scheme_obj->secure) {
308  if (!$scheme_obj->secure) {
309  return false;
310  }
311  }
312  return true;
313  }
314 }
315 
316 // vim: et sw=4 sts=4
__construct($scheme, $userinfo, $host, $port, $path, $query, $fragment)
Definition: URI.php:58
$result
$path
string
Definition: URI.php:36
$query
string
Definition: URI.php:41
isBenign($config, $context)
Returns true if this URL should be considered a &#39;benign&#39; URL, that is:
Definition: URI.php:295
Class that handles operations involving percent-encoding in URIs.
toString()
Convert URI back to string.
Definition: URI.php:219
Validates a host according to the IPv4, IPv6 and DNS (future) specifications.
Definition: Host.php:6
$userinfo
string
Definition: URI.php:21
isLocal($config, $context)
Returns true if this URL might be considered a &#39;local&#39; URL given the current context.
Definition: URI.php:273
validate($config, $context)
Generic validation method applicable for all schemes.
Definition: URI.php:108
getSchemeObj($config, $context)
Retrieves a scheme object corresponding to the URI&#39;s scheme/default.
Definition: URI.php:75
static instance($prototype=null)
Retrieve sole instance of the registry.
$scheme
string
Definition: URI.php:16
$def
Definition: croninfo.php:21
HTML Purifier&#39;s internal representation of a URI.
Definition: URI.php:11
$host
string
Definition: URI.php:26
$authority
$fragment
string
Definition: URI.php:46