PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/src/system/SecurityCenter/lib/vendor/htmlpurifier/HTMLPurifier/URIFilter/MakeAbsolute.php

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