From 7ccbeab5f095ba377e921e3549f3de9b112665fb Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Mon, 30 Jan 2012 08:00:19 +0000 Subject: [PATCH] * r108353: Made FileBackendMultiWrite consistency checks configurable. * Removed redundant code from r110259 and added a comment to isValidContainerName(). --- includes/filerepo/backend/FSFileBackend.php | 10 ------- includes/filerepo/backend/FileBackend.php | 1 + .../backend/FileBackendMultiWrite.php | 27 ++++++++++++++++--- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/includes/filerepo/backend/FSFileBackend.php b/includes/filerepo/backend/FSFileBackend.php index f6748c81b0..3eabd29cfe 100644 --- a/includes/filerepo/backend/FSFileBackend.php +++ b/includes/filerepo/backend/FSFileBackend.php @@ -57,16 +57,6 @@ class FSFileBackend extends FileBackendStore { : 0644; } - /** - * @see FileBackendStore::resolveContainerName() - */ - protected function resolveContainerName( $container ) { - if ( $container !== '.' ) { - return $container; // container is not a traversal - } - return null; - } - /** * @see FileBackendStore::resolveContainerPath() */ diff --git a/includes/filerepo/backend/FileBackend.php b/includes/filerepo/backend/FileBackend.php index fbae494159..53106941bc 100644 --- a/includes/filerepo/backend/FileBackend.php +++ b/includes/filerepo/backend/FileBackend.php @@ -1422,6 +1422,7 @@ abstract class FileBackendStore extends FileBackend { final protected static function isValidContainerName( $container ) { // This accounts for Swift and S3 restrictions while leaving room // for things like '.xxx' (hex shard chars) or '.seg' (segments). + // This disallows directory separators or traversal characters. // Note that matching strings URL encode to the same string; // in Swift, the length restriction is *after* URL encoding. return preg_match( '/^[a-z0-9][a-z0-9-_]{0,199}$/i', $container ); diff --git a/includes/filerepo/backend/FileBackendMultiWrite.php b/includes/filerepo/backend/FileBackendMultiWrite.php index d09462ab71..550a8af367 100644 --- a/includes/filerepo/backend/FileBackendMultiWrite.php +++ b/includes/filerepo/backend/FileBackendMultiWrite.php @@ -24,6 +24,11 @@ class FileBackendMultiWrite extends FileBackend { /** @var Array Prioritized list of FileBackendStore objects */ protected $backends = array(); // array of (backend index => backends) protected $masterIndex = -1; // integer; index of master backend + protected $syncChecks = 0; // integer bitfield + + /* Possible internal backend consistency checks */ + const CHECK_SIZE = 1; + const CHECK_TIME = 2; /** * Construct a proxy backend that consists of several internal backends. @@ -33,6 +38,9 @@ class FileBackendMultiWrite extends FileBackend { * FileBackendStore class, but with these additional settings: * 'class' : The name of the backend class * 'isMultiMaster' : This must be set for one backend. + * 'syncChecks' : Integer bitfield of internal backend sync checks to perform. + * Possible bits include self::CHECK_SIZE and self::CHECK_TIME. + * The checks are done before allowing any file operations. * @param $config Array */ public function __construct( array $config ) { @@ -61,6 +69,9 @@ class FileBackendMultiWrite extends FileBackend { if ( $this->masterIndex < 0 ) { // need backends and must have a master throw new MWException( 'No master backend defined.' ); } + $this->syncChecks = isset( $config['syncChecks'] ) + ? $config['syncChecks'] + : self::CHECK_SIZE; } /** @@ -156,6 +167,9 @@ class FileBackendMultiWrite extends FileBackend { */ public function consistencyCheck( array $paths ) { $status = Status::newGood(); + if ( $this->syncChecks == 0 ) { + return $status; // skip checks + } $mBackend = $this->backends[$this->masterIndex]; foreach ( array_unique( $paths ) as $path ) { @@ -171,13 +185,20 @@ class FileBackendMultiWrite extends FileBackend { if ( $mStat ) { // file is in master if ( !$cStat ) { // file should exist $status->fatal( 'backend-fail-synced', $path ); - } elseif ( $cStat['size'] != $mStat['size'] ) { // wrong size - $status->fatal( 'backend-fail-synced', $path ); - } else { + continue; + } + if ( $this->syncChecks & self::CHECK_SIZE ) { + if ( $cStat['size'] != $mStat['size'] ) { // wrong size + $status->fatal( 'backend-fail-synced', $path ); + continue; + } + } + if ( $this->syncChecks & self::CHECK_TIME ) { $mTs = wfTimestamp( TS_UNIX, $mStat['mtime'] ); $cTs = wfTimestamp( TS_UNIX, $cStat['mtime'] ); if ( abs( $mTs - $cTs ) > 30 ) { // outdated file somewhere $status->fatal( 'backend-fail-synced', $path ); + continue; } } } else { // file is not in master -- 2.20.1