PageRenderTime 34ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/common/libraries/plugin/htmlpurifier/library/HTMLPurifier/URIFilter/MakeAbsolute.php

https://bitbucket.org/chamilo/chamilo-dev/
PHP | 146 lines | 119 code | 8 blank | 19 comment | 31 complexity | 1faade1cf3e89caade909de2f4b135dd MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, LGPL-3.0, GPL-3.0, MIT
  1. <?php
  2. // does not support network paths
  3. class HTMLPurifier_URIFilter_MakeAbsolute extends HTMLPurifier_URIFilter
  4. {
  5. public $name = 'MakeAbsolute';
  6. protected $base;
  7. protected $basePathStack = array();
  8. public function prepare($config)
  9. {
  10. $def = $config->getDefinition('URI');
  11. $this->base = $def->base;
  12. if (is_null($this->base))
  13. {
  14. trigger_error('URI.MakeAbsolute is being ignored due to lack of value for URI.Base configuration', E_USER_WARNING);
  15. return false;
  16. }
  17. $this->base->fragment = null; // fragment is invalid for base URI
  18. $stack = explode('/', $this->base->path);
  19. array_pop($stack); // discard last segment
  20. $stack = $this->_collapseStack($stack); // do pre-parsing
  21. $this->basePathStack = $stack;
  22. return true;
  23. }
  24. public function filter(&$uri, $config, $context)
  25. {
  26. if (is_null($this->base))
  27. return true; // abort early
  28. if ($uri->path === '' && is_null($uri->scheme) && is_null($uri->host) && is_null($uri->query) && is_null($uri->fragment))
  29. {
  30. // reference to current document
  31. $uri = clone $this->base;
  32. return true;
  33. }
  34. if (! is_null($uri->scheme))
  35. {
  36. // absolute URI already: don't change
  37. if (! is_null($uri->host))
  38. return true;
  39. $scheme_obj = $uri->getSchemeObj($config, $context);
  40. if (! $scheme_obj)
  41. {
  42. // scheme not recognized
  43. return false;
  44. }
  45. if (! $scheme_obj->hierarchical)
  46. {
  47. // non-hierarchal URI with explicit scheme, don't change
  48. return true;
  49. }
  50. // special case: had a scheme but always is hierarchical and had no authority
  51. }
  52. if (! is_null($uri->host))
  53. {
  54. // network path, don't bother
  55. return true;
  56. }
  57. if ($uri->path === '')
  58. {
  59. $uri->path = $this->base->path;
  60. }
  61. elseif ($uri->path[0] !== '/')
  62. {
  63. // relative path, needs more complicated processing
  64. $stack = explode('/', $uri->path);
  65. $new_stack = array_merge($this->basePathStack, $stack);
  66. if ($new_stack[0] !== '' && ! is_null($this->base->host))
  67. {
  68. array_unshift($new_stack, '');
  69. }
  70. $new_stack = $this->_collapseStack($new_stack);
  71. $uri->path = implode('/', $new_stack);
  72. }
  73. else
  74. {
  75. // absolute path, but still we should collapse
  76. $uri->path = implode('/', $this->_collapseStack(explode('/', $uri->path)));
  77. }
  78. // re-combine
  79. $uri->scheme = $this->base->scheme;
  80. if (is_null($uri->userinfo))
  81. $uri->userinfo = $this->base->userinfo;
  82. if (is_null($uri->host))
  83. $uri->host = $this->base->host;
  84. if (is_null($uri->port))
  85. $uri->port = $this->base->port;
  86. return true;
  87. }
  88. /**
  89. * Resolve dots and double-dots in a path stack
  90. */
  91. private function _collapseStack($stack)
  92. {
  93. $result = array();
  94. $is_folder = false;
  95. for($i = 0; isset($stack[$i]); $i ++)
  96. {
  97. $is_folder = false;
  98. // absorb an internally duplicated slash
  99. if ($stack[$i] == '' && $i && isset($stack[$i + 1]))
  100. continue;
  101. if ($stack[$i] == '..')
  102. {
  103. if (! empty($result))
  104. {
  105. $segment = array_pop($result);
  106. if ($segment === '' && empty($result))
  107. {
  108. // error case: attempted to back out too far:
  109. // restore the leading slash
  110. $result[] = '';
  111. }
  112. elseif ($segment === '..')
  113. {
  114. $result[] = '..'; // cannot remove .. with ..
  115. }
  116. }
  117. else
  118. {
  119. // relative path, preserve the double-dots
  120. $result[] = '..';
  121. }
  122. $is_folder = true;
  123. continue;
  124. }
  125. if ($stack[$i] == '.')
  126. {
  127. // silently absorb
  128. $is_folder = true;
  129. continue;
  130. }
  131. $result[] = $stack[$i];
  132. }
  133. if ($is_folder)
  134. $result[] = '';
  135. return $result;
  136. }
  137. }
  138. // vim: et sw=4 sts=4