Safer autoloading with respect to file-scope code
Many files were in the autoloader despite having potentially harmful file-scope code. * Exclude all CommandLineInc maintenance scripts from the autoloader. * Introduce "NO_AUTOLOAD" tag which excludes the file containing it from the autoloader. Use it on CommandLineInc.php and a few suspicious-looking files without classes in case they are refactored to add classes in the future. * Add a test which parses all non-PSR4 class files and confirms that they do not contain dangerous file-scope code. It's slow (15s) but its results were enlightening. * Several maintenance scripts define constants in the file scope, intending to modify the behaviour of MediaWiki. Either move the define() to a later setup function, or protect with NO_AUTOLOAD. * Use require_once consistently with Maintenance.php and doMaintenance.php, per the original convention which is supposed to allow one maintenance script to use the class of another maintenance script. Using require breaks autoloading of these maintenance class files. * When Maintenance.php is included, check if MediaWiki has already started, and if so, return early. Revert the fix for T250003 which is incompatible with this safety measure. Hopefully it was superseded by splitting out the class file. * In runScript.php add a redundant PHP_SAPI check since it does some things in file-scope code before any other check will be run. * Change the if(false) class_alias(...) to something more hackish and more compatible with the new test. * Some site-related scripts found Maintenance.php in a non-standard way. Use the standard way. * fileOpPerfTest.php called error_reporting(). Probably debugging code left in; removed. * Moved mediawiki.compress.7z registration from the class file to the caller. Change-Id: I1b1be90343a5ab678df6f1b1bdd03319dcf6537f
This commit is contained in:
parent
320af70270
commit
20d06b34bb
32 changed files with 185 additions and 96 deletions
13
autoload.php
13
autoload.php
|
|
@ -169,7 +169,6 @@ $wgAutoloadLocalClasses = [
|
|||
'AugmentPageProps' => __DIR__ . '/includes/search/AugmentPageProps.php',
|
||||
'AuthManagerSpecialPage' => __DIR__ . '/includes/specialpage/AuthManagerSpecialPage.php',
|
||||
'AutoCommitUpdate' => __DIR__ . '/includes/deferred/AutoCommitUpdate.php',
|
||||
'AutoLoader' => __DIR__ . '/includes/AutoLoader.php',
|
||||
'AutoloadGenerator' => __DIR__ . '/includes/utils/AutoloadGenerator.php',
|
||||
'Autopromote' => __DIR__ . '/includes/Autopromote.php',
|
||||
'AvroValidator' => __DIR__ . '/includes/utils/AvroValidator.php',
|
||||
|
|
@ -238,7 +237,6 @@ $wgAutoloadLocalClasses = [
|
|||
'CdnCacheUpdate' => __DIR__ . '/includes/deferred/CdnCacheUpdate.php',
|
||||
'CdnPurgeJob' => __DIR__ . '/includes/jobqueue/jobs/CdnPurgeJob.php',
|
||||
'CentralIdLookup' => __DIR__ . '/includes/user/CentralIdLookup.php',
|
||||
'CgzCopyTransaction' => __DIR__ . '/maintenance/storage/recompressTracked.php',
|
||||
'ChangePassword' => __DIR__ . '/maintenance/changePassword.php',
|
||||
'ChangeTags' => __DIR__ . '/includes/changetags/ChangeTags.php',
|
||||
'ChangeTagsList' => __DIR__ . '/includes/changetags/ChangeTagsList.php',
|
||||
|
|
@ -261,7 +259,6 @@ $wgAutoloadLocalClasses = [
|
|||
'CheckDependencies' => __DIR__ . '/maintenance/checkDependencies.php',
|
||||
'CheckImages' => __DIR__ . '/maintenance/checkImages.php',
|
||||
'CheckLess' => __DIR__ . '/maintenance/checkLess.php',
|
||||
'CheckStorage' => __DIR__ . '/maintenance/storage/checkStorage.php',
|
||||
'CheckUsernames' => __DIR__ . '/maintenance/checkUsernames.php',
|
||||
'ClassCollector' => __DIR__ . '/includes/utils/ClassCollector.php',
|
||||
'CleanupAncientTables' => __DIR__ . '/maintenance/cleanupAncientTables.php',
|
||||
|
|
@ -287,8 +284,6 @@ $wgAutoloadLocalClasses = [
|
|||
'CollapsibleFieldsetLayout' => __DIR__ . '/includes/htmlform/CollapsibleFieldsetLayout.php',
|
||||
'Collation' => __DIR__ . '/includes/collation/Collation.php',
|
||||
'CollationCkb' => __DIR__ . '/includes/collation/CollationCkb.php',
|
||||
'CommandLineInc' => __DIR__ . '/maintenance/CommandLineInc.php',
|
||||
'CommandLineInstaller' => __DIR__ . '/maintenance/install.php',
|
||||
'CommentStore' => __DIR__ . '/includes/CommentStore.php',
|
||||
'CommentStoreComment' => __DIR__ . '/includes/CommentStoreComment.php',
|
||||
'CompareParserCache' => __DIR__ . '/maintenance/compareParserCache.php',
|
||||
|
|
@ -1139,7 +1134,6 @@ $wgAutoloadLocalClasses = [
|
|||
'MergeHistory' => __DIR__ . '/includes/MergeHistory.php',
|
||||
'MergeHistoryPager' => __DIR__ . '/includes/specials/pagers/MergeHistoryPager.php',
|
||||
'MergeLogFormatter' => __DIR__ . '/includes/logging/MergeLogFormatter.php',
|
||||
'MergeMessageFileList' => __DIR__ . '/maintenance/mergeMessageFileList.php',
|
||||
'MergeableUpdate' => __DIR__ . '/includes/deferred/MergeableUpdate.php',
|
||||
'Message' => __DIR__ . '/includes/language/Message.php',
|
||||
'MessageBlobStore' => __DIR__ . '/includes/resourceloader/MessageBlobStore.php',
|
||||
|
|
@ -1215,9 +1209,6 @@ $wgAutoloadLocalClasses = [
|
|||
'PPDStack_Hash' => __DIR__ . '/includes/parser/PPDStack_Hash.php',
|
||||
'PPFrame' => __DIR__ . '/includes/parser/PPFrame.php',
|
||||
'PPFrame_Hash' => __DIR__ . '/includes/parser/PPFrame_Hash.php',
|
||||
'PPFuzzTest' => __DIR__ . '/maintenance/preprocessorFuzzTest.php',
|
||||
'PPFuzzTester' => __DIR__ . '/maintenance/preprocessorFuzzTest.php',
|
||||
'PPFuzzUser' => __DIR__ . '/maintenance/preprocessorFuzzTest.php',
|
||||
'PPNode' => __DIR__ . '/includes/parser/PPNode.php',
|
||||
'PPNode_Hash_Array' => __DIR__ . '/includes/parser/PPNode_Hash_Array.php',
|
||||
'PPNode_Hash_Attr' => __DIR__ . '/includes/parser/PPNode_Hash_Attr.php',
|
||||
|
|
@ -1349,7 +1340,6 @@ $wgAutoloadLocalClasses = [
|
|||
'RebuildTextIndex' => __DIR__ . '/maintenance/rebuildtextindex.php',
|
||||
'RecentChange' => __DIR__ . '/includes/changes/RecentChange.php',
|
||||
'RecentChangesUpdateJob' => __DIR__ . '/includes/jobqueue/jobs/RecentChangesUpdateJob.php',
|
||||
'RecompressTracked' => __DIR__ . '/maintenance/storage/recompressTracked.php',
|
||||
'RecountCategories' => __DIR__ . '/maintenance/recountCategories.php',
|
||||
'RedirectSpecialArticle' => __DIR__ . '/includes/specialpage/RedirectSpecialArticle.php',
|
||||
'RedirectSpecialPage' => __DIR__ . '/includes/specialpage/RedirectSpecialPage.php',
|
||||
|
|
@ -1685,7 +1675,6 @@ $wgAutoloadLocalClasses = [
|
|||
'TitleParser' => __DIR__ . '/includes/title/TitleParser.php',
|
||||
'TitlePrefixSearch' => __DIR__ . '/includes/search/TitlePrefixSearch.php',
|
||||
'TitleValue' => __DIR__ . '/includes/title/TitleValue.php',
|
||||
'TrackBlobs' => __DIR__ . '/maintenance/storage/trackBlobs.php',
|
||||
'TrackingCategories' => __DIR__ . '/includes/TrackingCategories.php',
|
||||
'TraditionalImageGallery' => __DIR__ . '/includes/gallery/TraditionalImageGallery.php',
|
||||
'TransactionRoundAwareUpdate' => __DIR__ . '/includes/deferred/TransactionRoundAwareUpdate.php',
|
||||
|
|
@ -1711,8 +1700,6 @@ $wgAutoloadLocalClasses = [
|
|||
'UpdateCollation' => __DIR__ . '/maintenance/updateCollation.php',
|
||||
'UpdateDoubleWidthSearch' => __DIR__ . '/maintenance/updateDoubleWidthSearch.php',
|
||||
'UpdateExtensionJsonSchema' => __DIR__ . '/maintenance/updateExtensionJsonSchema.php',
|
||||
'UpdateLogging' => __DIR__ . '/maintenance/archives/upgradeLogging.php',
|
||||
'UpdateMediaWiki' => __DIR__ . '/maintenance/update.php',
|
||||
'UpdateRestrictions' => __DIR__ . '/maintenance/updateRestrictions.php',
|
||||
'UpdateSearchIndex' => __DIR__ . '/maintenance/updateSearchIndex.php',
|
||||
'UpdateSpecialPages' => __DIR__ . '/maintenance/updateSpecialPages.php',
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
* @file
|
||||
*/
|
||||
|
||||
// NO_AUTOLOAD -- file scope code, can't load self
|
||||
|
||||
/**
|
||||
* Locations of core classes
|
||||
* Extension classes are specified with $wgAutoloadClasses
|
||||
|
|
|
|||
|
|
@ -3,20 +3,24 @@
|
|||
use Composer\Package\Package;
|
||||
use Composer\Script\Event;
|
||||
|
||||
$GLOBALS['IP'] = __DIR__ . '/../../';
|
||||
require_once __DIR__ . '/../AutoLoader.php';
|
||||
|
||||
/**
|
||||
* @license GPL-2.0-or-later
|
||||
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
|
||||
*/
|
||||
class ComposerHookHandler {
|
||||
|
||||
private static function startAutoloader() {
|
||||
$GLOBALS['IP'] = __DIR__ . '/../../';
|
||||
require_once __DIR__ . '/../AutoLoader.php';
|
||||
}
|
||||
|
||||
public static function onPreUpdate( Event $event ) {
|
||||
self::startAutoloader();
|
||||
self::handleChangeEvent( $event );
|
||||
}
|
||||
|
||||
public static function onPreInstall( Event $event ) {
|
||||
self::startAutoloader();
|
||||
self::handleChangeEvent( $event );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -142,13 +142,11 @@ class ConcatenatedGzipHistoryBlob implements HistoryBlob {
|
|||
}
|
||||
}
|
||||
|
||||
// @phan-suppress-next-next-line PhanImpossibleCondition
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnconditionalIfStatement.Found
|
||||
if ( false ) {
|
||||
// Blobs generated by MediaWiki < 1.5 on PHP 4 were serialized with the
|
||||
// class name coerced to lowercase. We can improve efficiency by adding
|
||||
// autoload entries for the lowercase variants of these classes (T166759).
|
||||
// The code below is never executed, but it is picked up by the AutoloadGenerator
|
||||
// parser, which scans for class_alias() calls.
|
||||
class_alias( ConcatenatedGzipHistoryBlob::class, 'concatenatedgziphistoryblob' );
|
||||
}
|
||||
// Blobs generated by MediaWiki < 1.5 on PHP 4 were serialized with the
|
||||
// class name coerced to lowercase. We can improve efficiency by adding
|
||||
// autoload entries for the lowercase variants of these classes (T166759).
|
||||
// The code below is never executed, but it is picked up by the AutoloadGenerator
|
||||
// parser, which scans for class_alias() calls.
|
||||
/*
|
||||
class_alias( ConcatenatedGzipHistoryBlob::class, 'concatenatedgziphistoryblob' );
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -62,13 +62,11 @@ class HistoryBlobCurStub {
|
|||
}
|
||||
}
|
||||
|
||||
// @phan-suppress-next-next-line PhanImpossibleCondition
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnconditionalIfStatement.Found
|
||||
if ( false ) {
|
||||
// Blobs generated by MediaWiki < 1.5 on PHP 4 were serialized with the
|
||||
// class name coerced to lowercase. We can improve efficiency by adding
|
||||
// autoload entries for the lowercase variants of these classes (T166759).
|
||||
// The code below is never executed, but it is picked up by the AutoloadGenerator
|
||||
// parser, which scans for class_alias() calls.
|
||||
class_alias( HistoryBlobCurStub::class, 'historyblobcurstub' );
|
||||
}
|
||||
// Blobs generated by MediaWiki < 1.5 on PHP 4 were serialized with the
|
||||
// class name coerced to lowercase. We can improve efficiency by adding
|
||||
// autoload entries for the lowercase variants of these classes (T166759).
|
||||
// The code below is never executed, but it is picked up by the AutoloadGenerator
|
||||
// parser, which scans for class_alias() calls.
|
||||
/*
|
||||
class_alias( HistoryBlobCurStub::class, 'historyblobcurstub' );
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -143,13 +143,11 @@ class HistoryBlobStub {
|
|||
}
|
||||
}
|
||||
|
||||
// @phan-suppress-next-next-line PhanImpossibleCondition
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnconditionalIfStatement.Found
|
||||
if ( false ) {
|
||||
// Blobs generated by MediaWiki < 1.5 on PHP 4 were serialized with the
|
||||
// class name coerced to lowercase. We can improve efficiency by adding
|
||||
// autoload entries for the lowercase variants of these classes (T166759).
|
||||
// The code below is never executed, but it is picked up by the AutoloadGenerator
|
||||
// parser, which scans for class_alias() calls.
|
||||
class_alias( HistoryBlobStub::class, 'historyblobstub' );
|
||||
}
|
||||
// Blobs generated by MediaWiki < 1.5 on PHP 4 were serialized with the
|
||||
// class name coerced to lowercase. We can improve efficiency by adding
|
||||
// autoload entries for the lowercase variants of these classes (T166759).
|
||||
// The code below is never executed, but it is picked up by the AutoloadGenerator
|
||||
// parser, which scans for class_alias() calls.
|
||||
/*
|
||||
class_alias( HistoryBlobStub::class, 'historyblobstub' );
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -171,9 +171,22 @@ class AutoloadGenerator {
|
|||
if ( $this->shouldExclude( $inputPath ) ) {
|
||||
return;
|
||||
}
|
||||
$result = $this->collector->getClasses(
|
||||
file_get_contents( $inputPath )
|
||||
);
|
||||
$fileContents = file_get_contents( $inputPath );
|
||||
|
||||
// Skip files that declare themselves excluded
|
||||
if ( preg_match( '!^// *NO_AUTOLOAD!m', $fileContents ) ) {
|
||||
return;
|
||||
}
|
||||
// Skip files that use CommandLineInc since these execute file-scope
|
||||
// code when included
|
||||
if ( preg_match(
|
||||
'/(require|require_once)[ (].*(CommandLineInc.php|commandLine.inc)/',
|
||||
$fileContents )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$result = $this->collector->getClasses( $fileContents );
|
||||
|
||||
// Filter out classes that will be found by PSR4
|
||||
$result = array_filter( $result, function ( $class ) use ( $inputPath ) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
* @ingroup Maintenance
|
||||
*/
|
||||
|
||||
// NO_AUTOLOAD -- unsafe file-scope code
|
||||
|
||||
require_once __DIR__ . '/Maintenance.php';
|
||||
|
||||
global $optionsWithArgs, $optionsWithoutArgs, $allowUnregisteredOptions;
|
||||
|
|
@ -71,4 +73,4 @@ class CommandLineInc extends Maintenance {
|
|||
}
|
||||
|
||||
$maintClass = CommandLineInc::class;
|
||||
require RUN_MAINTENANCE_IF_MAIN;
|
||||
require_once RUN_MAINTENANCE_IF_MAIN;
|
||||
|
|
|
|||
|
|
@ -20,10 +20,16 @@
|
|||
* @defgroup Maintenance Maintenance
|
||||
*/
|
||||
|
||||
if ( !defined( 'MW_ENTRY_POINT' ) ) {
|
||||
define( 'MW_ENTRY_POINT', 'cli' );
|
||||
if ( defined( 'MEDIAWIKI' ) ) {
|
||||
// This file is included by many autoloaded class files, and so may
|
||||
// potentially be invoked in the context of a web request or another CLI
|
||||
// script. It's not appropriate to run the following file-scope code in
|
||||
// such a case.
|
||||
return;
|
||||
}
|
||||
|
||||
define( 'MW_ENTRY_POINT', 'cli' );
|
||||
|
||||
// Bail on old versions of PHP, or if composer has not been run yet to install
|
||||
// dependencies.
|
||||
require_once __DIR__ . '/../includes/PHPVersionCheck.php';
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
$basePath = getenv( 'MW_INSTALL_PATH' ) !== false ? getenv( 'MW_INSTALL_PATH' ) : __DIR__ . '/..';
|
||||
|
||||
require_once $basePath . '/maintenance/Maintenance.php';
|
||||
require_once __DIR__ . '/Maintenance.php';
|
||||
|
||||
/**
|
||||
* Maintenance script for adding a site definition into the sites table.
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
* @ingroup Benchmark
|
||||
*/
|
||||
|
||||
require __DIR__ . '/../Maintenance.php';
|
||||
require_once __DIR__ . '/../Maintenance.php';
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Revision\RevisionRecord;
|
||||
|
|
@ -194,4 +194,4 @@ class BenchmarkParse extends Maintenance {
|
|||
}
|
||||
|
||||
$maintClass = BenchmarkParse::class;
|
||||
require RUN_MAINTENANCE_IF_MAIN;
|
||||
require_once RUN_MAINTENANCE_IF_MAIN;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
require __DIR__ . '/../includes/Benchmarker.php';
|
||||
require_once __DIR__ . '/../includes/Benchmarker.php';
|
||||
|
||||
class BenchmarkTidy extends Benchmarker {
|
||||
public function __construct() {
|
||||
|
|
@ -79,4 +79,4 @@ class BenchmarkTidy extends Benchmarker {
|
|||
}
|
||||
|
||||
$maintClass = BenchmarkTidy::class;
|
||||
require RUN_MAINTENANCE_IF_MAIN;
|
||||
require_once RUN_MAINTENANCE_IF_MAIN;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
<?php
|
||||
|
||||
$basePath = getenv( 'MW_INSTALL_PATH' ) !== false ? getenv( 'MW_INSTALL_PATH' ) : __DIR__ . '/..';
|
||||
|
||||
require_once $basePath . '/maintenance/Maintenance.php';
|
||||
require_once __DIR__ . '/Maintenance.php';
|
||||
|
||||
/**
|
||||
* Maintenance script for exporting site definitions from XML into the sites table.
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
error_reporting( E_ALL );
|
||||
require_once __DIR__ . '/Maintenance.php';
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
<?php
|
||||
|
||||
$basePath = getenv( 'MW_INSTALL_PATH' ) !== false ? getenv( 'MW_INSTALL_PATH' ) : __DIR__ . '/..';
|
||||
|
||||
require_once $basePath . '/maintenance/Maintenance.php';
|
||||
require_once __DIR__ . '/Maintenance.php';
|
||||
|
||||
/**
|
||||
* Maintenance script for importing site definitions from XML into the sites table.
|
||||
|
|
|
|||
|
|
@ -36,6 +36,14 @@ use MediaWiki\Shell\Shell;
|
|||
class SevenZipStream {
|
||||
protected $stream;
|
||||
|
||||
public static function register() {
|
||||
static $done = false;
|
||||
if ( !$done ) {
|
||||
$done = true;
|
||||
stream_wrapper_register( 'mediawiki.compress.7z', self::class );
|
||||
}
|
||||
}
|
||||
|
||||
private function stripPath( $path ) {
|
||||
$prefix = 'mediawiki.compress.7z://';
|
||||
|
||||
|
|
@ -93,5 +101,3 @@ class SevenZipStream {
|
|||
return fseek( $this->stream, $offset, $whence );
|
||||
}
|
||||
}
|
||||
|
||||
stream_wrapper_register( 'mediawiki.compress.7z', SevenZipStream::class );
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
*/
|
||||
|
||||
require_once __DIR__ . '/BackupDumper.php';
|
||||
require_once __DIR__ . '/SevenZipStream.php';
|
||||
require_once __DIR__ . '/../../includes/export/WikiExporter.php';
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
|
@ -149,6 +148,8 @@ TEXT
|
|||
$this->loadWithArgv( $args );
|
||||
$this->processOptions();
|
||||
}
|
||||
|
||||
SevenZipStream::register();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
* @ingroup Maintenance
|
||||
*/
|
||||
|
||||
// NO_AUTOLOAD -- file-scope define() used to modify behaviour
|
||||
|
||||
require_once __DIR__ . '/Maintenance.php';
|
||||
|
||||
define( 'MW_CONFIG_CALLBACK', 'Installer::overrideConfig' );
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
* @ingroup Maintenance
|
||||
*/
|
||||
|
||||
// NO_AUTOLOAD -- file-scope define() used to modify behaviour
|
||||
|
||||
# Start from scratch
|
||||
define( 'MW_NO_EXTENSION_MESSAGES', 1 );
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
* @ingroup Maintenance
|
||||
*/
|
||||
|
||||
require __DIR__ . '/Maintenance.php';
|
||||
require_once __DIR__ . '/Maintenance.php';
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
|
|
|
|||
|
|
@ -21,12 +21,6 @@
|
|||
* @ingroup Maintenance
|
||||
*/
|
||||
|
||||
if ( !defined( 'MEDIAWIKI' ) ) {
|
||||
// So extensions (and other code) can check whether they're running in job mode.
|
||||
// This is not defined if this script is included from installer/updater or phpunit.
|
||||
define( 'MEDIAWIKI_JOB_RUNNER', true );
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/Maintenance.php';
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
|
@ -49,6 +43,13 @@ class RunJobs extends Maintenance {
|
|||
$this->addOption( 'wait', 'Wait for new jobs instead of exiting', false, false );
|
||||
}
|
||||
|
||||
public function finalSetup() {
|
||||
// So extensions (and other code) can check whether they're running in job mode.
|
||||
// This is not defined if this script is included from installer/updater or phpunit.
|
||||
define( 'MEDIAWIKI_JOB_RUNNER', true );
|
||||
parent::finalSetup();
|
||||
}
|
||||
|
||||
public function memoryLimit() {
|
||||
if ( $this->hasOption( 'memory-limit' ) ) {
|
||||
return parent::memoryLimit();
|
||||
|
|
|
|||
|
|
@ -35,6 +35,12 @@
|
|||
* @file
|
||||
* @ingroup Maintenance
|
||||
*/
|
||||
|
||||
if ( PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg' ) {
|
||||
echo "This script must be run from the command line\n";
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
$IP = getenv( 'MW_INSTALL_PATH' );
|
||||
|
||||
if ( $IP === false ) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
* @ingroup Maintenance ExternalStorage
|
||||
*/
|
||||
|
||||
// NO_AUTOLOAD -- file scope code
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
define( 'REPORTING_INTERVAL', 1 );
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
* @ingroup Maintenance
|
||||
*/
|
||||
|
||||
// NO_AUTOLOAD -- due to hashbang above
|
||||
|
||||
require_once __DIR__ . '/Maintenance.php';
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
// NO_AUTOLOAD -- file-scope code
|
||||
|
||||
if ( PHP_SAPI != 'cli' ) {
|
||||
die( "This script can only be run from the command line.\n" );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -197,4 +197,4 @@ WARN
|
|||
}
|
||||
|
||||
$maintClass = UserOptionsMaintenance::class;
|
||||
require RUN_MAINTENANCE_IF_MAIN;
|
||||
require_once RUN_MAINTENANCE_IF_MAIN;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
require __DIR__ . '/../../maintenance/Maintenance.php';
|
||||
require_once __DIR__ . '/../../maintenance/Maintenance.php';
|
||||
|
||||
define( 'MW_PARSER_TEST', true );
|
||||
|
||||
|
|
@ -485,4 +485,4 @@ class ParserEditTests extends Maintenance {
|
|||
}
|
||||
|
||||
$maintClass = ParserEditTests::class;
|
||||
require RUN_MAINTENANCE_IF_MAIN;
|
||||
require_once RUN_MAINTENANCE_IF_MAIN;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,7 @@
|
|||
|
||||
use Wikimedia\ScopedCallback;
|
||||
|
||||
require __DIR__ . '/../../maintenance/Maintenance.php';
|
||||
|
||||
// Make RequestContext::resetMain() happy
|
||||
define( 'MW_PARSER_TEST', 1 );
|
||||
require_once __DIR__ . '/../../maintenance/Maintenance.php';
|
||||
|
||||
class ParserFuzzTest extends Maintenance {
|
||||
private $parserTest;
|
||||
|
|
@ -24,6 +21,9 @@ class ParserFuzzTest extends Maintenance {
|
|||
}
|
||||
|
||||
public function finalSetup() {
|
||||
// Make RequestContext::resetMain() happy
|
||||
define( 'MW_PARSER_TEST', 1 );
|
||||
|
||||
self::requireTestsAutoloader();
|
||||
TestSetup::applyInitialConfig();
|
||||
}
|
||||
|
|
@ -196,4 +196,4 @@ class ParserFuzzTest extends Maintenance {
|
|||
}
|
||||
|
||||
$maintClass = ParserFuzzTest::class;
|
||||
require RUN_MAINTENANCE_IF_MAIN;
|
||||
require_once RUN_MAINTENANCE_IF_MAIN;
|
||||
|
|
|
|||
|
|
@ -24,11 +24,7 @@
|
|||
* @ingroup Testing
|
||||
*/
|
||||
|
||||
// Some methods which are discouraged for normal code throw exceptions unless
|
||||
// we declare this is just a test.
|
||||
define( 'MW_PARSER_TEST', true );
|
||||
|
||||
require __DIR__ . '/../../maintenance/Maintenance.php';
|
||||
require_once __DIR__ . '/../../maintenance/Maintenance.php';
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
|
|
@ -77,6 +73,10 @@ class ParserTestsMaintenance extends Maintenance {
|
|||
}
|
||||
|
||||
public function finalSetup() {
|
||||
// Some methods which are discouraged for normal code throw exceptions unless
|
||||
// we declare this is just a test.
|
||||
define( 'MW_PARSER_TEST', true );
|
||||
|
||||
parent::finalSetup();
|
||||
self::requireTestsAutoloader();
|
||||
TestSetup::applyInitialConfig();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
// Start up MediaWiki in command-line mode
|
||||
require_once __DIR__ . "/../../../../maintenance/Maintenance.php";
|
||||
require __DIR__ . "/RandomImageGenerator.php";
|
||||
require_once __DIR__ . "/RandomImageGenerator.php";
|
||||
|
||||
class GenerateRandomImages extends Maintenance {
|
||||
|
||||
|
|
@ -41,4 +41,4 @@ class GenerateRandomImages extends Maintenance {
|
|||
}
|
||||
|
||||
$maintClass = GenerateRandomImages::class;
|
||||
require RUN_MAINTENANCE_IF_MAIN;
|
||||
require_once RUN_MAINTENANCE_IF_MAIN;
|
||||
|
|
|
|||
|
|
@ -6,10 +6,6 @@
|
|||
* @file
|
||||
*/
|
||||
|
||||
// Set a flag which can be used to detect when other scripts have been entered
|
||||
// through this entry point or not.
|
||||
define( 'MW_PHPUNIT_TEST', true );
|
||||
|
||||
// Start up MediaWiki in command-line mode
|
||||
require_once dirname( dirname( __DIR__ ) ) . "/maintenance/Maintenance.php";
|
||||
|
||||
|
|
@ -29,6 +25,10 @@ class PHPUnitMaintClass extends Maintenance {
|
|||
}
|
||||
|
||||
public function setup() {
|
||||
// Set a flag which can be used to detect when other scripts have been entered
|
||||
// through this entry point or not.
|
||||
define( 'MW_PHPUNIT_TEST', true );
|
||||
|
||||
parent::setup();
|
||||
|
||||
require_once __DIR__ . '/../common/TestSetup.php';
|
||||
|
|
@ -131,4 +131,4 @@ class PHPUnitMaintClass extends Maintenance {
|
|||
}
|
||||
|
||||
$maintClass = PHPUnitMaintClass::class;
|
||||
require RUN_MAINTENANCE_IF_MAIN;
|
||||
require_once RUN_MAINTENANCE_IF_MAIN;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
<?php
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\ParserFactory;
|
||||
|
||||
class AutoLoaderStructureTest extends MediaWikiIntegrationTestCase {
|
||||
/**
|
||||
* Assert that there were no classes loaded that are not registered with the AutoLoader.
|
||||
|
|
@ -175,4 +180,63 @@ class AutoLoaderStructureTest extends MediaWikiIntegrationTestCase {
|
|||
|
||||
$this->assertSame( [], $missing );
|
||||
}
|
||||
|
||||
public static function provideAutoloadNoFileScope() {
|
||||
global $wgAutoloadLocalClasses;
|
||||
$files = array_unique( $wgAutoloadLocalClasses );
|
||||
$args = [];
|
||||
foreach ( $files as $file ) {
|
||||
$args[$file] = [ $file ];
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that all files in $wgAutoloadLocalClasses have no file-scope code
|
||||
* apart from specific exemptions.
|
||||
*
|
||||
* This is slow (~15s). Running it arguably renders all the performance
|
||||
* optimisations above obsolete.
|
||||
*
|
||||
* @dataProvider provideAutoloadNoFileScope
|
||||
*/
|
||||
public function testAutoloadNoFileScope( $file ) {
|
||||
$parser = ( new ParserFactory )->create( ParserFactory::ONLY_PHP7 );
|
||||
$ast = $parser->parse( file_get_contents( $file ) );
|
||||
foreach ( $ast as $node ) {
|
||||
if ( $node instanceof Stmt\ClassLike
|
||||
|| $node instanceof Stmt\Namespace_
|
||||
|| $node instanceof Stmt\Use_
|
||||
|| $node instanceof Stmt\Nop
|
||||
|| $node instanceof Stmt\Declare_
|
||||
|| $node instanceof Stmt\Function_
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if ( $node instanceof Stmt\Expression ) {
|
||||
$expr = $node->expr;
|
||||
if ( $expr instanceof Expr\FuncCall ) {
|
||||
if ( $expr->name instanceof Node\Name ) {
|
||||
if ( in_array( $expr->name->toString(), [
|
||||
'class_alias',
|
||||
'define'
|
||||
] ) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} elseif ( $expr instanceof Expr\Include_ ) {
|
||||
if ( $expr->type === Expr\Include_::TYPE_REQUIRE_ONCE ) {
|
||||
continue;
|
||||
}
|
||||
} elseif ( $expr instanceof Expr\Assign ) {
|
||||
if ( $expr->var->name === 'maintClass' ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
$line = $node->getLine();
|
||||
$this->assertNull( $node, "Found file scope code in $file at line $line" );
|
||||
}
|
||||
$this->assertTrue( true );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue