Aaron Schulz has uploaded a new change for review. https://gerrit.wikimedia.org/r/311362
Change subject: FSFile and TempFSFile cleanups ...................................................................... FSFile and TempFSFile cleanups * Remove wf* function dependencies. This includes wfTempDir(). Callers now should specify the directory, though it will try to do most of the wfTempDir() logic anyway if they do not. * Update callers to inject wfTempDir() so $wgTmpDirectory is used by TempFSFile instead of it proping to find a valid directory itself. * Move most of the wfTempDir() logic to TempFSFile::getUsableTempDirectory(). * Remove unused getMimeType() method. Change-Id: Idd55936b07f9448a6c90577708722b7b52b8fe66 --- M includes/GlobalFunctions.php M includes/api/ApiImageRotate.php M includes/filebackend/FSFile.php M includes/filebackend/TempFSFile.php M includes/filerepo/file/File.php M includes/upload/UploadFromChunks.php M includes/upload/UploadFromUrl.php M tests/phpunit/includes/filebackend/FileBackendTest.php M tests/phpunit/includes/filerepo/MigrateFileRepoLayoutTest.php M tests/phpunit/mocks/filebackend/MockFSFile.php 10 files changed, 57 insertions(+), 62 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core refs/changes/62/311362/1 diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index 90bba53..e5f518f 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -2078,35 +2078,7 @@ return $wgTmpDirectory; } - $tmpDir = array_map( "getenv", [ 'TMPDIR', 'TMP', 'TEMP' ] ); - $tmpDir[] = sys_get_temp_dir(); - $tmpDir[] = ini_get( 'upload_tmp_dir' ); - - foreach ( $tmpDir as $tmp ) { - if ( $tmp && file_exists( $tmp ) && is_dir( $tmp ) && is_writable( $tmp ) ) { - return $tmp; - } - } - - /** - * PHP on Windows will detect C:\Windows\Temp as not writable even though PHP can write to it - * so create a directory within that called 'mwtmp' with a suffix of the user running the - * current process. - * The user is included as if various scripts are run by different users they will likely - * not be able to access each others temporary files. - */ - if ( wfIsWindows() ) { - $tmp = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'mwtmp' . '-' . get_current_user(); - if ( !file_exists( $tmp ) ) { - mkdir( $tmp ); - } - if ( file_exists( $tmp ) && is_dir( $tmp ) && is_writable( $tmp ) ) { - return $tmp; - } - } - - throw new MWException( 'No writable temporary directory could be found. ' . - 'Please set $wgTmpDirectory to a writable directory.' ); + return TempFSFile::getUsableTempDirectory(); } /** diff --git a/includes/api/ApiImageRotate.php b/includes/api/ApiImageRotate.php index 2b99353..966bcbf 100644 --- a/includes/api/ApiImageRotate.php +++ b/includes/api/ApiImageRotate.php @@ -108,7 +108,7 @@ continue; } $ext = strtolower( pathinfo( "$srcPath", PATHINFO_EXTENSION ) ); - $tmpFile = TempFSFile::factory( 'rotate_', $ext ); + $tmpFile = TempFSFile::factory( 'rotate_', $ext, wfTempDir() ); $dstPath = $tmpFile->getPath(); $err = $handler->rotate( $file, [ 'srcPath' => $srcPath, diff --git a/includes/filebackend/FSFile.php b/includes/filebackend/FSFile.php index 8aa11b6..221fe9f 100644 --- a/includes/filebackend/FSFile.php +++ b/includes/filebackend/FSFile.php @@ -86,15 +86,6 @@ } /** - * Guess the MIME type from the file contents alone - * - * @return string - */ - public function getMimeType() { - return MimeMagic::singleton()->guessMimeType( $this->path, false ); - } - - /** * Get an associative array containing information about * a file with the given storage path. * @@ -117,8 +108,6 @@ * @return array */ public function getProps( $ext = true ) { - wfDebug( __METHOD__ . ": Getting file info for $this->path\n" ); - $info = self::placeholderProps(); $info['fileExists'] = $this->exists(); @@ -131,7 +120,7 @@ } # MIME type according to file contents - $info['file-mime'] = $this->getMimeType(); + $info['file-mime'] = $magic->guessMimeType( $this->path, false ); # logical MIME type $info['mime'] = $magic->improveTypeFromExtension( $info['file-mime'], $ext ); @@ -145,17 +134,15 @@ $handler = MediaHandler::getHandler( $info['mime'] ); if ( $handler ) { $tempImage = (object)[]; // XXX (hack for File object) + /** @noinspection PhpParamsInspection */ $info['metadata'] = $handler->getMetadata( $tempImage, $this->path ); + /** @noinspection PhpParamsInspection */ $gis = $handler->getImageSize( $tempImage, $this->path, $info['metadata'] ); if ( is_array( $gis ) ) { $info = $this->extractImageSizeInfo( $gis ) + $info; } } $info['sha1'] = $this->getSha1Base36(); - - wfDebug( __METHOD__ . ": $this->path loaded, {$info['size']} bytes, {$info['mime']}.\n" ); - } else { - wfDebug( __METHOD__ . ": $this->path NOT FOUND!\n" ); } return $info; diff --git a/includes/filebackend/TempFSFile.php b/includes/filebackend/TempFSFile.php index f572840..fed6812 100644 --- a/includes/filebackend/TempFSFile.php +++ b/includes/filebackend/TempFSFile.php @@ -48,15 +48,20 @@ * Temporary files may be purged when the file object falls out of scope. * * @param string $prefix - * @param string $extension + * @param string $extension Optional file extension + * @param string|null $tmpDirectory Optional parent directory * @return TempFSFile|null */ - public static function factory( $prefix, $extension = '' ) { + public static function factory( $prefix, $extension = '', $tmpDirectory = null ) { $ext = ( $extension != '' ) ? ".{$extension}" : ''; $attempts = 5; while ( $attempts-- ) { - $path = wfTempDir() . '/' . $prefix . wfRandomString( 12 ) . $ext; + $hex = sprintf( '%06x%06x', mt_rand( 0, 0xffffff ), mt_rand( 0, 0xffffff ) ); + if ( !is_string( $tmpDirectory ) ) { + $tmpDirectory = self::getUsableTempDirectory(); + } + $path = wfTempDir() . '/' . $prefix . $hex . $ext; MediaWiki\suppressWarnings(); $newFileHandle = fopen( $path, 'x' ); MediaWiki\restoreWarnings(); @@ -74,6 +79,40 @@ } /** + * @return string Filesystem path to a temporary directory + * @throws RuntimeException + */ + public static function getUsableTempDirectory() { + $tmpDir = array_map( 'getenv', [ 'TMPDIR', 'TMP', 'TEMP' ] ); + $tmpDir[] = sys_get_temp_dir(); + $tmpDir[] = ini_get( 'upload_tmp_dir' ); + foreach ( $tmpDir as $tmp ) { + if ( $tmp != '' && is_dir( $tmp ) && is_writable( $tmp ) ) { + return $tmp; + } + } + + // PHP on Windows will detect C:\Windows\Temp as not writable even though PHP can write to + // it so create a directory within that called 'mwtmp' with a suffix of the user running + // the current process. + // The user is included as if various scripts are run by different users they will likely + // not be able to access each others temporary files. + if ( strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN' ) { + $tmp = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'mwtmp-' . get_current_user(); + if ( !file_exists( $tmp ) ) { + mkdir( $tmp ); + } + if ( is_dir( $tmp ) && is_writable( $tmp ) ) { + return $tmp; + } + } + + throw new RuntimeException( + 'No writable temporary directory could be found. ' . + 'Please explicitly specify a writable directory in configuration.' ); + } + + /** * Purge this file off the file system * * @return bool Success diff --git a/includes/filerepo/file/File.php b/includes/filerepo/file/File.php index 425a08c..c48866b 100644 --- a/includes/filerepo/file/File.php +++ b/includes/filerepo/file/File.php @@ -1328,7 +1328,7 @@ */ protected function makeTransformTmpFile( $thumbPath ) { $thumbExt = FileBackend::extensionFromPath( $thumbPath ); - return TempFSFile::factory( 'transform_', $thumbExt ); + return TempFSFile::factory( 'transform_', $thumbExt, wfTempDir() ); } /** diff --git a/includes/upload/UploadFromChunks.php b/includes/upload/UploadFromChunks.php index 9145a85..08cf434 100644 --- a/includes/upload/UploadFromChunks.php +++ b/includes/upload/UploadFromChunks.php @@ -130,7 +130,7 @@ // Get the file extension from the last chunk $ext = FileBackend::extensionFromPath( $this->mVirtualTempPath ); // Get a 0-byte temp file to perform the concatenation at - $tmpFile = TempFSFile::factory( 'chunkedupload_', $ext ); + $tmpFile = TempFSFile::factory( 'chunkedupload_', $ext, wfTempDir() ); $tmpPath = false; // fail in concatenate() if ( $tmpFile ) { // keep alive with $this diff --git a/includes/upload/UploadFromUrl.php b/includes/upload/UploadFromUrl.php index 6639c34..865f630 100644 --- a/includes/upload/UploadFromUrl.php +++ b/includes/upload/UploadFromUrl.php @@ -202,7 +202,7 @@ * @return string Path to the file */ protected function makeTemporaryFile() { - $tmpFile = TempFSFile::factory( 'URL' ); + $tmpFile = TempFSFile::factory( 'URL', 'urlupload_', wfTempDir() ); $tmpFile->bind( $this ); return $tmpFile->getPath(); diff --git a/tests/phpunit/includes/filebackend/FileBackendTest.php b/tests/phpunit/includes/filebackend/FileBackendTest.php index 254cfbd..ca562aa 100644 --- a/tests/phpunit/includes/filebackend/FileBackendTest.php +++ b/tests/phpunit/includes/filebackend/FileBackendTest.php @@ -268,7 +268,7 @@ public static function provider_testStore() { $cases = []; - $tmpName = TempFSFile::factory( "unittests_", 'txt' )->getPath(); + $tmpName = TempFSFile::factory( "unittests_", 'txt', wfTempDir() )->getPath(); $toPath = self::baseStorePath() . '/unittest-cont1/e/fun/obj1.txt'; $op = [ 'op' => 'store', 'src' => $tmpName, 'dst' => $toPath ]; $cases[] = [ $op ]; @@ -1786,9 +1786,9 @@ $fileBContents = 'g-jmq3gpqgt3qtg q3GT '; $fileCContents = 'eigna[ogmewt 3qt g3qg flew[ag'; - $tmpNameA = TempFSFile::factory( "unittests_", 'txt' )->getPath(); - $tmpNameB = TempFSFile::factory( "unittests_", 'txt' )->getPath(); - $tmpNameC = TempFSFile::factory( "unittests_", 'txt' )->getPath(); + $tmpNameA = TempFSFile::factory( "unittests_", 'txt', wfTempDir() )->getPath(); + $tmpNameB = TempFSFile::factory( "unittests_", 'txt', wfTempDir() )->getPath(); + $tmpNameC = TempFSFile::factory( "unittests_", 'txt', wfTempDir() )->getPath(); $this->addTmpFiles( [ $tmpNameA, $tmpNameB, $tmpNameC ] ); file_put_contents( $tmpNameA, $fileAContents ); file_put_contents( $tmpNameB, $fileBContents ); diff --git a/tests/phpunit/includes/filerepo/MigrateFileRepoLayoutTest.php b/tests/phpunit/includes/filerepo/MigrateFileRepoLayoutTest.php index ed80c57..92a54fa 100644 --- a/tests/phpunit/includes/filerepo/MigrateFileRepoLayoutTest.php +++ b/tests/phpunit/includes/filerepo/MigrateFileRepoLayoutTest.php @@ -59,7 +59,8 @@ ->method( 'getRepo' ) ->will( $this->returnValue( $repoMock ) ); - $this->tmpFilepath = TempFSFile::factory( 'migratefilelayout-test-', 'png' )->getPath(); + $this->tmpFilepath = TempFSFile::factory( + 'migratefilelayout-test-', 'png', wfTempDir() )->getPath(); file_put_contents( $this->tmpFilepath, $this->text ); diff --git a/tests/phpunit/mocks/filebackend/MockFSFile.php b/tests/phpunit/mocks/filebackend/MockFSFile.php index bdeed58..6797f59 100644 --- a/tests/phpunit/mocks/filebackend/MockFSFile.php +++ b/tests/phpunit/mocks/filebackend/MockFSFile.php @@ -50,15 +50,11 @@ return wfTimestamp( TS_MW ); } - public function getMimeType() { - return 'text/mock'; - } - public function getProps( $ext = true ) { return [ 'fileExists' => $this->exists(), 'size' => $this->getSize(), - 'file-mime' => $this->getMimeType(), + 'file-mime' => 'text/mock', 'sha1' => $this->getSha1Base36(), ]; } -- To view, visit https://gerrit.wikimedia.org/r/311362 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Idd55936b07f9448a6c90577708722b7b52b8fe66 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/core Gerrit-Branch: master Gerrit-Owner: Aaron Schulz <asch...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits