PageRenderTime 36ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/joomla/filesystem/path.php

https://bitbucket.org/pastor399/newcastleunifc
PHP | 308 lines | 162 code | 36 blank | 110 comment | 38 complexity | 1179e852c1b5c582cdf3fd51981ae4a8 MD5 | raw file
  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage FileSystem
  5. *
  6. * @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die;
  10. if (!defined('JPATH_ROOT'))
  11. {
  12. // Define a string constant for the root directory of the file system in native format
  13. define('JPATH_ROOT', JPath::clean(JPATH_SITE));
  14. }
  15. /**
  16. * A Path handling class
  17. *
  18. * @package Joomla.Platform
  19. * @subpackage FileSystem
  20. * @since 11.1
  21. */
  22. class JPath
  23. {
  24. /**
  25. * Checks if a path's permissions can be changed.
  26. *
  27. * @param string $path Path to check.
  28. *
  29. * @return boolean True if path can have mode changed.
  30. *
  31. * @since 11.1
  32. */
  33. public static function canChmod($path)
  34. {
  35. $perms = fileperms($path);
  36. if ($perms !== false)
  37. {
  38. if (@chmod($path, $perms ^ 0001))
  39. {
  40. @chmod($path, $perms);
  41. return true;
  42. }
  43. }
  44. return false;
  45. }
  46. /**
  47. * Chmods files and directories recursively to given permissions.
  48. *
  49. * @param string $path Root path to begin changing mode [without trailing slash].
  50. * @param string $filemode Octal representation of the value to change file mode to [null = no change].
  51. * @param string $foldermode Octal representation of the value to change folder mode to [null = no change].
  52. *
  53. * @return boolean True if successful [one fail means the whole operation failed].
  54. *
  55. * @since 11.1
  56. */
  57. public static function setPermissions($path, $filemode = '0644', $foldermode = '0755')
  58. {
  59. // Initialise return value
  60. $ret = true;
  61. if (is_dir($path))
  62. {
  63. $dh = opendir($path);
  64. while ($file = readdir($dh))
  65. {
  66. if ($file != '.' && $file != '..')
  67. {
  68. $fullpath = $path . '/' . $file;
  69. if (is_dir($fullpath))
  70. {
  71. if (!self::setPermissions($fullpath, $filemode, $foldermode))
  72. {
  73. $ret = false;
  74. }
  75. }
  76. else
  77. {
  78. if (isset($filemode))
  79. {
  80. if (!@ chmod($fullpath, octdec($filemode)))
  81. {
  82. $ret = false;
  83. }
  84. }
  85. }
  86. }
  87. }
  88. closedir($dh);
  89. if (isset($foldermode))
  90. {
  91. if (!@ chmod($path, octdec($foldermode)))
  92. {
  93. $ret = false;
  94. }
  95. }
  96. }
  97. else
  98. {
  99. if (isset($filemode))
  100. {
  101. $ret = @ chmod($path, octdec($filemode));
  102. }
  103. }
  104. return $ret;
  105. }
  106. /**
  107. * Get the permissions of the file/folder at a give path.
  108. *
  109. * @param string $path The path of a file/folder.
  110. *
  111. * @return string Filesystem permissions.
  112. *
  113. * @since 11.1
  114. */
  115. public static function getPermissions($path)
  116. {
  117. $path = self::clean($path);
  118. $mode = @ decoct(@ fileperms($path) & 0777);
  119. if (strlen($mode) < 3)
  120. {
  121. return '---------';
  122. }
  123. $parsed_mode = '';
  124. for ($i = 0; $i < 3; $i++)
  125. {
  126. // Read
  127. $parsed_mode .= ($mode{$i} & 04) ? "r" : "-";
  128. // Write
  129. $parsed_mode .= ($mode{$i} & 02) ? "w" : "-";
  130. // Execute
  131. $parsed_mode .= ($mode{$i} & 01) ? "x" : "-";
  132. }
  133. return $parsed_mode;
  134. }
  135. /**
  136. * Checks for snooping outside of the file system root.
  137. *
  138. * @param string $path A file system path to check.
  139. * @param string $ds Directory separator (optional).
  140. *
  141. * @return string A cleaned version of the path or exit on error.
  142. *
  143. * @since 11.1
  144. * @throws Exception
  145. */
  146. public static function check($path, $ds = DIRECTORY_SEPARATOR)
  147. {
  148. if (strpos($path, '..') !== false)
  149. {
  150. // Don't translate
  151. throw new Exception('JPath::check Use of relative paths not permitted', 20);
  152. }
  153. $path = self::clean($path);
  154. if ((JPATH_ROOT != '') && strpos($path, self::clean(JPATH_ROOT)) !== 0)
  155. {
  156. throw new Exception('JPath::check Snooping out of bounds @ ' . $path, 20);
  157. }
  158. return $path;
  159. }
  160. /**
  161. * Function to strip additional / or \ in a path name.
  162. *
  163. * @param string $path The path to clean.
  164. * @param string $ds Directory separator (optional).
  165. *
  166. * @return string The cleaned path.
  167. *
  168. * @since 11.1
  169. * @throws UnexpectedValueException
  170. */
  171. public static function clean($path, $ds = DIRECTORY_SEPARATOR)
  172. {
  173. if (!is_string($path) && !empty($path))
  174. {
  175. throw new UnexpectedValueException('JPath::clean: $path is not a string.');
  176. }
  177. $path = trim($path);
  178. if (empty($path))
  179. {
  180. $path = JPATH_ROOT;
  181. }
  182. // Remove double slashes and backslashes and convert all slashes and backslashes to DIRECTORY_SEPARATOR
  183. // If dealing with a UNC path don't forget to prepend the path with a backslash.
  184. elseif (($ds == '\\') && ($path[0] == '\\' ) && ( $path[1] == '\\' ))
  185. {
  186. $path = "\\" . preg_replace('#[/\\\\]+#', $ds, $path);
  187. }
  188. else
  189. {
  190. $path = preg_replace('#[/\\\\]+#', $ds, $path);
  191. }
  192. return $path;
  193. }
  194. /**
  195. * Method to determine if script owns the path.
  196. *
  197. * @param string $path Path to check ownership.
  198. *
  199. * @return boolean True if the php script owns the path passed.
  200. *
  201. * @since 11.1
  202. */
  203. public static function isOwner($path)
  204. {
  205. jimport('joomla.filesystem.file');
  206. $tmp = md5(mt_rand());
  207. $ssp = ini_get('session.save_path');
  208. $jtp = JPATH_SITE . '/tmp';
  209. // Try to find a writable directory
  210. $dir = is_writable('/tmp') ? '/tmp' : false;
  211. $dir = (!$dir && is_writable($ssp)) ? $ssp : false;
  212. $dir = (!$dir && is_writable($jtp)) ? $jtp : false;
  213. if ($dir)
  214. {
  215. $test = $dir . '/' . $tmp;
  216. // Create the test file
  217. $blank = '';
  218. JFile::write($test, $blank, false);
  219. // Test ownership
  220. $return = (fileowner($test) == fileowner($path));
  221. // Delete the test file
  222. JFile::delete($test);
  223. return $return;
  224. }
  225. return false;
  226. }
  227. /**
  228. * Searches the directory paths for a given file.
  229. *
  230. * @param mixed $paths An path string or array of path strings to search in
  231. * @param string $file The file name to look for.
  232. *
  233. * @return mixed The full path and file name for the target file, or boolean false if the file is not found in any of the paths.
  234. *
  235. * @since 11.1
  236. */
  237. public static function find($paths, $file)
  238. {
  239. // Force to array
  240. if (!is_array($paths) && !($paths instanceof Iterator))
  241. {
  242. settype($paths, 'array');
  243. }
  244. // Start looping through the path set
  245. foreach ($paths as $path)
  246. {
  247. // Get the path to the file
  248. $fullname = $path . '/' . $file;
  249. // Is the path based on a stream?
  250. if (strpos($path, '://') === false)
  251. {
  252. // Not a stream, so do a realpath() to avoid directory
  253. // traversal attempts on the local file system.
  254. // Needed for substr() later
  255. $path = realpath($path);
  256. $fullname = realpath($fullname);
  257. }
  258. /*
  259. * The substr() check added to make sure that the realpath()
  260. * results in a directory registered so that
  261. * non-registered directories are not accessible via directory
  262. * traversal attempts.
  263. */
  264. if (file_exists($fullname) && substr($fullname, 0, strlen($path)) == $path)
  265. {
  266. return $fullname;
  267. }
  268. }
  269. // Could not find the file in the set of paths
  270. return false;
  271. }
  272. }