Index: trunk/phase3/includes/filerepo/backend/FileBackend.php |
— | — | @@ -1422,6 +1422,7 @@ |
1423 | 1423 | final protected static function isValidContainerName( $container ) { |
1424 | 1424 | // This accounts for Swift and S3 restrictions while leaving room |
1425 | 1425 | // for things like '.xxx' (hex shard chars) or '.seg' (segments). |
| 1426 | + // This disallows directory separators or traversal characters. |
1426 | 1427 | // Note that matching strings URL encode to the same string; |
1427 | 1428 | // in Swift, the length restriction is *after* URL encoding. |
1428 | 1429 | return preg_match( '/^[a-z0-9][a-z0-9-_]{0,199}$/i', $container ); |
Index: trunk/phase3/includes/filerepo/backend/FileBackendMultiWrite.php |
— | — | @@ -24,7 +24,12 @@ |
25 | 25 | /** @var Array Prioritized list of FileBackendStore objects */ |
26 | 26 | protected $backends = array(); // array of (backend index => backends) |
27 | 27 | protected $masterIndex = -1; // integer; index of master backend |
| 28 | + protected $syncChecks = 0; // integer bitfield |
28 | 29 | |
| 30 | + /* Possible internal backend consistency checks */ |
| 31 | + const CHECK_SIZE = 1; |
| 32 | + const CHECK_TIME = 2; |
| 33 | + |
29 | 34 | /** |
30 | 35 | * Construct a proxy backend that consists of several internal backends. |
31 | 36 | * Additional $config params include: |
— | — | @@ -33,6 +38,9 @@ |
34 | 39 | * FileBackendStore class, but with these additional settings: |
35 | 40 | * 'class' : The name of the backend class |
36 | 41 | * 'isMultiMaster' : This must be set for one backend. |
| 42 | + * 'syncChecks' : Integer bitfield of internal backend sync checks to perform. |
| 43 | + * Possible bits include self::CHECK_SIZE and self::CHECK_TIME. |
| 44 | + * The checks are done before allowing any file operations. |
37 | 45 | * @param $config Array |
38 | 46 | */ |
39 | 47 | public function __construct( array $config ) { |
— | — | @@ -61,6 +69,9 @@ |
62 | 70 | if ( $this->masterIndex < 0 ) { // need backends and must have a master |
63 | 71 | throw new MWException( 'No master backend defined.' ); |
64 | 72 | } |
| 73 | + $this->syncChecks = isset( $config['syncChecks'] ) |
| 74 | + ? $config['syncChecks'] |
| 75 | + : self::CHECK_SIZE; |
65 | 76 | } |
66 | 77 | |
67 | 78 | /** |
— | — | @@ -156,6 +167,9 @@ |
157 | 168 | */ |
158 | 169 | public function consistencyCheck( array $paths ) { |
159 | 170 | $status = Status::newGood(); |
| 171 | + if ( $this->syncChecks == 0 ) { |
| 172 | + return $status; // skip checks |
| 173 | + } |
160 | 174 | |
161 | 175 | $mBackend = $this->backends[$this->masterIndex]; |
162 | 176 | foreach ( array_unique( $paths ) as $path ) { |
— | — | @@ -171,13 +185,20 @@ |
172 | 186 | if ( $mStat ) { // file is in master |
173 | 187 | if ( !$cStat ) { // file should exist |
174 | 188 | $status->fatal( 'backend-fail-synced', $path ); |
175 | | - } elseif ( $cStat['size'] != $mStat['size'] ) { // wrong size |
176 | | - $status->fatal( 'backend-fail-synced', $path ); |
177 | | - } else { |
| 189 | + continue; |
| 190 | + } |
| 191 | + if ( $this->syncChecks & self::CHECK_SIZE ) { |
| 192 | + if ( $cStat['size'] != $mStat['size'] ) { // wrong size |
| 193 | + $status->fatal( 'backend-fail-synced', $path ); |
| 194 | + continue; |
| 195 | + } |
| 196 | + } |
| 197 | + if ( $this->syncChecks & self::CHECK_TIME ) { |
178 | 198 | $mTs = wfTimestamp( TS_UNIX, $mStat['mtime'] ); |
179 | 199 | $cTs = wfTimestamp( TS_UNIX, $cStat['mtime'] ); |
180 | 200 | if ( abs( $mTs - $cTs ) > 30 ) { // outdated file somewhere |
181 | 201 | $status->fatal( 'backend-fail-synced', $path ); |
| 202 | + continue; |
182 | 203 | } |
183 | 204 | } |
184 | 205 | } else { // file is not in master |
Index: trunk/phase3/includes/filerepo/backend/FSFileBackend.php |
— | — | @@ -58,16 +58,6 @@ |
59 | 59 | } |
60 | 60 | |
61 | 61 | /** |
62 | | - * @see FileBackendStore::resolveContainerName() |
63 | | - */ |
64 | | - protected function resolveContainerName( $container ) { |
65 | | - if ( $container !== '.' ) { |
66 | | - return $container; // container is not a traversal |
67 | | - } |
68 | | - return null; |
69 | | - } |
70 | | - |
71 | | - /** |
72 | 62 | * @see FileBackendStore::resolveContainerPath() |
73 | 63 | */ |
74 | 64 | protected function resolveContainerPath( $container, $relStoragePath ) { |