From 63601400e476c6cf43d985f3e7b9864681695ed4 Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Fri, 18 Jan 2013 16:46:04 +0100 Subject: Update to MediaWiki 1.20.2 this update includes: * adjusted Arch Linux skin * updated FluxBBAuthPlugin * patch for https://bugzilla.wikimedia.org/show_bug.cgi?id=44024 --- includes/filerepo/backend/FSFileBackend.php | 600 ---------------------------- 1 file changed, 600 deletions(-) delete mode 100644 includes/filerepo/backend/FSFileBackend.php (limited to 'includes/filerepo/backend/FSFileBackend.php') diff --git a/includes/filerepo/backend/FSFileBackend.php b/includes/filerepo/backend/FSFileBackend.php deleted file mode 100644 index 1a4c44ad..00000000 --- a/includes/filerepo/backend/FSFileBackend.php +++ /dev/null @@ -1,600 +0,0 @@ -basePath = rtrim( $config['basePath'], '/' ); // remove trailing slash - } else { - $this->basePath = null; // none; containers must have explicit paths - } - - if ( isset( $config['containerPaths'] ) ) { - $this->containerPaths = (array)$config['containerPaths']; - foreach ( $this->containerPaths as &$path ) { - $path = rtrim( $path, '/' ); // remove trailing slash - } - } - - $this->fileMode = isset( $config['fileMode'] ) - ? $config['fileMode'] - : 0644; - } - - /** - * @see FileBackendStore::resolveContainerPath() - */ - protected function resolveContainerPath( $container, $relStoragePath ) { - // Check that container has a root directory - if ( isset( $this->containerPaths[$container] ) || isset( $this->basePath ) ) { - // Check for sane relative paths (assume the base paths are OK) - if ( $this->isLegalRelPath( $relStoragePath ) ) { - return $relStoragePath; - } - } - return null; - } - - /** - * Sanity check a relative file system path for validity - * - * @param $path string Normalized relative path - * @return bool - */ - protected function isLegalRelPath( $path ) { - // Check for file names longer than 255 chars - if ( preg_match( '![^/]{256}!', $path ) ) { // ext3/NTFS - return false; - } - if ( wfIsWindows() ) { // NTFS - return !preg_match( '![:*?"<>|]!', $path ); - } else { - return true; - } - } - - /** - * Given the short (unresolved) and full (resolved) name of - * a container, return the file system path of the container. - * - * @param $shortCont string - * @param $fullCont string - * @return string|null - */ - protected function containerFSRoot( $shortCont, $fullCont ) { - if ( isset( $this->containerPaths[$shortCont] ) ) { - return $this->containerPaths[$shortCont]; - } elseif ( isset( $this->basePath ) ) { - return "{$this->basePath}/{$fullCont}"; - } - return null; // no container base path defined - } - - /** - * Get the absolute file system path for a storage path - * - * @param $storagePath string Storage path - * @return string|null - */ - protected function resolveToFSPath( $storagePath ) { - list( $fullCont, $relPath ) = $this->resolveStoragePathReal( $storagePath ); - if ( $relPath === null ) { - return null; // invalid - } - list( $b, $shortCont, $r ) = FileBackend::splitStoragePath( $storagePath ); - $fsPath = $this->containerFSRoot( $shortCont, $fullCont ); // must be valid - if ( $relPath != '' ) { - $fsPath .= "/{$relPath}"; - } - return $fsPath; - } - - /** - * @see FileBackendStore::isPathUsableInternal() - */ - public function isPathUsableInternal( $storagePath ) { - $fsPath = $this->resolveToFSPath( $storagePath ); - if ( $fsPath === null ) { - return false; // invalid - } - $parentDir = dirname( $fsPath ); - - if ( file_exists( $fsPath ) ) { - $ok = is_file( $fsPath ) && is_writable( $fsPath ); - } else { - $ok = is_dir( $parentDir ) && is_writable( $parentDir ); - } - - return $ok; - } - - /** - * @see FileBackendStore::doStoreInternal() - */ - protected function doStoreInternal( array $params ) { - $status = Status::newGood(); - - $dest = $this->resolveToFSPath( $params['dst'] ); - if ( $dest === null ) { - $status->fatal( 'backend-fail-invalidpath', $params['dst'] ); - return $status; - } - - if ( file_exists( $dest ) ) { - if ( !empty( $params['overwrite'] ) ) { - $ok = unlink( $dest ); - if ( !$ok ) { - $status->fatal( 'backend-fail-delete', $params['dst'] ); - return $status; - } - } else { - $status->fatal( 'backend-fail-alreadyexists', $params['dst'] ); - return $status; - } - } - - $ok = copy( $params['src'], $dest ); - if ( !$ok ) { - $status->fatal( 'backend-fail-store', $params['src'], $params['dst'] ); - return $status; - } - - $this->chmod( $dest ); - - return $status; - } - - /** - * @see FileBackendStore::doCopyInternal() - */ - protected function doCopyInternal( array $params ) { - $status = Status::newGood(); - - $source = $this->resolveToFSPath( $params['src'] ); - if ( $source === null ) { - $status->fatal( 'backend-fail-invalidpath', $params['src'] ); - return $status; - } - - $dest = $this->resolveToFSPath( $params['dst'] ); - if ( $dest === null ) { - $status->fatal( 'backend-fail-invalidpath', $params['dst'] ); - return $status; - } - - if ( file_exists( $dest ) ) { - if ( !empty( $params['overwrite'] ) ) { - $ok = unlink( $dest ); - if ( !$ok ) { - $status->fatal( 'backend-fail-delete', $params['dst'] ); - return $status; - } - } else { - $status->fatal( 'backend-fail-alreadyexists', $params['dst'] ); - return $status; - } - } - - $ok = copy( $source, $dest ); - if ( !$ok ) { - $status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] ); - return $status; - } - - $this->chmod( $dest ); - - return $status; - } - - /** - * @see FileBackendStore::doMoveInternal() - */ - protected function doMoveInternal( array $params ) { - $status = Status::newGood(); - - $source = $this->resolveToFSPath( $params['src'] ); - if ( $source === null ) { - $status->fatal( 'backend-fail-invalidpath', $params['src'] ); - return $status; - } - - $dest = $this->resolveToFSPath( $params['dst'] ); - if ( $dest === null ) { - $status->fatal( 'backend-fail-invalidpath', $params['dst'] ); - return $status; - } - - if ( file_exists( $dest ) ) { - if ( !empty( $params['overwrite'] ) ) { - // Windows does not support moving over existing files - if ( wfIsWindows() ) { - $ok = unlink( $dest ); - if ( !$ok ) { - $status->fatal( 'backend-fail-delete', $params['dst'] ); - return $status; - } - } - } else { - $status->fatal( 'backend-fail-alreadyexists', $params['dst'] ); - return $status; - } - } - - $ok = rename( $source, $dest ); - clearstatcache(); // file no longer at source - if ( !$ok ) { - $status->fatal( 'backend-fail-move', $params['src'], $params['dst'] ); - return $status; - } - - return $status; - } - - /** - * @see FileBackendStore::doDeleteInternal() - */ - protected function doDeleteInternal( array $params ) { - $status = Status::newGood(); - - $source = $this->resolveToFSPath( $params['src'] ); - if ( $source === null ) { - $status->fatal( 'backend-fail-invalidpath', $params['src'] ); - return $status; - } - - if ( !is_file( $source ) ) { - if ( empty( $params['ignoreMissingSource'] ) ) { - $status->fatal( 'backend-fail-delete', $params['src'] ); - } - return $status; // do nothing; either OK or bad status - } - - $ok = unlink( $source ); - if ( !$ok ) { - $status->fatal( 'backend-fail-delete', $params['src'] ); - return $status; - } - - return $status; - } - - /** - * @see FileBackendStore::doCreateInternal() - */ - protected function doCreateInternal( array $params ) { - $status = Status::newGood(); - - $dest = $this->resolveToFSPath( $params['dst'] ); - if ( $dest === null ) { - $status->fatal( 'backend-fail-invalidpath', $params['dst'] ); - return $status; - } - - if ( file_exists( $dest ) ) { - if ( !empty( $params['overwrite'] ) ) { - $ok = unlink( $dest ); - if ( !$ok ) { - $status->fatal( 'backend-fail-delete', $params['dst'] ); - return $status; - } - } else { - $status->fatal( 'backend-fail-alreadyexists', $params['dst'] ); - return $status; - } - } - - $bytes = file_put_contents( $dest, $params['content'] ); - if ( $bytes === false ) { - $status->fatal( 'backend-fail-create', $params['dst'] ); - return $status; - } - - $this->chmod( $dest ); - - return $status; - } - - /** - * @see FileBackendStore::doPrepareInternal() - */ - protected function doPrepareInternal( $fullCont, $dirRel, array $params ) { - $status = Status::newGood(); - list( $b, $shortCont, $r ) = FileBackend::splitStoragePath( $params['dir'] ); - $contRoot = $this->containerFSRoot( $shortCont, $fullCont ); // must be valid - $dir = ( $dirRel != '' ) ? "{$contRoot}/{$dirRel}" : $contRoot; - if ( !wfMkdirParents( $dir ) ) { // make directory and its parents - $status->fatal( 'directorycreateerror', $params['dir'] ); - } elseif ( !is_writable( $dir ) ) { - $status->fatal( 'directoryreadonlyerror', $params['dir'] ); - } elseif ( !is_readable( $dir ) ) { - $status->fatal( 'directorynotreadableerror', $params['dir'] ); - } - return $status; - } - - /** - * @see FileBackendStore::doSecureInternal() - */ - protected function doSecureInternal( $fullCont, $dirRel, array $params ) { - $status = Status::newGood(); - list( $b, $shortCont, $r ) = FileBackend::splitStoragePath( $params['dir'] ); - $contRoot = $this->containerFSRoot( $shortCont, $fullCont ); // must be valid - $dir = ( $dirRel != '' ) ? "{$contRoot}/{$dirRel}" : $contRoot; - // Seed new directories with a blank index.html, to prevent crawling... - if ( !empty( $params['noListing'] ) && !file_exists( "{$dir}/index.html" ) ) { - $bytes = file_put_contents( "{$dir}/index.html", '' ); - if ( !$bytes ) { - $status->fatal( 'backend-fail-create', $params['dir'] . '/index.html' ); - return $status; - } - } - // Add a .htaccess file to the root of the container... - if ( !empty( $params['noAccess'] ) ) { - if ( !file_exists( "{$contRoot}/.htaccess" ) ) { - $bytes = file_put_contents( "{$contRoot}/.htaccess", "Deny from all\n" ); - if ( !$bytes ) { - $storeDir = "mwstore://{$this->name}/{$shortCont}"; - $status->fatal( 'backend-fail-create', "{$storeDir}/.htaccess" ); - return $status; - } - } - } - return $status; - } - - /** - * @see FileBackendStore::doCleanInternal() - */ - protected function doCleanInternal( $fullCont, $dirRel, array $params ) { - $status = Status::newGood(); - list( $b, $shortCont, $r ) = FileBackend::splitStoragePath( $params['dir'] ); - $contRoot = $this->containerFSRoot( $shortCont, $fullCont ); // must be valid - $dir = ( $dirRel != '' ) ? "{$contRoot}/{$dirRel}" : $contRoot; - wfSuppressWarnings(); - if ( is_dir( $dir ) ) { - rmdir( $dir ); // remove directory if empty - } - wfRestoreWarnings(); - return $status; - } - - /** - * @see FileBackendStore::doFileExists() - */ - protected function doGetFileStat( array $params ) { - $source = $this->resolveToFSPath( $params['src'] ); - if ( $source === null ) { - return false; // invalid storage path - } - - $this->trapWarnings(); // don't trust 'false' if there were errors - $stat = is_file( $source ) ? stat( $source ) : false; // regular files only - $hadError = $this->untrapWarnings(); - - if ( $stat ) { - return array( - 'mtime' => wfTimestamp( TS_MW, $stat['mtime'] ), - 'size' => $stat['size'] - ); - } elseif ( !$hadError ) { - return false; // file does not exist - } else { - return null; // failure - } - } - - /** - * @see FileBackendStore::doClearCache() - */ - protected function doClearCache( array $paths = null ) { - clearstatcache(); // clear the PHP file stat cache - } - - /** - * @see FileBackendStore::getFileListInternal() - */ - public function getFileListInternal( $fullCont, $dirRel, array $params ) { - list( $b, $shortCont, $r ) = FileBackend::splitStoragePath( $params['dir'] ); - $contRoot = $this->containerFSRoot( $shortCont, $fullCont ); // must be valid - $dir = ( $dirRel != '' ) ? "{$contRoot}/{$dirRel}" : $contRoot; - $exists = is_dir( $dir ); - if ( !$exists ) { - wfDebug( __METHOD__ . "() given directory does not exist: '$dir'\n" ); - return array(); // nothing under this dir - } - $readable = is_readable( $dir ); - if ( !$readable ) { - wfDebug( __METHOD__ . "() given directory is unreadable: '$dir'\n" ); - return null; // bad permissions? - } - return new FSFileBackendFileList( $dir ); - } - - /** - * @see FileBackendStore::getLocalReference() - */ - public function getLocalReference( array $params ) { - $source = $this->resolveToFSPath( $params['src'] ); - if ( $source === null ) { - return null; - } - return new FSFile( $source ); - } - - /** - * @see FileBackendStore::getLocalCopy() - */ - public function getLocalCopy( array $params ) { - $source = $this->resolveToFSPath( $params['src'] ); - if ( $source === null ) { - return null; - } - - // Create a new temporary file with the same extension... - $ext = FileBackend::extensionFromPath( $params['src'] ); - $tmpFile = TempFSFile::factory( wfBaseName( $source ) . '_', $ext ); - if ( !$tmpFile ) { - return null; - } - $tmpPath = $tmpFile->getPath(); - - // Copy the source file over the temp file - $ok = copy( $source, $tmpPath ); - if ( !$ok ) { - return null; - } - - $this->chmod( $tmpPath ); - - return $tmpFile; - } - - /** - * Chmod a file, suppressing the warnings - * - * @param $path string Absolute file system path - * @return bool Success - */ - protected function chmod( $path ) { - wfSuppressWarnings(); - $ok = chmod( $path, $this->fileMode ); - wfRestoreWarnings(); - - return $ok; - } - - /** - * Listen for E_WARNING errors and track whether any happen - * - * @return bool - */ - protected function trapWarnings() { - $this->hadWarningErrors[] = false; // push to stack - set_error_handler( array( $this, 'handleWarning' ), E_WARNING ); - return false; // invoke normal PHP error handler - } - - /** - * Stop listening for E_WARNING errors and return true if any happened - * - * @return bool - */ - protected function untrapWarnings() { - restore_error_handler(); // restore previous handler - return array_pop( $this->hadWarningErrors ); // pop from stack - } - - private function handleWarning() { - $this->hadWarningErrors[count( $this->hadWarningErrors ) - 1] = true; - return true; // suppress from PHP handler - } -} - -/** - * Wrapper around RecursiveDirectoryIterator that catches - * exception or does any custom behavoir that we may want. - * Do not use this class from places outside FSFileBackend. - * - * @ingroup FileBackend - */ -class FSFileBackendFileList implements Iterator { - /** @var RecursiveIteratorIterator */ - protected $iter; - protected $suffixStart; // integer - protected $pos = 0; // integer - - /** - * @param $dir string file system directory - */ - public function __construct( $dir ) { - $dir = realpath( $dir ); // normalize - $this->suffixStart = strlen( $dir ) + 1; // size of "path/to/dir/" - try { - # Get an iterator that will return leaf nodes (non-directories) - if ( MWInit::classExists( 'FilesystemIterator' ) ) { // PHP >= 5.3 - # RecursiveDirectoryIterator extends FilesystemIterator. - # FilesystemIterator::SKIP_DOTS default is inconsistent in PHP 5.3.x. - $flags = FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS; - $this->iter = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator( $dir, $flags ) ); - } else { // PHP < 5.3 - # RecursiveDirectoryIterator extends DirectoryIterator - $this->iter = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator( $dir ) ); - } - } catch ( UnexpectedValueException $e ) { - $this->iter = null; // bad permissions? deleted? - } - } - - public function current() { - // Return only the relative path and normalize slashes to FileBackend-style - // Make sure to use the realpath since the suffix is based upon that - return str_replace( '\\', '/', - substr( realpath( $this->iter->current() ), $this->suffixStart ) ); - } - - public function key() { - return $this->pos; - } - - public function next() { - try { - $this->iter->next(); - } catch ( UnexpectedValueException $e ) { - $this->iter = null; - } - ++$this->pos; - } - - public function rewind() { - $this->pos = 0; - try { - $this->iter->rewind(); - } catch ( UnexpectedValueException $e ) { - $this->iter = null; - } - } - - public function valid() { - return $this->iter && $this->iter->valid(); - } -} -- cgit v1.2.3-54-g00ecf