= 2) { $scheme = $stream[0] . '://'; $path = $stream[1]; } $path = trim($path); // 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. if (($ds == '\\') && ($path[0] == '\\') && ($path[1] == '\\')) { $path = '\\' . preg_replace('#[/\\\\]+#', $ds, $path); } else { $path = preg_replace('#[/\\\\]+#', $ds, $path); } return $scheme . $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 1.0 */ public static function isOwner($path) { $tmp = md5(random_bytes(16)); $ssp = ini_get('session.save_path'); // Try to find a writable directory $dir = is_writable('/tmp') ? '/tmp' : false; $dir = !$dir && is_writable('.') ? '.' : $dir; $dir = !$dir && is_writable($ssp) ? $ssp : $dir; if ($dir) { $test = $dir . '/' . $tmp; // Create the test file $blank = ''; File::write($test, $blank, false); // Test ownership $return = fileowner($test) === fileowner($path); // Delete the test file File::delete($test); return $return; } return false; } /** * Searches the directory paths for a given file. * * @param mixed $paths A path string or array of path strings to search in * @param string $file The file name to look for. * * @return string|boolean 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 1.0 */ 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; } /** * Resolves /./, /../ and multiple / in a string and returns the resulting absolute path, inspired by Flysystem * Removes trailing slashes * * @param string $path A path to resolve * * @return string The resolved path * * @since 1.6.0 */ public static function resolve($path) { $path = static::clean($path); // Save start character for absolute path $startCharacter = ($path[0] === DIRECTORY_SEPARATOR) ? DIRECTORY_SEPARATOR : ''; $parts = array(); foreach (explode(DIRECTORY_SEPARATOR, $path) as $part) { switch ($part) { case '': case '.': break; case '..': if (empty($parts)) { throw new FilesystemException('Path is outside of the defined root'); } array_pop($parts); break; default: $parts[] = $part; break; } } return $startCharacter . implode(DIRECTORY_SEPARATOR, $parts); } /** * Remove all references to root directory path and the system tmp path from a message * * @param string $message The message to be cleaned * @param string $rootDirectory Optional root directory, defaults to JPATH_ROOT * * @return string * @since 2.0.1 */ public static function removeRoot($message, $rootDirectory = null) { if (empty($rootDirectory)) { $rootDirectory = JPATH_ROOT; } $makePattern = static function ($dir) { return '~' . str_replace('~', '\\~', preg_replace('~[/\\\\]+~', '.',$dir)) . '~'; }; $replacements = [ $makePattern(static::clean($rootDirectory)) => '[ROOT]', $makePattern(sys_get_temp_dir()) => '[TMP]', ]; return preg_replace(array_keys($replacements), array_values($replacements), $message); } }