PageRenderTime 49ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/moodle/lib/htmlpurifier/HTMLPurifier/URI.php

https://bitbucket.org/geek745/moodle-db2
PHP | 182 lines | 109 code | 23 blank | 50 comment | 33 complexity | 2de71bcff038d2e23515e8870b5cf4a8 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, BSD-3-Clause, LGPL-2.0
  1. <?php
  2. require_once 'HTMLPurifier/URIParser.php';
  3. require_once 'HTMLPurifier/URIFilter.php';
  4. /**
  5. * HTML Purifier's internal representation of a URI.
  6. * @note
  7. * Internal data-structures are completely escaped. If the data needs
  8. * to be used in a non-URI context (which is very unlikely), be sure
  9. * to decode it first. The URI may not necessarily be well-formed until
  10. * validate() is called.
  11. */
  12. class HTMLPurifier_URI
  13. {
  14. var $scheme, $userinfo, $host, $port, $path, $query, $fragment;
  15. /**
  16. * @note Automatically normalizes scheme and port
  17. */
  18. function HTMLPurifier_URI($scheme, $userinfo, $host, $port, $path, $query, $fragment) {
  19. $this->scheme = is_null($scheme) || ctype_lower($scheme) ? $scheme : strtolower($scheme);
  20. $this->userinfo = $userinfo;
  21. $this->host = $host;
  22. $this->port = is_null($port) ? $port : (int) $port;
  23. $this->path = $path;
  24. $this->query = $query;
  25. $this->fragment = $fragment;
  26. }
  27. /**
  28. * Retrieves a scheme object corresponding to the URI's scheme/default
  29. * @param $config Instance of HTMLPurifier_Config
  30. * @param $context Instance of HTMLPurifier_Context
  31. * @return Scheme object appropriate for validating this URI
  32. */
  33. function getSchemeObj($config, &$context) {
  34. $registry =& HTMLPurifier_URISchemeRegistry::instance();
  35. if ($this->scheme !== null) {
  36. $scheme_obj = $registry->getScheme($this->scheme, $config, $context);
  37. if (!$scheme_obj) return false; // invalid scheme, clean it out
  38. } else {
  39. // no scheme: retrieve the default one
  40. $def = $config->getDefinition('URI');
  41. $scheme_obj = $registry->getScheme($def->defaultScheme, $config, $context);
  42. if (!$scheme_obj) {
  43. // something funky happened to the default scheme object
  44. trigger_error(
  45. 'Default scheme object "' . $def->defaultScheme . '" was not readable',
  46. E_USER_WARNING
  47. );
  48. return false;
  49. }
  50. }
  51. return $scheme_obj;
  52. }
  53. /**
  54. * Generic validation method applicable for all schemes. May modify
  55. * this URI in order to get it into a compliant form.
  56. * @param $config Instance of HTMLPurifier_Config
  57. * @param $context Instance of HTMLPurifier_Context
  58. * @return True if validation/filtering succeeds, false if failure
  59. */
  60. function validate($config, &$context) {
  61. // ABNF definitions from RFC 3986
  62. $chars_sub_delims = '!$&\'()*+,;=';
  63. $chars_gen_delims = ':/?#[]@';
  64. $chars_pchar = $chars_sub_delims . ':@';
  65. // validate scheme (MUST BE FIRST!)
  66. if (!is_null($this->scheme) && is_null($this->host)) {
  67. $def = $config->getDefinition('URI');
  68. if ($def->defaultScheme === $this->scheme) {
  69. $this->scheme = null;
  70. }
  71. }
  72. // validate host
  73. if (!is_null($this->host)) {
  74. $host_def = new HTMLPurifier_AttrDef_URI_Host();
  75. $this->host = $host_def->validate($this->host, $config, $context);
  76. if ($this->host === false) $this->host = null;
  77. }
  78. // validate username
  79. if (!is_null($this->userinfo)) {
  80. $encoder = new HTMLPurifier_PercentEncoder($chars_sub_delims . ':');
  81. $this->userinfo = $encoder->encode($this->userinfo);
  82. }
  83. // validate port
  84. if (!is_null($this->port)) {
  85. if ($this->port < 1 || $this->port > 65535) $this->port = null;
  86. }
  87. // validate path
  88. $path_parts = array();
  89. $segments_encoder = new HTMLPurifier_PercentEncoder($chars_pchar . '/');
  90. if (!is_null($this->host)) {
  91. // path-abempty (hier and relative)
  92. $this->path = $segments_encoder->encode($this->path);
  93. } elseif ($this->path !== '' && $this->path[0] === '/') {
  94. // path-absolute (hier and relative)
  95. if (strlen($this->path) >= 2 && $this->path[1] === '/') {
  96. // This shouldn't ever happen!
  97. $this->path = '';
  98. } else {
  99. $this->path = $segments_encoder->encode($this->path);
  100. }
  101. } elseif (!is_null($this->scheme) && $this->path !== '') {
  102. // path-rootless (hier)
  103. // Short circuit evaluation means we don't need to check nz
  104. $this->path = $segments_encoder->encode($this->path);
  105. } elseif (is_null($this->scheme) && $this->path !== '') {
  106. // path-noscheme (relative)
  107. // (once again, not checking nz)
  108. $segment_nc_encoder = new HTMLPurifier_PercentEncoder($chars_sub_delims . '@');
  109. $c = strpos($this->path, '/');
  110. if ($c !== false) {
  111. $this->path =
  112. $segment_nc_encoder->encode(substr($this->path, 0, $c)) .
  113. $segments_encoder->encode(substr($this->path, $c));
  114. } else {
  115. $this->path = $segment_nc_encoder->encode($this->path);
  116. }
  117. } else {
  118. // path-empty (hier and relative)
  119. $this->path = ''; // just to be safe
  120. }
  121. // qf = query and fragment
  122. $qf_encoder = new HTMLPurifier_PercentEncoder($chars_pchar . '/?');
  123. if (!is_null($this->query)) {
  124. $this->query = $qf_encoder->encode($this->query);
  125. }
  126. if (!is_null($this->fragment)) {
  127. $this->fragment = $qf_encoder->encode($this->fragment);
  128. }
  129. return true;
  130. }
  131. /**
  132. * Convert URI back to string
  133. * @return String URI appropriate for output
  134. */
  135. function toString() {
  136. // reconstruct authority
  137. $authority = null;
  138. if (!is_null($this->host)) {
  139. $authority = '';
  140. if(!is_null($this->userinfo)) $authority .= $this->userinfo . '@';
  141. $authority .= $this->host;
  142. if(!is_null($this->port)) $authority .= ':' . $this->port;
  143. }
  144. // reconstruct the result
  145. $result = '';
  146. if (!is_null($this->scheme)) $result .= $this->scheme . ':';
  147. if (!is_null($authority)) $result .= '//' . $authority;
  148. $result .= $this->path;
  149. if (!is_null($this->query)) $result .= '?' . $this->query;
  150. if (!is_null($this->fragment)) $result .= '#' . $this->fragment;
  151. return $result;
  152. }
  153. /**
  154. * Returns a copy of the URI object
  155. */
  156. function copy() {
  157. return unserialize(serialize($this));
  158. }
  159. }