From 224b22a051051f6c2e494c3a2fb4adb42898e2d1 Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Tue, 14 Jan 2014 19:24:18 +0100 Subject: Update to MediaWiki 1.22.1 --- includes/DefaultSettings.php | 2 +- includes/HttpFunctions.php | 7 +++- includes/LinksUpdate.php | 1 + includes/Sanitizer.php | 51 +++++++++++++++++++++++++-- includes/WikiPage.php | 15 +++++++- includes/XmlTypeCheck.php | 31 +++++++++++++++- includes/actions/RawAction.php | 3 ++ includes/api/ApiQueryLogEvents.php | 10 ++++-- includes/cache/LocalisationCache.php | 23 ++++++++++++ includes/changes/EnhancedChangesList.php | 5 ++- includes/db/DatabaseMssql.php | 2 +- includes/db/DatabaseMysqlBase.php | 9 ++++- includes/db/DatabaseOracle.php | 2 +- includes/db/DatabasePostgres.php | 30 ++++++++++++++-- includes/db/DatabaseSqlite.php | 2 +- includes/installer/Installer.i18n.php | 25 +++++++------ includes/installer/Installer.php | 2 +- includes/installer/LocalSettingsGenerator.php | 7 +++- includes/installer/OracleInstaller.php | 4 +-- includes/installer/WebInstaller.php | 2 +- includes/installer/WebInstallerPage.php | 17 +++++---- includes/parser/LinkHolderArray.php | 2 +- includes/specials/SpecialUploadStash.php | 2 ++ includes/specials/SpecialWatchlist.php | 16 +++++++++ includes/upload/UploadBase.php | 47 +++++++++++++++++++----- 25 files changed, 266 insertions(+), 51 deletions(-) (limited to 'includes') diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 0fc59fb2..f423e623 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -63,7 +63,7 @@ $wgConf = new SiteConfiguration; * MediaWiki version number * @since 1.2 */ -$wgVersion = '1.22.0'; +$wgVersion = '1.22.1'; /** * Name of the site. It must be changed in LocalSettings.php diff --git a/includes/HttpFunctions.php b/includes/HttpFunctions.php index 78c2ac7a..fa2fc12b 100644 --- a/includes/HttpFunctions.php +++ b/includes/HttpFunctions.php @@ -730,7 +730,12 @@ class CurlHttpRequest extends MWHttpRequest { $this->curlOptions[CURLOPT_PROXY] = $this->proxy; $this->curlOptions[CURLOPT_TIMEOUT] = $this->timeout; - $this->curlOptions[CURLOPT_CONNECTTIMEOUT_MS] = $this->connectTimeout * 1000; + + // Only supported in curl >= 7.16.2 + if ( defined( 'CURLOPT_CONNECTTIMEOUT_MS' ) ) { + $this->curlOptions[CURLOPT_CONNECTTIMEOUT_MS] = $this->connectTimeout * 1000; + } + $this->curlOptions[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0; $this->curlOptions[CURLOPT_WRITEFUNCTION] = $this->callback; $this->curlOptions[CURLOPT_HEADERFUNCTION] = array( $this, "readHeader" ); diff --git a/includes/LinksUpdate.php b/includes/LinksUpdate.php index fdd0e3c1..ed52eb9c 100644 --- a/includes/LinksUpdate.php +++ b/includes/LinksUpdate.php @@ -382,6 +382,7 @@ class LinksUpdate extends SqlDataUpdate { foreach ( $diffs as $url => $dummy ) { foreach ( wfMakeUrlIndexes( $url ) as $index ) { $arr[] = array( + 'el_id' => $this->mDb->nextSequenceValue( 'externallinks_el_id_seq' ), 'el_from' => $this->mId, 'el_to' => $url, 'el_index' => $index, diff --git a/includes/Sanitizer.php b/includes/Sanitizer.php index 499d8218..9e9ac38b 100644 --- a/includes/Sanitizer.php +++ b/includes/Sanitizer.php @@ -865,6 +865,27 @@ class Sanitizer { $value = preg_replace_callback( $decodeRegex, array( __CLASS__, 'cssDecodeCallback' ), $value ); + // Normalize Halfwidth and Fullwidth Unicode block that IE6 might treat as ascii + $value = preg_replace_callback( + '/[!-[]-z]/u', // U+FF01 to U+FF5A, excluding U+FF3C (bug 58088) + function ( $matches ) { + $cp = utf8ToCodepoint( $matches[0] ); + if ( $cp === false ) { + return ''; + } + return chr( $cp - 65248 ); // ASCII range \x21-\x7A + }, + $value + ); + + // Convert more characters IE6 might treat as ascii + // U+0280, U+0274, U+207F, U+029F, U+026A, U+207D, U+208D + $value = str_replace( + array( 'ʀ', 'ɴ', 'ⁿ', 'ʟ', 'ɪ', '⁽', '₍' ), + array( 'r', 'n', 'n', 'l', 'i', '(', '(' ), + $value + ); + // Let the value through if it's nothing but a single comment, to // allow other functions which may reject it to pass some error // message through. @@ -885,10 +906,36 @@ class Sanitizer { } } + // S followed by repeat, iteration, or prolonged sound marks, + // which IE will treat as "ss" + $value = preg_replace( + '/s(?: + \xE3\x80\xB1 | # U+3031 + \xE3\x82\x9D | # U+309D + \xE3\x83\xBC | # U+30FC + \xE3\x83\xBD | # U+30FD + \xEF\xB9\xBC | # U+FE7C + \xEF\xB9\xBD | # U+FE7D + \xEF\xBD\xB0 # U+FF70 + )/ix', + 'ss', + $value + ); + // Reject problematic keywords and control characters - if ( preg_match( '/[\000-\010\016-\037\177]/', $value ) ) { + if ( preg_match( '/[\000-\010\013\016-\037\177]/', $value ) ) { return '/* invalid control char */'; - } elseif ( preg_match( '! expression | filter\s*: | accelerator\s*: | url\s*\( | image\s*\( | image-set\s*\( !ix', $value ) ) { + } elseif ( preg_match( + '! expression + | filter\s*: + | accelerator\s*: + | -o-link\s*: + | -o-link-source\s*: + | -o-replace\s*: + | url\s*\( + | image\s*\( + | image-set\s*\( + !ix', $value ) ) { return '/* insecure input */'; } return $value; diff --git a/includes/WikiPage.php b/includes/WikiPage.php index 7c3dc937..61a05a12 100644 --- a/includes/WikiPage.php +++ b/includes/WikiPage.php @@ -48,9 +48,11 @@ class WikiPage implements Page, IDBAccessObject { public $mDataLoaded = false; // !< Boolean public $mIsRedirect = false; // !< Boolean public $mLatest = false; // !< Integer (false means "not loaded") - public $mPreparedEdit = false; // !< Array /**@}}*/ + /** @var stdclass Map of cache fields (text, parser output, ect) for a proposed/new edit */ + protected $mPreparedEdit = false; + /** * @var int */ @@ -242,6 +244,17 @@ class WikiPage implements Page, IDBAccessObject { $this->mTimestamp = ''; $this->mIsRedirect = false; $this->mLatest = false; + // Bug 57026: do not clear mPreparedEdit since prepareTextForEdit() already checks + // the requested rev ID and immutable content against the cached one. + // Clearing it can cause extra parses on edit for no reason. + } + + /** + * Clear the mPreparedEdit cache field, as may be needed by mutable content types + * @return void + * @since 1.23 + */ + public function clearPreparedEdit() { $this->mPreparedEdit = false; } diff --git a/includes/XmlTypeCheck.php b/includes/XmlTypeCheck.php index 92ca7d80..eb98a4ad 100644 --- a/includes/XmlTypeCheck.php +++ b/includes/XmlTypeCheck.php @@ -39,6 +39,13 @@ class XmlTypeCheck { */ public $rootElement = ''; + /** + * Additional parsing options + */ + private $parserOptions = array( + 'processing_instruction_handler' => '', + ); + /** * @param string $input a filename or string containing the XML element * @param callable $filterCallback (optional) @@ -48,9 +55,13 @@ class XmlTypeCheck { * Filter should return 'true' to toggle on $this->filterMatch * @param boolean $isFile (optional) indicates if the first parameter is a * filename (default, true) or if it is a string (false) + * @param array $options list of additional parsing options: + * processing_instruction_handler: Callback for xml_set_processing_instruction_handler */ - function __construct( $input, $filterCallback = null, $isFile = true ) { + function __construct( $input, $filterCallback = null, $isFile = true, $options = array() ) { $this->filterCallback = $filterCallback; + $this->parserOptions = array_merge( $this->parserOptions, $options ); + if ( $isFile ) { $this->validateFromFile( $input ); } else { @@ -107,6 +118,12 @@ class XmlTypeCheck { // case folding violates XML standard, turn it off xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, false ); xml_set_element_handler( $parser, array( $this, 'rootElementOpen' ), false ); + if ( $this->parserOptions['processing_instruction_handler'] ) { + xml_set_processing_instruction_handler( + $parser, + array( $this, 'processingInstructionHandler' ) + ); + } return $parser; } @@ -181,4 +198,16 @@ class XmlTypeCheck { $this->filterMatch = true; } } + + /** + * @param $parser + * @param $target + * @param $data + */ + private function processingInstructionHandler( $parser, $target, $data ) { + if ( call_user_func( $this->parserOptions['processing_instruction_handler'], $target, $data ) ) { + // Filter hit! + $this->filterMatch = true; + } + } } diff --git a/includes/actions/RawAction.php b/includes/actions/RawAction.php index 32751e45..1a2b3cb1 100644 --- a/includes/actions/RawAction.php +++ b/includes/actions/RawAction.php @@ -94,6 +94,9 @@ class RawAction extends FormlessAction { # Output may contain user-specific data; # vary generated content for open sessions on private wikis $privateCache = !User::isEveryoneAllowed( 'read' ) && ( $smaxage == 0 || session_id() != '' ); + // Bug 53032 - make this private if user is logged in, + // so we don't accidentally cache cookies + $privateCache = $privateCache ?: $this->getUser()->isLoggedIn(); # allow the client to cache this for 24 hours $mode = $privateCache ? 'private' : 'public'; $response->header( 'Cache-Control: ' . $mode . ', s-maxage=' . $smaxage . ', max-age=' . $maxage ); diff --git a/includes/api/ApiQueryLogEvents.php b/includes/api/ApiQueryLogEvents.php index 1a2719ed..26774ef4 100644 --- a/includes/api/ApiQueryLogEvents.php +++ b/includes/api/ApiQueryLogEvents.php @@ -294,18 +294,22 @@ class ApiQueryLogEvents extends ApiQueryBase { if ( $this->fld_ids ) { $vals['logid'] = intval( $row->log_id ); - $vals['pageid'] = intval( $row->page_id ); } if ( $this->fld_title || $this->fld_parsedcomment ) { $title = Title::makeTitle( $row->log_namespace, $row->log_title ); } - if ( $this->fld_title ) { + if ( $this->fld_title || $this->fld_ids ) { if ( LogEventsList::isDeleted( $row, LogPage::DELETED_ACTION ) ) { $vals['actionhidden'] = ''; } else { - ApiQueryBase::addTitleInfo( $vals, $title ); + if ( $this->fld_title ) { + ApiQueryBase::addTitleInfo( $vals, $title ); + } + if ( $this->fld_ids ) { + $vals['pageid'] = intval( $row->page_id ); + } } } diff --git a/includes/cache/LocalisationCache.php b/includes/cache/LocalisationCache.php index 1bfd17bd..25a1e196 100644 --- a/includes/cache/LocalisationCache.php +++ b/includes/cache/LocalisationCache.php @@ -594,6 +594,10 @@ class LocalisationCache { $ruleElements = $ruleset->getElementsByTagName( "pluralRule" ); foreach ( $ruleElements as $elt ) { $ruleType = $elt->getAttribute( 'count' ); + if ( $ruleType === 'other' ) { + // Don't record "other" rules, which have an empty condition + continue; + } $rules[] = $elt->nodeValue; $ruleTypes[] = $ruleType; } @@ -953,6 +957,25 @@ class LocalisationCache { $this->store = new LCStore_Null; $this->manualRecache = false; } + + /** + * Return an array with initialised languages. + * + * @return array + */ + public function getInitialisedLanguages() { + return $this->initialisedLangs; + } + + /** + * Set initialised languages. + * + * @param array $languages Optional array of initialised languages. + */ + public function setInitialisedLanguages( $languages = array() ) { + $this->initialisedLangs = $languages; + } + } /** diff --git a/includes/changes/EnhancedChangesList.php b/includes/changes/EnhancedChangesList.php index 433adb37..4c8aa451 100644 --- a/includes/changes/EnhancedChangesList.php +++ b/includes/changes/EnhancedChangesList.php @@ -200,7 +200,7 @@ class EnhancedChangesList extends ChangesList { if ( $block[0]->mAttribs['rc_log_type'] ) { # Log entry $classes[] = Sanitizer::escapeClass( 'mw-changeslist-log-' - . $block[0]->mAttribs['rc_log_type'] . '-' . $block[0]->mAttribs['rc_title'] ); + . $block[0]->mAttribs['rc_log_type'] ); } else { $classes[] = Sanitizer::escapeClass( 'mw-changeslist-ns' . $block[0]->mAttribs['rc_namespace'] . '-' . $block[0]->mAttribs['rc_title'] ); @@ -551,8 +551,7 @@ class EnhancedChangesList extends ChangesList { $classes = array( 'mw-enhanced-rc' ); if ( $logType ) { # Log entry - $classes[] = Sanitizer::escapeClass( 'mw-changeslist-log-' - . $logType . '-' . $rcObj->mAttribs['rc_title'] ); ++ $classes[] = Sanitizer::escapeClass( 'mw-changeslist-log-' . $logType ); } else { $classes[] = Sanitizer::escapeClass( 'mw-changeslist-ns' . $rcObj->mAttribs['rc_namespace'] . '-' . $rcObj->mAttribs['rc_title'] ); diff --git a/includes/db/DatabaseMssql.php b/includes/db/DatabaseMssql.php index 240a097c..37f5372e 100644 --- a/includes/db/DatabaseMssql.php +++ b/includes/db/DatabaseMssql.php @@ -655,7 +655,7 @@ class DatabaseMssql extends DatabaseBase { * @return string wikitext of a link to the server software's web site */ public function getSoftwareLink() { - return "[http://www.microsoft.com/sql/ MS SQL Server]"; + return "[{{int:version-db-mssql-url}} MS SQL Server]"; } /** diff --git a/includes/db/DatabaseMysqlBase.php b/includes/db/DatabaseMysqlBase.php index 26c9d247..8f12b92d 100644 --- a/includes/db/DatabaseMysqlBase.php +++ b/includes/db/DatabaseMysqlBase.php @@ -681,7 +681,14 @@ abstract class DatabaseMysqlBase extends DatabaseBase { * @return string */ public function getSoftwareLink() { - return '[http://www.mysql.com/ MySQL]'; + $version = $this->getServerVersion(); + if ( strpos( $version, 'MariaDB' ) !== false ) { + return '[{{int:version-db-mariadb-url}} MariaDB]'; + } elseif ( strpos( $version, 'percona' ) !== false ) { + return '[{{int:version-db-percona-url}} Percona Server]'; + } else { + return '[{{int:version-db-mysql-url}} MySQL]'; + } } /** diff --git a/includes/db/DatabaseOracle.php b/includes/db/DatabaseOracle.php index fbaa4da5..32d4d984 100644 --- a/includes/db/DatabaseOracle.php +++ b/includes/db/DatabaseOracle.php @@ -846,7 +846,7 @@ class DatabaseOracle extends DatabaseBase { * @return string wikitext of a link to the server software's web site */ public function getSoftwareLink() { - return '[http://www.oracle.com/ Oracle]'; + return '[{{int:version-db-oracle-url}} Oracle]'; } /** diff --git a/includes/db/DatabasePostgres.php b/includes/db/DatabasePostgres.php index e564a162..aed35f10 100644 --- a/includes/db/DatabasePostgres.php +++ b/includes/db/DatabasePostgres.php @@ -720,6 +720,29 @@ __INDEXATTR__; return false; } + /** + * Change the FOR UPDATE option as necessary based on the join conditions. Then pass + * to the parent function to get the actual SQL text. + * + * In Postgres when using FOR UPDATE, only the main table and tables that are inner joined + * can be locked. That means tables in an outer join cannot be FOR UPDATE locked. Trying to do + * so causes a DB error. This wrapper checks which tables can be locked and adjusts it accordingly. + */ + function selectSQLText( $table, $vars, $conds = '', $fname = __METHOD__, $options = array(), $join_conds = array() ) { + $forUpdateKey = array_search( 'FOR UPDATE', $options ); + if ( $forUpdateKey !== false && $join_conds ) { + unset( $options[$forUpdateKey] ); + + foreach ( $join_conds as $table => $join_cond ) { + if ( 0 === preg_match( '/^(?:LEFT|RIGHT|FULL)(?: OUTER)? JOIN$/i', $join_cond[0] ) ) { + $options['FOR UPDATE'][] = $table; + } + } + } + + return parent::selectSQLText( $table, $vars, $conds, $fname, $options, $join_conds ); + } + /** * INSERT wrapper, inserts an array into a table * @@ -1060,7 +1083,7 @@ __INDEXATTR__; * @return string wikitext of a link to the server software's web site */ public function getSoftwareLink() { - return '[http://www.postgresql.org/ PostgreSQL]'; + return '[{{int:version-db-postgres-url}} PostgreSQL]'; } /** @@ -1399,9 +1422,12 @@ SQL; // : false ); //} - if ( isset( $noKeyOptions['FOR UPDATE'] ) ) { + if ( isset( $options['FOR UPDATE'] ) ) { + $postLimitTail .= ' FOR UPDATE OF ' . implode( ', ', $options['FOR UPDATE'] ); + } else if ( isset( $noKeyOptions['FOR UPDATE'] ) ) { $postLimitTail .= ' FOR UPDATE'; } + if ( isset( $noKeyOptions['DISTINCT'] ) || isset( $noKeyOptions['DISTINCTROW'] ) ) { $startOpts .= 'DISTINCT'; } diff --git a/includes/db/DatabaseSqlite.php b/includes/db/DatabaseSqlite.php index 4a51226f..3e034649 100644 --- a/includes/db/DatabaseSqlite.php +++ b/includes/db/DatabaseSqlite.php @@ -614,7 +614,7 @@ class DatabaseSqlite extends DatabaseBase { * @return string wikitext of a link to the server software's web site */ public function getSoftwareLink() { - return "[http://sqlite.org/ SQLite]"; + return "[{{int:version-db-sqlite-url}} SQLite]"; } /** diff --git a/includes/installer/Installer.i18n.php b/includes/installer/Installer.i18n.php index edf5ff25..16e83e4f 100644 --- a/includes/installer/Installer.i18n.php +++ b/includes/installer/Installer.i18n.php @@ -100,9 +100,8 @@ You should [//www.mediawiki.org/wiki/Unicode_normalization_considerations upgrad 'config-no-db' => 'Could not find a suitable database driver! You need to install a database driver for PHP. The following database types are supported: $1. -If you are on shared hosting, ask your hosting provider to install a suitable database driver. -If you compiled PHP yourself, reconfigure it with a database client enabled, for example using ./configure --with-mysql. -If you installed PHP from a Debian or Ubuntu package, then you also need install the php5-mysql module.', +If you compiled PHP yourself, reconfigure it with a database client enabled, for example, using ./configure --with-mysqli. +If you installed PHP from a Debian or Ubuntu package, then you also need to install, for example, the php5-mysql package.', 'config-outdated-sqlite' => "'''Warning:''' you have SQLite $1, which is lower than minimum required version $2. SQLite will be unavailable.", 'config-no-fts3' => "'''Warning:''' SQLite is compiled without the [//sqlite.org/fts3.html FTS3 module], search features will be unavailable on this backend.", 'config-register-globals' => "'''Warning: PHP's [http://php.net/register_globals register_globals] option is enabled.''' @@ -243,7 +242,7 @@ That includes raw user data (email addresses, hashed passwords) as well as delet Consider putting the database somewhere else altogether, for example in /var/lib/mediawiki/yourwiki.", 'config-oracle-def-ts' => 'Default tablespace:', 'config-oracle-temp-ts' => 'Temporary tablespace:', - 'config-type-mysql' => 'MySQL', + 'config-type-mysql' => 'MySQL (or compatible)', 'config-type-postgres' => 'PostgreSQL', 'config-type-sqlite' => 'SQLite', 'config-type-oracle' => 'Oracle', @@ -252,10 +251,10 @@ Consider putting the database somewhere else altogether, for example in /v $1 If you do not see the database system you are trying to use listed below, then follow the instructions linked above to enable support.', - 'config-support-mysql' => '* $1 is the primary target for MediaWiki and is best supported ([http://www.php.net/manual/en/mysql.installation.php how to compile PHP with MySQL support])', - 'config-support-postgres' => '* $1 is a popular open source database system as an alternative to MySQL ([http://www.php.net/manual/en/pgsql.installation.php how to compile PHP with PostgreSQL support]). There may be some minor outstanding bugs, and it is not recommended for use in a production environment.', - 'config-support-sqlite' => '* $1 is a lightweight database system which is very well supported. ([http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], uses PDO)', - 'config-support-oracle' => '* $1 is a commercial enterprise database. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])', + 'config-dbsupport-mysql' => '* [{{int:version-db-mysql-url}} MySQL] is the primary target for MediaWiki and is best supported. MediaWiki also works with [{{int:version-db-mariadb-url}} MariaDB] and [{{int:version-db-percona-url}} Percona Server], which are MySQL compatible. ([http://www.php.net/manual/en/mysqli.installation.php How to compile PHP with MySQL support])', + 'config-dbsupport-postgres' => '* [{{int:version-db-postgres-url}} PostgreSQL] is a popular open source database system as an alternative to MySQL. There may be some minor outstanding bugs, and it is not recommended for use in a production environment. ([http://www.php.net/manual/en/pgsql.installation.php How to compile PHP with PostgreSQL support])', + 'config-dbsupport-sqlite' => '* [{{int:version-db-sqlite-url}} SQLite] is a lightweight database system that is very well supported. ([http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], uses PDO)', + 'config-dbsupport-oracle' => '* [{{int:version-db-oracle-url}} Oracle] is a commercial enterprise database. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])', 'config-header-mysql' => 'MySQL settings', 'config-header-postgres' => 'PostgreSQL settings', 'config-header-sqlite' => 'SQLite settings', @@ -640,7 +639,7 @@ See also: * {{msg-mw|config-env-php}}', 'config-unicode-pure-php-warning' => 'PECL is the name of a group producing standard pieces of software for PHP, and intl is the name of their library handling some aspects of internationalization.', 'config-unicode-update-warning' => "ICU is a body producing standard software tools for support of Unicode and other internationalization aspects. This message warns the system administrator installing MediaWiki that the server's software is not up-to-date and MediaWiki will have problems handling some characters.", - 'config-no-db' => '{{doc-important|Do not translate "./configure --with-mysql" and "php5-mysql".}} + 'config-no-db' => '{{doc-important|Do not translate "./configure --with-mysqli" and "php5-mysql".}} Parameters: * $1 is comma separated list of database types supported by MediaWiki.', 'config-outdated-sqlite' => 'Used as warning. Parameters: @@ -704,12 +703,12 @@ Message shown when PHP parameter suhosin.get.max_value_length is be * $2 - error message', 'config-sqlite-dir-help' => '{{doc-important|Do not translate .htaccess and /var/lib/mediawiki/yourwiki.}} Used in help box.', - 'config-type-mysql' => '{{optional}}', + 'config-type-mysql' => '"Or compatible" refers to several database systems that are compatible with MySQL, as explained in {{msg-mw|config-dbsupport-mysql}}, and thus also work with this choice of database type.', 'config-type-postgres' => '{{optional}}', 'config-type-sqlite' => '{{optional}}', 'config-type-oracle' => '{{optional}}', 'config-support-info' => 'Parameters: -* $1 - a list of DBMSs that MediaWiki supports, composed with other config-type-* and config-support-* messages.', +* $1 - a list of DBMSs that MediaWiki supports, composed with config-dbsupport-* messages.', 'config-support-mysql' => 'Parameters: * $1 - a link to the MySQL home page having the anchor text "MySQL".', 'config-support-postgres' => 'Parameters: @@ -718,6 +717,10 @@ Used in help box.', * $1 - a link to the SQLite home page having the anchor text "SQLite".', 'config-support-oracle' => 'Parameters: * $1 - a link to the Oracle home page, the anchor text of which is "Oracle".', + 'config-dbsupport-mysql' => 'Used in {{msg-mw|config-support-info}}.', + 'config-dbsupport-postgres' => 'Used in {{msg-mw|config-support-info}}.', + 'config-dbsupport-sqlite' => 'Used in {{msg-mw|config-support-info}}.', + 'config-dbsupport-oracle' => 'Used in {{msg-mw|config-support-info}}.', 'config-invalid-db-server-oracle' => 'Used as error message. Parameters: * $1 - database server name See also: diff --git a/includes/installer/Installer.php b/includes/installer/Installer.php index 36c41910..62bb2ec4 100644 --- a/includes/installer/Installer.php +++ b/includes/installer/Installer.php @@ -1411,7 +1411,7 @@ abstract class Installer { $wgVersion = "1.22"; $wgResourceModules = array(); - require_once( $file ); + require_once $file ; $e = array_values( $wgExtensionCredits ); if( $e ) { $ext = array_values( $e[0] ); diff --git a/includes/installer/LocalSettingsGenerator.php b/includes/installer/LocalSettingsGenerator.php index 5c803d3e..53939826 100644 --- a/includes/installer/LocalSettingsGenerator.php +++ b/includes/installer/LocalSettingsGenerator.php @@ -145,7 +145,12 @@ class LocalSettingsGenerator { $ip = $this->installer->getVar( 'IP' ); foreach ( $this->extensions as $ext) { - $path = str_replace( $ip, '$IP', $extensions[$ext]['path'] ); + $path = str_replace( $ip, '', $extensions[$ext]['path'] ); + $prefix = ''; + if ( $path !== $extensions[$ext]['path'] ) { + $prefix = '$IP'; + } + $path = $prefix . self::escapePhpString( $path ); $localSettings .= "require_once \"$path\";\n"; } } diff --git a/includes/installer/OracleInstaller.php b/includes/installer/OracleInstaller.php index 77575100..8ce74f42 100644 --- a/includes/installer/OracleInstaller.php +++ b/includes/installer/OracleInstaller.php @@ -91,12 +91,12 @@ class OracleInstaller extends DatabaseInstaller { public function submitConnectForm() { // Get variables from the request - $newValues = $this->setVarsFromRequest( + $newValues = $this->setVarsFromRequest( array( 'wgDBserver', 'wgDBprefix', 'wgDBuser', 'wgDBpassword' - ); + ) ); $this->parent->setVar( 'wgDBname', $this->getVar( 'wgDBuser' ) ); // Validate them diff --git a/includes/installer/WebInstaller.php b/includes/installer/WebInstaller.php index 95765259..1f8ee00a 100644 --- a/includes/installer/WebInstaller.php +++ b/includes/installer/WebInstaller.php @@ -917,7 +917,7 @@ class WebInstaller extends Installer { } if ( isset( $params['rawtext'] ) ) { $labelText = $params['rawtext']; - } else if ( isset( $params['label'] ) ) { + } elseif ( isset( $params['label'] ) ) { $labelText = $this->parse( wfMessage( $params['label'] )->text() ); } else { $labelText = ""; diff --git a/includes/installer/WebInstallerPage.php b/includes/installer/WebInstallerPage.php index 7e8a3631..ad399133 100644 --- a/includes/installer/WebInstallerPage.php +++ b/includes/installer/WebInstallerPage.php @@ -480,12 +480,11 @@ class WebInstaller_DBConnect extends WebInstallerPage { $settings = ''; $defaultType = $this->getVar( 'wgDBtype' ); - // Messages: config-support-mysql, config-support-postgres, config-support-oracle, - // config-support-sqlite + // Messages: config-dbsupport-mysql, config-dbsupport-postgres, config-dbsupport-oracle, + // config-dbsupport-sqlite $dbSupport = ''; foreach ( $this->parent->getDBTypes() as $type ) { - $link = DatabaseBase::factory( $type )->getSoftwareLink(); - $dbSupport .= wfMessage( "config-support-$type", $link )->plain() . "\n"; + $dbSupport .= wfMessage( "config-dbsupport-$type" )->plain() . "\n"; } $this->addHTML( $this->parent->getInfoBox( wfMessage( 'config-support-info', trim( $dbSupport ) )->text() ) ); @@ -951,7 +950,7 @@ class WebInstaller_Options extends WebInstallerPage { /* Force a recache, so we load extensions descriptions */ global $wgLang; $lc = Language::getLocalisationCache(); - $lc->initialisedLangs = array(); + $lc->setInitialisedLanguages( array() ); $lc->getItem( $wgLang->mCode, '' ); LinkCache::singleton()->useDatabase( false ); @@ -1184,10 +1183,14 @@ class WebInstaller_Options extends WebInstallerPage { $this->setVar( 'wgRightsIcon', '' ); } - $extsAvailable = array_map( function($e) { if( isset($e['name']) ) return $e['name']; }, $this->parent->findExtensions() ); + $extsAvailable = array_map( + function( $e ) { + if( isset( $e['name'] ) ) { + return $e['name']; + } + }, $this->parent->findExtensions() ); $extsToInstall = array(); foreach ( $extsAvailable as $key => $ext ) { - var_dump("config_ext-$ext"); if ( $this->parent->request->getCheck( 'config_ext-' . $ext ) ) { $extsToInstall[] = $extsAvailable[ $key ]; } diff --git a/includes/parser/LinkHolderArray.php b/includes/parser/LinkHolderArray.php index 27ff9e7d..f1a0b258 100644 --- a/includes/parser/LinkHolderArray.php +++ b/includes/parser/LinkHolderArray.php @@ -281,7 +281,7 @@ class LinkHolderArray { $linkCache = LinkCache::singleton(); $output = $this->parent->getOutput(); - if( $linkCache->useDatabase() ) { + if ( $linkCache->useDatabase() ) { wfProfileIn( __METHOD__ . '-check' ); $dbr = wfGetDB( DB_SLAVE ); $threshold = $this->parent->getOptions()->getStubThreshold(); diff --git a/includes/specials/SpecialUploadStash.php b/includes/specials/SpecialUploadStash.php index 87b64428..1373df1a 100644 --- a/includes/specials/SpecialUploadStash.php +++ b/includes/specials/SpecialUploadStash.php @@ -308,6 +308,8 @@ class SpecialUploadStash extends UnlistedSpecialPage { header( "Content-Type: $contentType", true ); header( 'Content-Transfer-Encoding: binary', true ); header( 'Expires: Sun, 17-Jan-2038 19:14:07 GMT', true ); + // Bug 53032 - It shouldn't be a problem here, but let's be safe and not cache + header( 'Cache-Control: private' ); header( "Content-Length: $size", true ); } diff --git a/includes/specials/SpecialWatchlist.php b/includes/specials/SpecialWatchlist.php index 4afa279e..55dc6efd 100644 --- a/includes/specials/SpecialWatchlist.php +++ b/includes/specials/SpecialWatchlist.php @@ -299,6 +299,22 @@ class SpecialWatchlist extends SpecialPage { } } + // Log entries with DELETED_ACTION must not show up unless the user has + // the necessary rights. + if ( !$user->isAllowed( 'deletedhistory' ) ) { + $bitmask = LogPage::DELETED_ACTION; + } elseif ( !$user->isAllowed( 'suppressrevision' ) ) { + $bitmask = LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED; + } else { + $bitmask = 0; + } + if ( $bitmask ) { + $conds[] = $dbr->makeList( array( + 'rc_type != ' . RC_LOG, + $dbr->bitAnd( 'rc_deleted', $bitmask ) . " != $bitmask", + ), LIST_OR ); + } + ChangeTags::modifyDisplayQuery( $tables, $fields, $conds, $join_conds, $options, '' ); wfRunHooks( 'SpecialWatchlistQuery', array( &$conds, &$tables, &$join_conds, &$fields, $values ) ); diff --git a/includes/upload/UploadBase.php b/includes/upload/UploadBase.php index 2260241d..916ad6c1 100644 --- a/includes/upload/UploadBase.php +++ b/includes/upload/UploadBase.php @@ -250,7 +250,7 @@ abstract class UploadBase { /** * @param string $srcPath the source path - * @return string the real path if it was a virtual URL + * @return string|bool the real path if it was a virtual URL Returns false on failure */ function getRealPath( $srcPath ) { wfProfileIn( __METHOD__ ); @@ -259,12 +259,15 @@ abstract class UploadBase { // @todo just make uploads work with storage paths // UploadFromStash loads files via virtual URLs $tmpFile = $repo->getLocalCopy( $srcPath ); - $tmpFile->bind( $this ); // keep alive with $this - wfProfileOut( __METHOD__ ); - return $tmpFile->getPath(); + if ( $tmpFile ) { + $tmpFile->bind( $this ); // keep alive with $this + } + $path = $tmpFile ? $tmpFile->getPath() : false; + } else { + $path = $srcPath; } wfProfileOut( __METHOD__ ); - return $srcPath; + return $path; } /** @@ -475,9 +478,10 @@ abstract class UploadBase { return array( 'uploadscripted' ); } if ( $this->mFinalExtension == 'svg' || $mime == 'image/svg+xml' ) { - if ( $this->detectScriptInSvg( $this->mTempPath ) ) { + $svgStatus = $this->detectScriptInSvg( $this->mTempPath ); + if ( $svgStatus !== false ) { wfProfileOut( __METHOD__ ); - return array( 'uploadscripted' ); + return $svgStatus; } } } @@ -1158,8 +1162,33 @@ abstract class UploadBase { * @return bool */ protected function detectScriptInSvg( $filename ) { - $check = new XmlTypeCheck( $filename, array( $this, 'checkSvgScriptCallback' ) ); - return $check->filterMatch; + $check = new XmlTypeCheck( + $filename, + array( $this, 'checkSvgScriptCallback' ), + true, + array( 'processing_instruction_handler' => 'UploadBase::checkSvgPICallback' ) + ); + if ( $check->wellFormed !== true ) { + // Invalid xml (bug 58553) + return array( 'uploadinvalidxml' ); + } elseif ( $check->filterMatch ) { + return array( 'uploadscripted' ); + } + return false; + } + + /** + * Callback to filter SVG Processing Instructions. + * @param $target string processing instruction name + * @param $data string processing instruction attribute and value + * @return bool (true if the filter identified something bad) + */ + public static function checkSvgPICallback( $target, $data ) { + // Don't allow external stylesheets (bug 57550) + if ( preg_match( '/xml-stylesheet/i', $target) ) { + return true; + } + return false; } /** -- cgit v1.2.2