You've already forked joomla_test
							
							
		
			
				
	
	
		
			309 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			309 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * @package     Joomla.Platform
 | |
|  * @subpackage  FileSystem
 | |
|  *
 | |
|  * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
 | |
|  * @license     GNU General Public License version 2 or later; see LICENSE
 | |
|  */
 | |
| 
 | |
| defined('JPATH_PLATFORM') or die;
 | |
| 
 | |
| if (!defined('JPATH_ROOT'))
 | |
| {
 | |
| 	// Define a string constant for the root directory of the file system in native format
 | |
| 	define('JPATH_ROOT', JPath::clean(JPATH_SITE));
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * A Path handling class
 | |
|  *
 | |
|  * @package     Joomla.Platform
 | |
|  * @subpackage  FileSystem
 | |
|  * @since       11.1
 | |
|  */
 | |
| class JPath
 | |
| {
 | |
| 	/**
 | |
| 	 * Checks if a path's permissions can be changed.
 | |
| 	 *
 | |
| 	 * @param   string  $path  Path to check.
 | |
| 	 *
 | |
| 	 * @return  boolean  True if path can have mode changed.
 | |
| 	 *
 | |
| 	 * @since   11.1
 | |
| 	 */
 | |
| 	public static function canChmod($path)
 | |
| 	{
 | |
| 		$perms = fileperms($path);
 | |
| 		if ($perms !== false)
 | |
| 		{
 | |
| 			if (@chmod($path, $perms ^ 0001))
 | |
| 			{
 | |
| 				@chmod($path, $perms);
 | |
| 				return true;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Chmods files and directories recursively to given permissions.
 | |
| 	 *
 | |
| 	 * @param   string  $path        Root path to begin changing mode [without trailing slash].
 | |
| 	 * @param   string  $filemode    Octal representation of the value to change file mode to [null = no change].
 | |
| 	 * @param   string  $foldermode  Octal representation of the value to change folder mode to [null = no change].
 | |
| 	 *
 | |
| 	 * @return  boolean  True if successful [one fail means the whole operation failed].
 | |
| 	 *
 | |
| 	 * @since   11.1
 | |
| 	 */
 | |
| 	public static function setPermissions($path, $filemode = '0644', $foldermode = '0755')
 | |
| 	{
 | |
| 		// Initialise return value
 | |
| 		$ret = true;
 | |
| 
 | |
| 		if (is_dir($path))
 | |
| 		{
 | |
| 			$dh = opendir($path);
 | |
| 
 | |
| 			while ($file = readdir($dh))
 | |
| 			{
 | |
| 				if ($file != '.' && $file != '..')
 | |
| 				{
 | |
| 					$fullpath = $path . '/' . $file;
 | |
| 					if (is_dir($fullpath))
 | |
| 					{
 | |
| 						if (!self::setPermissions($fullpath, $filemode, $foldermode))
 | |
| 						{
 | |
| 							$ret = false;
 | |
| 						}
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						if (isset($filemode))
 | |
| 						{
 | |
| 							if (!@ chmod($fullpath, octdec($filemode)))
 | |
| 							{
 | |
| 								$ret = false;
 | |
| 							}
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			closedir($dh);
 | |
| 			if (isset($foldermode))
 | |
| 			{
 | |
| 				if (!@ chmod($path, octdec($foldermode)))
 | |
| 				{
 | |
| 					$ret = false;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			if (isset($filemode))
 | |
| 			{
 | |
| 				$ret = @ chmod($path, octdec($filemode));
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return $ret;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Get the permissions of the file/folder at a give path.
 | |
| 	 *
 | |
| 	 * @param   string  $path  The path of a file/folder.
 | |
| 	 *
 | |
| 	 * @return  string  Filesystem permissions.
 | |
| 	 *
 | |
| 	 * @since   11.1
 | |
| 	 */
 | |
| 	public static function getPermissions($path)
 | |
| 	{
 | |
| 		$path = self::clean($path);
 | |
| 		$mode = @ decoct(@ fileperms($path) & 0777);
 | |
| 
 | |
| 		if (strlen($mode) < 3)
 | |
| 		{
 | |
| 			return '---------';
 | |
| 		}
 | |
| 
 | |
| 		$parsed_mode = '';
 | |
| 		for ($i = 0; $i < 3; $i++)
 | |
| 		{
 | |
| 			// Read
 | |
| 			$parsed_mode .= ($mode{$i} & 04) ? "r" : "-";
 | |
| 
 | |
| 			// Write
 | |
| 			$parsed_mode .= ($mode{$i} & 02) ? "w" : "-";
 | |
| 
 | |
| 			// Execute
 | |
| 			$parsed_mode .= ($mode{$i} & 01) ? "x" : "-";
 | |
| 		}
 | |
| 
 | |
| 		return $parsed_mode;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Checks for snooping outside of the file system root.
 | |
| 	 *
 | |
| 	 * @param   string  $path  A file system path to check.
 | |
| 	 * @param   string  $ds    Directory separator (optional).
 | |
| 	 *
 | |
| 	 * @return  string  A cleaned version of the path or exit on error.
 | |
| 	 *
 | |
| 	 * @since   11.1
 | |
| 	 * @throws  Exception
 | |
| 	 */
 | |
| 	public static function check($path, $ds = DIRECTORY_SEPARATOR)
 | |
| 	{
 | |
| 		if (strpos($path, '..') !== false)
 | |
| 		{
 | |
| 			// Don't translate
 | |
| 			throw new Exception('JPath::check Use of relative paths not permitted', 20);
 | |
| 		}
 | |
| 
 | |
| 		$path = self::clean($path);
 | |
| 		if ((JPATH_ROOT != '') && strpos($path, self::clean(JPATH_ROOT)) !== 0)
 | |
| 		{
 | |
| 			throw new Exception('JPath::check Snooping out of bounds @ ' . $path, 20);
 | |
| 		}
 | |
| 
 | |
| 		return $path;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Function to strip additional / or \ in a path name.
 | |
| 	 *
 | |
| 	 * @param   string  $path  The path to clean.
 | |
| 	 * @param   string  $ds    Directory separator (optional).
 | |
| 	 *
 | |
| 	 * @return  string  The cleaned path.
 | |
| 	 *
 | |
| 	 * @since   11.1
 | |
| 	 * @throws  UnexpectedValueException
 | |
| 	 */
 | |
| 	public static function clean($path, $ds = DIRECTORY_SEPARATOR)
 | |
| 	{
 | |
| 		if (!is_string($path) && !empty($path))
 | |
| 		{
 | |
| 			throw new UnexpectedValueException('JPath::clean: $path is not a string.');
 | |
| 		}
 | |
| 
 | |
| 		$path = trim($path);
 | |
| 
 | |
| 		if (empty($path))
 | |
| 		{
 | |
| 			$path = JPATH_ROOT;
 | |
| 		}
 | |
| 		// Remove double slashes and backslashes and convert all slashes and backslashes to DIRECTORY_SEPARATOR
 | |
| 		// If dealing with a UNC path don't forget to prepend the path with a backslash.
 | |
| 		elseif (($ds == '\\') && ($path[0] == '\\' ) && ( $path[1] == '\\' ))
 | |
| 		{
 | |
| 			$path = "\\" . preg_replace('#[/\\\\]+#', $ds, $path);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			$path = preg_replace('#[/\\\\]+#', $ds, $path);
 | |
| 		}
 | |
| 
 | |
| 		return $path;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Method to determine if script owns the path.
 | |
| 	 *
 | |
| 	 * @param   string  $path  Path to check ownership.
 | |
| 	 *
 | |
| 	 * @return  boolean  True if the php script owns the path passed.
 | |
| 	 *
 | |
| 	 * @since   11.1
 | |
| 	 */
 | |
| 	public static function isOwner($path)
 | |
| 	{
 | |
| 		jimport('joomla.filesystem.file');
 | |
| 
 | |
| 		$tmp = md5(mt_rand());
 | |
| 		$ssp = ini_get('session.save_path');
 | |
| 		$jtp = JPATH_SITE . '/tmp';
 | |
| 
 | |
| 		// Try to find a writable directory
 | |
| 		$dir = is_writable('/tmp') ? '/tmp' : false;
 | |
| 		$dir = (!$dir && is_writable($ssp)) ? $ssp : false;
 | |
| 		$dir = (!$dir && is_writable($jtp)) ? $jtp : false;
 | |
| 
 | |
| 		if ($dir)
 | |
| 		{
 | |
| 			$test = $dir . '/' . $tmp;
 | |
| 
 | |
| 			// Create the test file
 | |
| 			$blank = '';
 | |
| 			JFile::write($test, $blank, false);
 | |
| 
 | |
| 			// Test ownership
 | |
| 			$return = (fileowner($test) == fileowner($path));
 | |
| 
 | |
| 			// Delete the test file
 | |
| 			JFile::delete($test);
 | |
| 
 | |
| 			return $return;
 | |
| 		}
 | |
| 
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Searches the directory paths for a given file.
 | |
| 	 *
 | |
| 	 * @param   mixed   $paths  An path string or array of path strings to search in
 | |
| 	 * @param   string  $file   The file name to look for.
 | |
| 	 *
 | |
| 	 * @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.
 | |
| 	 *
 | |
| 	 * @since   11.1
 | |
| 	 */
 | |
| 	public static function find($paths, $file)
 | |
| 	{
 | |
| 		// Force to array
 | |
| 		if (!is_array($paths) && !($paths instanceof Iterator))
 | |
| 		{
 | |
| 			settype($paths, 'array');
 | |
| 		}
 | |
| 
 | |
| 		// Start looping through the path set
 | |
| 		foreach ($paths as $path)
 | |
| 		{
 | |
| 			// Get the path to the file
 | |
| 			$fullname = $path . '/' . $file;
 | |
| 
 | |
| 			// Is the path based on a stream?
 | |
| 			if (strpos($path, '://') === false)
 | |
| 			{
 | |
| 				// Not a stream, so do a realpath() to avoid directory
 | |
| 				// traversal attempts on the local file system.
 | |
| 
 | |
| 				// Needed for substr() later
 | |
| 				$path = realpath($path);
 | |
| 				$fullname = realpath($fullname);
 | |
| 			}
 | |
| 
 | |
| 			/*
 | |
| 			 * The substr() check added to make sure that the realpath()
 | |
| 			 * results in a directory registered so that
 | |
| 			 * non-registered directories are not accessible via directory
 | |
| 			 * traversal attempts.
 | |
| 			 */
 | |
| 			if (file_exists($fullname) && substr($fullname, 0, strlen($path)) == $path)
 | |
| 			{
 | |
| 				return $fullname;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		// Could not find the file in the set of paths
 | |
| 		return false;
 | |
| 	}
 | |
| }
 | 
