From 670602f082c006326eee311d6e3ab6033d9bcdf9 Mon Sep 17 00:00:00 2001 From: Chad Horohoe Date: Sat, 6 Nov 2010 22:16:19 +0000 Subject: [PATCH] Trying to kill install-utils.inc/old install crap: * Cripple the old installer (entry point is gone, supporting code immediately exits). Keeping the latter for reference still :) * Move posix_isatty() wrapper to Maintenance.php, all CLI scripts include this * Clarify docs on archive() deprecation and removal - hasn't been used going back thru 1.15 * Clarify docs on dbsource() deprecation and removal - was in wide use thru 1.15. 1.16 removed all extension usages * Move the two PHP bug tests to a file with the other installer files, moved them to more logical places in new install/update sequence * Remove mw_have_dl/mw_get_session_save_path, zero callers * Move readconsole() and helpers to be a static method on Maintenance, no extensions have used it since 1.15 either --- config/Installer.php | 25 +--- config/old-index.php | 47 ------ includes/AutoLoader.php | 2 + includes/installer/Installer.i18n.php | 4 + includes/installer/Installer.php | 36 ++++- includes/installer/PhpBugTests.php | 69 +++++++++ maintenance/Maintenance.php | 75 ++++++++++ maintenance/eval.php | 2 +- maintenance/install-utils.inc | 207 +------------------------- maintenance/mcc.php | 2 +- maintenance/update.php | 26 +++- 11 files changed, 217 insertions(+), 278 deletions(-) delete mode 100644 config/old-index.php create mode 100644 includes/installer/PhpBugTests.php diff --git a/config/Installer.php b/config/Installer.php index e2d0134588..544ee4234f 100644 --- a/config/Installer.php +++ b/config/Installer.php @@ -1,31 +1,12 @@ , 2006 Rob Church - * http://www.mediawiki.org/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html + * DO NOT USE ANY OF THIS CODE. BEING RETAINED FOR REFERENCE UNTIL JUST BEFORE + * THE 1.17 BRANCH * * @file */ -if( !defined( 'MEDIAWIKI_INSTALL' ) ) { - die( 'Not an entry point.' ); -} +die( 'Now nearly 100% obsolete!' ); error_reporting( E_ALL | E_STRICT ); header( "Content-type: text/html; charset=utf-8" ); diff --git a/config/old-index.php b/config/old-index.php deleted file mode 100644 index 32912a8cd9..0000000000 --- a/config/old-index.php +++ /dev/null @@ -1,47 +0,0 @@ -, 2006 Rob Church - * http://www.mediawiki.org/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - */ - -# Attempt to set up the include path, to fix problems with relative includes -$IP = dirname( dirname( __FILE__ ) ); -define( 'MW_INSTALL_PATH', $IP ); - -# Define an entry point and include some files -define( "MEDIAWIKI", true ); -define( "MEDIAWIKI_INSTALL", true ); - -# Check for PHP 5 -if ( !function_exists( 'version_compare' ) - || version_compare( phpversion(), '5.0.0' ) < 0 -) { - define( 'MW_PHP4', '1' ); - require( "$IP/includes/DefaultSettings.php" ); - require( "$IP/includes/templates/PHP4.php" ); - exit; -} - -// Isolate the rest of the code so this file can die out cleanly -// if we find we're running under PHP 4.x... We use PHP 5 syntax -// which doesn't parse under 4. -require( dirname( __FILE__ ) . "/Installer.php" ); diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index c3c3739c92..1bdf6aa325 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -450,6 +450,8 @@ $wgAutoloadLocalClasses = array( 'WebInstallerOutput' => 'includes/installer/WebInstallerOutput.php', 'MysqlInstaller' => 'includes/installer/MysqlInstaller.php', 'MysqlUpdater' => 'includes/installer/MysqlUpdater.php', + 'PhpXmlBugTester' => 'includes/installer/PhpBugTests.php', + 'PhpRefCallBugTester' => 'includes/installer/PhpBugTests.php', 'PostgresInstaller' => 'includes/installer/PostgresInstaller.php', 'PostgresUpdater' => 'includes/installer/PostgresUpdater.php', 'SqliteInstaller' => 'includes/installer/SqliteInstaller.php', diff --git a/includes/installer/Installer.i18n.php b/includes/installer/Installer.i18n.php index 107a262eb2..60fb860504 100644 --- a/includes/installer/Installer.i18n.php +++ b/includes/installer/Installer.i18n.php @@ -155,6 +155,10 @@ Installation aborted.", 'config-uploads-safe' => 'The default directory for uploads is safe from arbitrary scripts execution.', 'config-uploads-not-safe' => "'''Warning:''' Your default directory for uploads $1 is vulnerable to arbitrary scripts execution. Although MediaWiki checks all uploaded files for security threats, it is highly recommended to [http://www.mediawiki.org/wiki/Manual:Security#Upload_security close this security vulnerability] before enabling uploads.", + 'config-brokenlibxml' => 'Your system has a combination of PHP and libxml2 versions which is buggy and can cause hidden data corruption in MediaWiki and other web apps. +Upgrade to PHP 5.2.9 or later and libxml2 2.7.3 or later! ABORTING ([http://bugs.php.net/bug.php?id=45996 bug filed with PHP]).', + 'config-using531' => 'PHP $1 is not compatible with MediaWiki due to a bug involving reference parameters to __call(). +Upgrade to PHP 5.3.2 or higher, or downgrade to PHP 5.3.0 to fix this. ABORTING ([http://bugs.php.net/bug.php?id=50394 bug filed with PHP])', 'config-db-type' => 'Database type:', 'config-db-host' => 'Database host:', 'config-db-host-help' => 'If your database server is on different server, enter the host name or IP address here. diff --git a/includes/installer/Installer.php b/includes/installer/Installer.php index 8a2c36f4fd..7b1d4517a2 100644 --- a/includes/installer/Installer.php +++ b/includes/installer/Installer.php @@ -85,6 +85,8 @@ abstract class Installer { 'envCheckMediaWikiVersion', 'envCheckDB', 'envCheckRegisterGlobals', + 'envCheckBrokenXML', + 'envCheckPHP531', 'envCheckMagicQuotes', 'envCheckMagicSybase', 'envCheckMbstring', @@ -470,6 +472,30 @@ abstract class Installer { } } + /** + * Some versions of libxml+PHP break < and > encoding horribly + */ + public function envCheckBrokenXML() { + $test = new PhpXmlBugTester(); + if ( !$test->ok ) { + $this->showMessage( 'config-brokenlibxml' ); + return false; + } + } + + /** + * Test PHP (probably 5.3.1, but it could regress again) to make sure that + * reference parameters to __call() are not converted to null + */ + public function envCheckPHP531() { + $test = new PhpRefCallBugTester; + $test->execute(); + if ( !$test->ok ) { + $this->showMessage( 'config-using531' ); + return false; + } + } + /** * Environment check for magic_quotes_runtime. */ @@ -845,7 +871,7 @@ abstract class Installer { * * @return Array */ - protected function getPossibleBinPaths() { + protected static function getPossibleBinPaths() { return array_merge( array( '/usr/bin', '/usr/local/bin', '/opt/csw/bin', '/usr/gnu/bin', '/usr/sfw/bin', '/sw/bin', '/opt/local/bin' ), @@ -869,7 +895,7 @@ abstract class Installer { * If $versionInfo is not false, only executables with a version * matching $versionInfo[1] will be returned. */ - protected function locateExecutable( $path, $names, $versionInfo = false ) { + public static function locateExecutable( $path, $names, $versionInfo = false ) { if ( !is_array( $names ) ) { $names = array( $names ); } @@ -902,9 +928,9 @@ abstract class Installer { * Same as locateExecutable(), but checks in getPossibleBinPaths() by default * @see locateExecutable() */ - protected function locateExecutableInDefaultPaths( $names, $versionInfo = false ) { - foreach( $this->getPossibleBinPaths() as $path ) { - $exe = $this->locateExecutable( $path, $names, $versionInfo ); + public static function locateExecutableInDefaultPaths( $names, $versionInfo = false ) { + foreach( self::getPossibleBinPaths() as $path ) { + $exe = self::locateExecutable( $path, $names, $versionInfo ); if( $exe !== false ) { return $exe; } diff --git a/includes/installer/PhpBugTests.php b/includes/installer/PhpBugTests.php new file mode 100644 index 0000000000..0dba34a04e --- /dev/null +++ b/includes/installer/PhpBugTests.php @@ -0,0 +1,69 @@ +c'; + $xml = '' . htmlspecialchars( $charData ) . ''; + + $parser = xml_parser_create(); + xml_set_character_data_handler( $parser, array( $this, 'chardata' ) ); + $parsedOk = xml_parse( $parser, $xml, true ); + $this->ok = $parsedOk && ( $this->parsedData == $charData ); + } + public function chardata( $parser, $data ) { + $this->parsedData .= $data; + } +} + +/** + * Test for PHP bug #50394 (PHP 5.3.x conversion to null only, not 5.2.x) + * @see http://bugs.php.net/bug.php?id=45996 + */ +class PhpRefCallBugTester { + public $ok = false; + + function __call( $name, $args ) { + $old = error_reporting( E_ALL & ~E_WARNING ); + call_user_func_array( array( $this, 'checkForBrokenRef' ), $args ); + error_reporting( $old ); + } + + function checkForBrokenRef( &$var ) { + if ( $var ) { + $this->ok = true; + } + } + + function execute() { + $var = true; + call_user_func_array( array( $this, 'foo' ), array( &$var ) ); + } +} diff --git a/maintenance/Maintenance.php b/maintenance/Maintenance.php index 2bc3e67aee..b459c3f474 100644 --- a/maintenance/Maintenance.php +++ b/maintenance/Maintenance.php @@ -18,6 +18,15 @@ if ( version_compare( PHP_VERSION, '5.1.0' ) < 0 ) { "administrator.\n" ); } +// Wrapper for posix_isatty() +if ( !function_exists( 'posix_isatty' ) ) { + # We default as considering stdin a tty (for nice readline methods) + # but treating stout as not a tty to avoid color codes + function posix_isatty( $fd ) { + return !$fd; + } +} + /** * Abstract maintenance class for quickly writing and churning out * maintenance scripts with minimal effort. All that _must_ be defined @@ -1044,6 +1053,72 @@ abstract class Maintenance { return $title; } + /** + * Prompt the console for input + * @param $prompt String what to begin the line with, like '> ' + * @return String response + */ + public static function readconsole( $prompt = '> ' ) { + static $isatty = null; + if ( is_null( $isatty ) ) { + if ( posix_isatty( 0 /*STDIN*/ ) ) { + $isatty = true; + } else { + $isatty = false; + } + } + + if ( $isatty && function_exists( 'readline' ) ) { + return readline( $prompt ); + } else { + if ( $isatty ) { + $st = readlineEmulation( $prompt ); + } else { + if ( feof( STDIN ) ) { + $st = false; + } else { + $st = fgets( STDIN, 1024 ); + } + } + if ( $st === false ) return false; + $resp = trim( $st ); + return $resp; + } + } + + /** + * Emulate readline() + * @param $prompt String what to begin the line with, like '> ' + * @return String + */ + private static function readlineEmulation( $prompt ) { + $bash = array( 'bash' ); + if ( !wfIsWindows() && Installer::locateExecutableInDefaultPaths( $bash ) ) { + $retval = false; + $encPrompt = wfEscapeShellArg( $prompt ); + $command = "read -er -p $encPrompt && echo \"\$REPLY\""; + $encCommand = wfEscapeShellArg( $command ); + $line = wfShellExec( "$bash -c $encCommand", $retval ); + + if ( $retval == 0 ) { + return $line; + } elseif ( $retval == 127 ) { + // Couldn't execute bash even though we thought we saw it. + // Shell probably spit out an error message, sorry :( + // Fall through to fgets()... + } else { + // EOF/ctrl+D + return false; + } + } + + // Fallback... we'll have no editing controls, EWWW + if ( feof( STDIN ) ) { + return false; + } + print $prompt; + return fgets( STDIN, 1024 ); + } } class FakeMaintenance extends Maintenance { diff --git a/maintenance/eval.php b/maintenance/eval.php index 43db368d36..3cc1d16ab7 100644 --- a/maintenance/eval.php +++ b/maintenance/eval.php @@ -53,7 +53,7 @@ if ( $useReadline ) { readline_read_history( $historyFile ); } -while ( ( $line = readconsole( '> ' ) ) !== false ) { +while ( ( $line = Maintenance::readconsole() ) !== false ) { if ( $useReadline ) { readline_add_history( $line ); readline_write_history( $historyFile ); diff --git a/maintenance/install-utils.inc b/maintenance/install-utils.inc index 37f976cfa0..93ca0b5838 100644 --- a/maintenance/install-utils.inc +++ b/maintenance/install-utils.inc @@ -1,182 +1,14 @@ index.php5 \n" . - "to continue installation. ABORTING.\n"; - die( 1 ); - } - - $test = new PhpXmlBugTester(); - if ( !$test->ok ) { - echo "Your system has a combination of PHP and libxml2 versions which is buggy\n" . - "and can cause hidden data corruption in MediaWiki and other web apps.\n" . - "Upgrade to PHP 5.2.9 or later and libxml2 2.7.3 or later!\n" . - "ABORTING (http://bugs.php.net/bug.php?id=45996 for details).\n"; - die( 1 ); - } - - $test = new PhpRefCallBugTester; - $test->execute(); - if ( !$test->ok ) { - echo "PHP 5.3.1 is not compatible with MediaWiki due to a bug involving\n" . - "reference parameters to __call. Upgrade to PHP 5.3.2 or higher, or \n" . - "downgrade to PHP 5.3.0 to fix this.\n" . - "ABORTING (see http://bugs.php.net/bug.php?id=50394 for details)\n"; - die( 1 ); - } - - global $wgCommandLineMode; - $wgCommandLineMode = true; - umask( 000 ); - @set_time_limit( 0 ); -} - /** - * Test for PHP+libxml2 bug which breaks XML input subtly with certain versions. - * http://bugs.php.net/bug.php?id=45996 - * Known fixed with PHP 5.2.9 + libxml2-2.7.3 + * @deprecated Use DatabaseBase::sourceFile(). Will probably be removed in 1.19 */ -class PhpXmlBugTester { - private $parsedData = ''; - public $ok = false; - public function __construct() { - $charData = 'c'; - $xml = '' . htmlspecialchars( $charData ) . ''; - - $parser = xml_parser_create(); - xml_set_character_data_handler( $parser, array( $this, 'chardata' ) ); - $parsedOk = xml_parse( $parser, $xml, true ); - $this->ok = $parsedOk && ( $this->parsedData == $charData ); - } - public function chardata( $parser, $data ) { - $this->parsedData .= $data; - } -} - -/** - * Test for PHP bug #50394 (PHP 5.3.x conversion to null only, not 5.2.x) - */ -class PhpRefCallBugTester { - public $ok = false; - - function __call( $name, $args ) { - $old = error_reporting( E_ALL & ~E_WARNING ); - call_user_func_array( array( $this, 'checkForBrokenRef' ), $args ); - error_reporting( $old ); - } - - function checkForBrokenRef( &$var ) { - if ( $var ) { - $this->ok = true; - } - } - - function execute() { - $var = true; - call_user_func_array( array( $this, 'foo' ), array( &$var ) ); - } -} - -if ( !function_exists( 'posix_isatty' ) ) { - # We default as considering stdin a tty (for nice readline methods) - # but treating stout as not a tty to avoid color codes - function posix_isatty( $fd ) { - return !$fd; - } -} - -function readconsole( $prompt = '' ) { - static $isatty = null; - if ( is_null( $isatty ) ) { - if ( posix_isatty( 0 /*STDIN*/ ) ) { - $isatty = true; - } else { - $isatty = false; - } - } - - if ( $isatty && function_exists( 'readline' ) ) { - return readline( $prompt ); - } else { - if ( $isatty ) { - $st = readlineEmulation( $prompt ); - } else { - if ( feof( STDIN ) ) { - $st = false; - } else { - $st = fgets( STDIN, 1024 ); - } - } - if ( $st === false ) return false; - $resp = trim( $st ); - return $resp; - } -} - -function findExecutable( $name ) { - $paths = explode( PATH_SEPARATOR, getenv( "PATH" ) ); - foreach ( $paths as $path ) { - $full = $path . DIRECTORY_SEPARATOR . $name; - if ( file_exists( $full ) ) { - if ( wfIsWindows() || is_executable( $full ) ) { - return $full; - } - } - } - return false; -} - -function readlineEmulation( $prompt ) { - $bash = "bash"; - if ( !wfIsWindows() && findExecutable( $bash ) ) { - $retval = false; - $encPrompt = wfEscapeShellArg( $prompt ); - $command = "read -er -p $encPrompt && echo \"\$REPLY\""; - $encCommand = wfEscapeShellArg( $command ); - $line = wfShellExec( "$bash -c $encCommand", $retval ); - - if ( $retval == 0 ) { - return $line; - } elseif ( $retval == 127 ) { - // Couldn't execute bash even though we thought we saw it. - // Shell probably spit out an error message, sorry :( - // Fall through to fgets()... - } else { - // EOF/ctrl+D - return false; - } - } - - // Fallback... we'll have no editing controls, EWWW - if ( feof( STDIN ) ) { - return false; - } - print $prompt; - return fgets( STDIN, 1024 ); -} - - -# -# Read and execute SQL commands from a file -# function dbsource( $fname, $db = false ) { wfDeprecated( __METHOD__ ); if ( !$db ) { @@ -189,38 +21,11 @@ function dbsource( $fname, $db = false ) { } } +/** + * @deprecated Use DatabaseBase::patchPath(). Will probably be removed in 1.18 + */ function archive( $name ) { wfDeprecated( __METHOD__ ); $dbr = wfGetDB( DB_SLAVE ); return $dbr->patchPath( $name ); } - -/** - * Get the value of session.save_path - * - * Per http://www.php.net/manual/en/ref.session.php#ini.session.save-path, - * this might have some additional preceding parts which need to be - * ditched - * - * @return string - */ -function mw_get_session_save_path() { - $path = ini_get( 'session.save_path' ); - $path = substr( $path, strrpos( $path, ';' ) ); - return $path; -} - -/** - * Is dl() available to us? - * - * According to http://www.php.net/manual/en/function.dl.php, dl() - * is *not* available when `enable_dl` is off, or under `safe_mode` - * - * @return bool - */ -function mw_have_dl() { - return function_exists( 'dl' ) - && is_callable( 'dl' ) - && wfIniGetBool( 'enable_dl' ) - && !wfIniGetBool( 'safe_mode' ); -} diff --git a/maintenance/mcc.php b/maintenance/mcc.php index 7598179d48..f13c444b58 100644 --- a/maintenance/mcc.php +++ b/maintenance/mcc.php @@ -46,7 +46,7 @@ do { $showhelp = false; $quit = false; - $line = readconsole( '> ' ); + $line = Maintenance::readconsole(); if ( $line === false ) exit; $args = explode( ' ', $line ); diff --git a/maintenance/update.php b/maintenance/update.php index dc0d719724..1443a6d821 100644 --- a/maintenance/update.php +++ b/maintenance/update.php @@ -35,6 +35,30 @@ class UpdateMediaWiki extends Maintenance { return 2 /* Maintenance::DB_ADMIN */; } + private function compatChecks() { + $test = new PhpXmlBugTester(); + if ( !$test->ok ) { + $this->error( + "Your system has a combination of PHP and libxml2 versions which is buggy\n" . + "and can cause hidden data corruption in MediaWiki and other web apps.\n" . + "Upgrade to PHP 5.2.9 or later and libxml2 2.7.3 or later!\n" . + "ABORTING (see http://bugs.php.net/bug.php?id=45996).\n", + true ); + } + + $test = new PhpRefCallBugTester; + $test->execute(); + if ( !$test->ok ) { + $ver = phpversion(); + $this->error( + "PHP $ver is not compatible with MediaWiki due to a bug involving\n" . + "reference parameters to __call. Upgrade to PHP 5.3.2 or higher, or \n" . + "downgrade to PHP 5.3.0 to fix this.\n" . + "ABORTING (see http://bugs.php.net/bug.php?id=50394 for details)\n", + true ); + } + } + function execute() { global $wgVersion, $wgTitle, $wgLang; @@ -44,7 +68,7 @@ class UpdateMediaWiki extends Maintenance { $this->output( "MediaWiki {$wgVersion} Updater\n\n" ); if ( !$this->hasOption( 'skip-compat-checks' ) ) { - install_version_checks(); + $this->compatChecks(); } else { $this->output( "Skipping compatibility checks, proceed at your own risk (Ctrl+C to abort)\n" ); wfCountdown( 5 ); -- 2.20.1