X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2Flibs%2Ffilebackend%2FFSFileBackend.php;h=f23e5cc888f6bbc6fef44f05af256d324052114e;hp=593e617fe60c023ee0e047b926e484e4146a7478;hb=e390198c4e4be7632b01173e42050061f1cc346a;hpb=ba2e62391743f6dbe767651bfbb50e7ba13701ce diff --git a/includes/libs/filebackend/FSFileBackend.php b/includes/libs/filebackend/FSFileBackend.php index 593e617fe6..f23e5cc888 100644 --- a/includes/libs/filebackend/FSFileBackend.php +++ b/includes/libs/filebackend/FSFileBackend.php @@ -124,7 +124,7 @@ class FSFileBackend extends FileBackendStore { // See https://www.php.net/manual/en/migration71.windows-support.php return 0; } else { - return FileBackend::ATTR_UNICODE_PATHS; + return self::ATTR_UNICODE_PATHS; } } @@ -137,7 +137,7 @@ class FSFileBackend extends FileBackendStore { } } - return null; + return null; // invalid } /** @@ -228,7 +228,7 @@ class FSFileBackend extends FileBackendStore { } if ( !empty( $params['async'] ) ) { // deferred - $tempFile = TempFSFile::factory( 'create_', 'tmp', $this->tmpDirectory ); + $tempFile = $this->tmpFileFactory->newTempFSFile( 'create_', 'tmp' ); if ( !$tempFile ) { $status->fatal( 'backend-fail-create', $params['dst'] ); @@ -576,25 +576,23 @@ class FSFileBackend extends FileBackendStore { protected function doGetFileStat( array $params ) { $source = $this->resolveToFSPath( $params['src'] ); if ( $source === null ) { - return false; // invalid storage path + return self::$RES_ERROR; // 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 ) { + if ( is_array( $stat ) ) { $ct = new ConvertibleTimestamp( $stat['mtime'] ); return [ 'mtime' => $ct->getTimestamp( TS_MW ), 'size' => $stat['size'] ]; - } elseif ( !$hadError ) { - return false; // file does not exist - } else { - return null; // failure } + + return $hadError ? self::$RES_ERROR : self::$RES_ABSENT; } protected function doClearCache( array $paths = null ) { @@ -610,7 +608,7 @@ class FSFileBackend extends FileBackendStore { $exists = is_dir( $dir ); $hadError = $this->untrapWarnings(); - return $hadError ? null : $exists; + return $hadError ? self::$RES_ERROR : $exists; } /** @@ -624,18 +622,27 @@ class FSFileBackend extends FileBackendStore { list( , $shortCont, ) = FileBackend::splitStoragePath( $params['dir'] ); $contRoot = $this->containerFSRoot( $shortCont, $fullCont ); // must be valid $dir = ( $dirRel != '' ) ? "{$contRoot}/{$dirRel}" : $contRoot; + + $this->trapWarnings(); // don't trust 'false' if there were errors $exists = is_dir( $dir ); - if ( !$exists ) { - $this->logger->warning( __METHOD__ . "() given directory does not exist: '$dir'\n" ); + $isReadable = $exists ? is_readable( $dir ) : false; + $hadError = $this->untrapWarnings(); - return []; // nothing under this dir - } elseif ( !is_readable( $dir ) ) { - $this->logger->warning( __METHOD__ . "() given directory is unreadable: '$dir'\n" ); + if ( $isReadable ) { + return new FSFileBackendDirList( $dir, $params ); + } elseif ( $exists ) { + $this->logger->warning( __METHOD__ . ": given directory is unreadable: '$dir'" ); - return null; // bad permissions? - } + return self::$RES_ERROR; // bad permissions? + } elseif ( $hadError ) { + $this->logger->warning( __METHOD__ . ": given directory was unreachable: '$dir'" ); - return new FSFileBackendDirList( $dir, $params ); + return self::$RES_ERROR; + } else { + $this->logger->info( __METHOD__ . ": given directory does not exist: '$dir'" ); + + return []; // nothing under this dir + } } /** @@ -649,18 +656,27 @@ class FSFileBackend extends FileBackendStore { list( , $shortCont, ) = FileBackend::splitStoragePath( $params['dir'] ); $contRoot = $this->containerFSRoot( $shortCont, $fullCont ); // must be valid $dir = ( $dirRel != '' ) ? "{$contRoot}/{$dirRel}" : $contRoot; + + $this->trapWarnings(); // don't trust 'false' if there were errors $exists = is_dir( $dir ); - if ( !$exists ) { - $this->logger->warning( __METHOD__ . "() given directory does not exist: '$dir'\n" ); + $isReadable = $exists ? is_readable( $dir ) : false; + $hadError = $this->untrapWarnings(); - return []; // nothing under this dir - } elseif ( !is_readable( $dir ) ) { - $this->logger->warning( __METHOD__ . "() given directory is unreadable: '$dir'\n" ); + if ( $exists && $isReadable ) { + return new FSFileBackendFileList( $dir, $params ); + } elseif ( $exists ) { + $this->logger->warning( __METHOD__ . ": given directory is unreadable: '$dir'\n" ); - return null; // bad permissions? - } + return self::$RES_ERROR; // bad permissions? + } elseif ( $hadError ) { + $this->logger->warning( __METHOD__ . ": given directory was unreachable: '$dir'\n" ); - return new FSFileBackendFileList( $dir, $params ); + return self::$RES_ERROR; + } else { + $this->logger->info( __METHOD__ . ": given directory does not exist: '$dir'\n" ); + + return []; // nothing under this dir + } } protected function doGetLocalReferenceMulti( array $params ) { @@ -668,10 +684,21 @@ class FSFileBackend extends FileBackendStore { foreach ( $params['srcs'] as $src ) { $source = $this->resolveToFSPath( $src ); - if ( $source === null || !is_file( $source ) ) { - $fsFiles[$src] = null; // invalid path or file does not exist - } else { + if ( $source === null ) { + $fsFiles[$src] = self::$RES_ERROR; // invalid path + continue; + } + + $this->trapWarnings(); // don't trust 'false' if there were errors + $isFile = is_file( $source ); // regular files only + $hadError = $this->untrapWarnings(); + + if ( $isFile ) { $fsFiles[$src] = new FSFile( $source ); + } elseif ( $hadError ) { + $fsFiles[$src] = self::$RES_ERROR; + } else { + $fsFiles[$src] = self::$RES_ABSENT; } } @@ -684,26 +711,31 @@ class FSFileBackend extends FileBackendStore { foreach ( $params['srcs'] as $src ) { $source = $this->resolveToFSPath( $src ); if ( $source === null ) { - $tmpFiles[$src] = null; // invalid path + $tmpFiles[$src] = self::$RES_ERROR; // invalid path + continue; + } + // Create a new temporary file with the same extension... + $ext = FileBackend::extensionFromPath( $src ); + $tmpFile = $this->tmpFileFactory->newTempFSFile( 'localcopy_', $ext ); + if ( !$tmpFile ) { + $tmpFiles[$src] = self::$RES_ERROR; + continue; + } + + $tmpPath = $tmpFile->getPath(); + // Copy the source file over the temp file + $this->trapWarnings(); + $isFile = is_file( $source ); // regular files only + $copySuccess = $isFile ? copy( $source, $tmpPath ) : false; + $hadError = $this->untrapWarnings(); + + if ( $copySuccess ) { + $this->chmod( $tmpPath ); + $tmpFiles[$src] = $tmpFile; + } elseif ( $hadError ) { + $tmpFiles[$src] = self::$RES_ERROR; // copy failed } else { - // Create a new temporary file with the same extension... - $ext = FileBackend::extensionFromPath( $src ); - $tmpFile = TempFSFile::factory( 'localcopy_', $ext, $this->tmpDirectory ); - if ( !$tmpFile ) { - $tmpFiles[$src] = null; - } else { - $tmpPath = $tmpFile->getPath(); - // Copy the source file over the temp file - $this->trapWarnings(); - $ok = copy( $source, $tmpPath ); - $this->untrapWarnings(); - if ( !$ok ) { - $tmpFiles[$src] = null; - } else { - $this->chmod( $tmpPath ); - $tmpFiles[$src] = $tmpFile; - } - } + $tmpFiles[$src] = self::$RES_ABSENT; } } @@ -795,8 +827,16 @@ class FSFileBackend extends FileBackendStore { * Listen for E_WARNING errors and track whether any happen */ protected function trapWarnings() { - $this->hadWarningErrors[] = false; // push to stack - set_error_handler( [ $this, 'handleWarning' ], E_WARNING ); + // push to stack + $this->hadWarningErrors[] = false; + set_error_handler( function ( $errno, $errstr ) { + // more detailed error logging + $this->logger->error( $errstr ); + $this->hadWarningErrors[count( $this->hadWarningErrors ) - 1] = true; + + // suppress from PHP handler + return true; + }, E_WARNING ); } /** @@ -805,20 +845,9 @@ class FSFileBackend extends FileBackendStore { * @return bool */ protected function untrapWarnings() { - restore_error_handler(); // restore previous handler - return array_pop( $this->hadWarningErrors ); // pop from stack - } - - /** - * @param int $errno - * @param string $errstr - * @return bool - * @private - */ - public function handleWarning( $errno, $errstr ) { - $this->logger->error( $errstr ); // more detailed error logging - $this->hadWarningErrors[count( $this->hadWarningErrors ) - 1] = true; - - return true; // suppress from PHP handler + // restore previous handler + restore_error_handler(); + // pop from stack + return array_pop( $this->hadWarningErrors ); } }