Merge "Fix typo in comment"
authortstarling <tstarling@wikimedia.org>
Mon, 26 Mar 2012 23:47:04 +0000 (23:47 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 26 Mar 2012 23:47:04 +0000 (23:47 +0000)
16 files changed:
HISTORY
RELEASE-NOTES-1.19
includes/DefaultSettings.php
includes/EditPage.php
includes/Export.php
includes/OutputPage.php
includes/actions/CreditsAction.php
includes/actions/PurgeAction.php
includes/api/ApiBase.php
includes/api/ApiMain.php
includes/parser/CoreParserFunctions.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php
includes/resourceloader/ResourceLoaderUserOptionsModule.php
includes/specials/SpecialUpload.php
maintenance/backup.inc

diff --git a/HISTORY b/HISTORY
index 14a80d0..3dc2e9a 100644 (file)
--- a/HISTORY
+++ b/HISTORY
@@ -1,27 +1,40 @@
 Change notes from older releases. For current info see RELEASE-NOTES-1.20.
 
 == MediaWiki 1.18 ==
-=== Changes since 1.18.1 ===
+=== Changes since 1.18.2 ===
+* (bug 35446) Using "{{nse:}}" with an invalid namespace name no longer throws
+  a PHP warning.
+
+== MediaWiki 1.18.2 ==
+2012-03-21
+
+This is a maintenance and security release of the MediaWiki 1.18 branch.
 
+=== Changes since 1.18.1 ===
 * (bug 33686) could not get a list of contributor for an article when using
  a SQLite database.
 * (Bug 33865) Exception thrown in action=parse when attempting to use the title
   parameter without setting the text parameter.
 * UserMailer could potentially throw a fatal error when a MailAddress object had
   an empty email address.
+* (Bug 33087) Exchange server rejected mail sent by MediaWiki
 * (bug 34528) Edit section tooltips show correction section name again
 * (bug 34246) MediaWiki:Whatlinkshere-summary message is displayed again in
   Special:Whatlinkshere
-
-=== MediaWiki 1.18.1 ===
+* (bug 22555) Remove or skip strip markers from tag hooks like &lt;nowiki&gt; in
+  core parser functions which operate on strings, such as formatnum.
+* (bug 34212) ApiBlock/ApiUnblock allow action to take place without a token
+  parameter present.
+* (bug 34907) Fixed exposure of tokens through load.php that could have facilitated
+  CSRF attacks.
+* (bug 35317) CSRF in Special:Upload.
+
+== MediaWiki 1.18.1 ==
 2012-01-11
 
 This a maintenance and security release of the MediaWiki 1.18 branch.
 
-==== Security changes ====
-* (bug 33117) prop=revisions allows deleted text to be exposed through cache pollution.
-
-==== Changes since 1.18.0 ====
+=== Changes since 1.18.0 ===
 * (bug 32712) Fix for search indexing of pages with certain unicode chars following URL.
 * (bug 3901) Lang, hreflang attribs added to sidebar interlanguage links for screen readers.
 * (bug 30774) mediawiki.html: Add support for numbers and booleans in the
@@ -47,6 +60,12 @@ This a maintenance and security release of the MediaWiki 1.18 branch.
   all pages.
 * Fixed recentchanges FK violation on page delete and cache purge error in updater
   for Oracle DB.
+* (bug 33117) prop=revisions allows deleted text to be exposed through cache pollution.
+
+== MediaWiki 1.18.0 ==
+2011-11-24
+
+This is the first stable release of the MediaWiki 1.18 branch.
 
 === Summary of selected changes in 1.18 ===
 
index 9255909..7a5d50a 100644 (file)
@@ -11,6 +11,9 @@ This is a beta release of the MediaWiki 1.19 branch. Please test it and let us
 know what you think of it. Beta releases are not recommended for use in
 production.
 
+=== Changes since 1.19 beta 2 ===
+* Special:Watchlist no longer sets links to feed when the user is anonymous
+
 === Changes since 1.19 beta 1 ===
 * (bug 35014) Including a special page no longer sets the page's title to the
   included page.
@@ -33,7 +36,6 @@ production.
   inside a heading.
 * (bug 34907) Fixed exposure of tokens through load.php that could have facilitated
   CSRF attacks
-* Special:Watchlist no longer sets links to feed when the user is anonymous
 
 === Configuration changes in 1.19 ===
 * Removed SkinTemplateSetupPageCss hook; use BeforePageDisplay instead.
index e214b7b..1ca2aba 100644 (file)
@@ -2581,13 +2581,6 @@ $wgResourceLoaderMaxage = array(
        ),
 );
 
-/**
- * Whether to embed private modules inline with HTML output or to bypass
- * caching and check the user parameter against $wgUser to prevent
- * unauthorized access to private modules.
- */
-$wgResourceLoaderInlinePrivateModules = true;
-
 /**
  * The default debug mode (on/off) for of ResourceLoader requests. This will still
  * be overridden when the debug URL parameter is used.
index 8f4761c..31e6626 100644 (file)
@@ -3027,12 +3027,15 @@ HTML
        /**
         * Show "your edit contains spam" page with your diff and text
         *
-        * @param $match string|bool Text which triggered one or more filters
+        * @param $match string|Array|bool Text (or array of texts) which triggered one or more filters
         */
        public function spamPageWithContent( $match = false ) {
-               global $wgOut;
+               global $wgOut, $wgLang;
                $this->textbox2 = $this->textbox1;
 
+               if( is_array( $match ) ){
+                       $match = $wgLang->listToText( $match );
+               }
                $wgOut->prepareErrorPage( wfMessage( 'spamprotectiontitle' ) );
 
                $wgOut->addHTML( '<div id="spamprotected">' );
index 82aa946..0bddd4c 100644 (file)
@@ -794,6 +794,11 @@ class DumpFileOutput extends DumpOutput {
                $this->filename = $file;
        }
 
+       function writeCloseStream( $string ) {
+               parent::writeCloseStream( $string );
+               fclose( $this->handle );
+       }
+
        function write( $string ) {
                fputs( $this->handle, $string );
        }
@@ -854,6 +859,11 @@ class DumpPipeOutput extends DumpFileOutput {
                $this->filename = $file;
        }
 
+       function writeCloseStream( $string ) {
+               parent::writeCloseStream( $string );
+               proc_close( $this->procOpenResource );
+       }
+
        function startCommand( $command ) {
                $spec = array(
                        0 => array( "pipe", "r" ),
index 27804d7..beaca5f 100644 (file)
@@ -2505,7 +2505,7 @@ $templates
         * @return string html <script> and <style> tags
         */
        protected function makeResourceLoaderLink( $modules, $only, $useESI = false, array $extraQuery = array(), $loadCall = false ) {
-               global $wgResourceLoaderUseESI, $wgResourceLoaderInlinePrivateModules;
+               global $wgResourceLoaderUseESI;
 
                if ( !count( $modules ) ) {
                        return '';
@@ -2584,10 +2584,11 @@ $templates
                                continue;
                        }
 
-                       // Support inlining of private modules if configured as such. Note that these
-                       // modules should be loaded from getHeadScripts() before the first loader call.
-                       // Otherwise other modules can't properly use them as dependencies (bug 30914)
-                       if ( $group === 'private' && $wgResourceLoaderInlinePrivateModules ) {
+                       // Inline private modules. These can't be loaded through load.php for security
+                       // reasons, see bug 34907. Note that these modules should be loaded from
+                       // getHeadScripts() before the first loader call. Otherwise other modules can't
+                       // properly use them as dependencies (bug 30914)
+                       if ( $group === 'private' ) {
                                if ( $only == ResourceLoaderModule::TYPE_STYLES ) {
                                        $links .= Html::inlineStyle(
                                                $resourceLoader->makeModuleResponse( $context, $modules )
index cd083c3..f715229 100644 (file)
@@ -30,7 +30,7 @@ class CreditsAction extends FormlessAction {
        }
 
        protected function getDescription() {
-               return wfMsgHtml( 'creditspage' );
+               return $this->msg( 'creditspage' )->escaped();
        }
 
        /**
index 21a6d90..cd58889 100644 (file)
@@ -79,15 +79,15 @@ class PurgeAction extends FormAction {
        }
 
        protected function alterForm( HTMLForm $form ) {
-               $form->setSubmitText( wfMsg( 'confirm_purge_button' ) );
+               $form->setSubmitTextMsg( 'confirm_purge_button' );
        }
 
        protected function preText() {
-               return wfMessage( 'confirm-purge-top' )->parse();
+               return $this->msg( 'confirm-purge-top' )->parse();
        }
 
        protected function postText() {
-               return wfMessage( 'confirm-purge-bottom' )->parse();
+               return $this->msg( 'confirm-purge-bottom' )->parse();
        }
 
        public function onSuccess() {
index a8c3cc7..607c47a 100644 (file)
@@ -282,12 +282,12 @@ abstract class ApiBase extends ContextSource {
                                        if ( is_numeric( $k ) ) {
                                                $msg .= "  $v\n";
                                        } else {
-                                               $v .= ":";
                                                if ( is_array( $v ) ) {
                                                        $msgExample = implode( "\n", array_map( array( $this, 'indentExampleText' ), $v ) );
                                                } else {
                                                        $msgExample = "  $v";
                                                }
+                                               $msgExample .= ":";
                                                $msg .= wordwrap( $msgExample, 100, "\n" ) . "\n    $k\n";
                                        }
                                }
index a3f2c24..15b0861 100644 (file)
@@ -595,7 +595,7 @@ class ApiMain extends ApiBase {
 
                // Die if token required, but not provided (unless there is a gettoken parameter)
                $salt = $module->getTokenSalt();
-               if ( $salt !== false && !isset( $moduleParams['gettoken'] ) ) {
+               if ( $salt !== false && !$moduleParams['gettoken'] ) {
                        if ( !isset( $moduleParams['token'] ) ) {
                                $this->dieUsageMsg( array( 'missingparam', 'token' ) );
                        } else {
index 0abfcef..7614bf5 100644 (file)
@@ -141,7 +141,11 @@ class CoreParserFunctions {
        }
 
        static function nse( $parser, $part1 = '' ) {
-               return wfUrlencode( str_replace( ' ', '_', self::ns( $parser, $part1 ) ) );
+               $ret = self::ns( $parser, $part1 );
+               if ( is_string( $ret ) ) {
+                       $ret = wfUrlencode( str_replace( ' ', '_', $ret ) );
+               }
+               return $ret;
        }
 
        /**
index ffb418a..7a036b8 100644 (file)
@@ -173,7 +173,7 @@ class ResourceLoader {
                        $cache->set( $key, $result );
                } catch ( Exception $exception ) {
                        // Return exception as a comment
-                       $result = "/*\n{$exception->__toString()}\n*/\n";
+                       $result = $this->makeComment( $exception->__toString() );
                }
 
                wfProfileOut( __METHOD__ );
@@ -431,13 +431,20 @@ class ResourceLoader {
                ob_start();
 
                wfProfileIn( __METHOD__ );
-               $exceptions = '';
+               $errors = '';
 
                // Split requested modules into two groups, modules and missing
                $modules = array();
                $missing = array();
                foreach ( $context->getModules() as $name ) {
                        if ( isset( $this->moduleInfos[$name] ) ) {
+                               $module = $this->getModule( $name );
+                               // Do not allow private modules to be loaded from the web.
+                               // This is a security issue, see bug 34907.
+                               if ( $module->getGroup() === 'private' ) {
+                                       $errors .= $this->makeComment( "Cannot show private module \"$name\"" );
+                                       continue;
+                               }
                                $modules[$name] = $this->getModule( $name );
                        } else {
                                $missing[] = $name;
@@ -449,12 +456,11 @@ class ResourceLoader {
                        $this->preloadModuleInfo( array_keys( $modules ), $context );
                } catch( Exception $e ) {
                        // Add exception to the output as a comment
-                       $exceptions .= "/*\n{$e->__toString()}\n*/\n";
+                       $errors .= $this->makeComment( $e->__toString() );
                }
 
                wfProfileIn( __METHOD__.'-getModifiedTime' );
 
-               $private = false;
                // To send Last-Modified and support If-Modified-Since, we need to detect
                // the last modified time
                $mtime = wfTimestamp( TS_UNIX, $wgCacheEpoch );
@@ -463,22 +469,18 @@ class ResourceLoader {
                         * @var $module ResourceLoaderModule
                         */
                        try {
-                               // Bypass Squid and other shared caches if the request includes any private modules
-                               if ( $module->getGroup() === 'private' ) {
-                                       $private = true;
-                               }
                                // Calculate maximum modified time
                                $mtime = max( $mtime, $module->getModifiedTime( $context ) );
                        } catch ( Exception $e ) {
                                // Add exception to the output as a comment
-                               $exceptions .= "/*\n{$e->__toString()}\n*/\n";
+                               $errors .= $this->makeComment( $e->__toString() );
                        }
                }
 
                wfProfileOut( __METHOD__.'-getModifiedTime' );
 
                // Send content type and cache related headers
-               $this->sendResponseHeaders( $context, $mtime, $private );
+               $this->sendResponseHeaders( $context, $mtime );
 
                // If there's an If-Modified-Since header, respond with a 304 appropriately
                if ( $this->tryRespondLastModified( $context, $mtime ) ) {
@@ -490,20 +492,20 @@ class ResourceLoader {
                $response = $this->makeModuleResponse( $context, $modules, $missing );
 
                // Prepend comments indicating exceptions
-               $response = $exceptions . $response;
+               $response = $errors . $response;
 
                // Capture any PHP warnings from the output buffer and append them to the
                // response in a comment if we're in debug mode.
                if ( $context->getDebug() && strlen( $warnings = ob_get_contents() ) ) {
-                       $response = "/*\n$warnings\n*/\n" . $response;
+                       $response = $this->makeComment( $warnings ) . $response;
                }
 
                // Remove the output buffer and output the response
                ob_end_clean();
                echo $response;
 
-               // Save response to file cache unless there are private modules or errors
-               if ( isset( $fileCache ) && !$private && !$exceptions && !$missing ) {
+               // Save response to file cache unless there are errors
+               if ( isset( $fileCache ) && !$errors && !$missing ) {
                        // Cache single modules...and other requests if there are enough hits
                        if ( ResourceFileCache::useFileCache( $context ) ) {
                                if ( $fileCache->isCacheWorthy() ) {
@@ -521,10 +523,9 @@ class ResourceLoader {
         * Send content type and last modified headers to the client.
         * @param $context ResourceLoaderContext
         * @param $mtime string TS_MW timestamp to use for last-modified
-        * @param $private bool True iff response contains any private modules
         * @return void
         */
-       protected function sendResponseHeaders( ResourceLoaderContext $context, $mtime, $private ) {
+       protected function sendResponseHeaders( ResourceLoaderContext $context, $mtime ) {
                global $wgResourceLoaderMaxage;
                // If a version wasn't specified we need a shorter expiry time for updates
                // to propagate to clients quickly
@@ -548,13 +549,8 @@ class ResourceLoader {
                        header( 'Cache-Control: private, no-cache, must-revalidate' );
                        header( 'Pragma: no-cache' );
                } else {
-                       if ( $private ) {
-                               header( "Cache-Control: private, max-age=$maxage" );
-                               $exp = $maxage;
-                       } else {
-                               header( "Cache-Control: public, max-age=$maxage, s-maxage=$smaxage" );
-                               $exp = min( $maxage, $smaxage );
-                       }
+                       header( "Cache-Control: public, max-age=$maxage, s-maxage=$smaxage" );
+                       $exp = min( $maxage, $smaxage );
                        header( 'Expires: ' . wfTimestamp( TS_RFC2822, $exp + time() ) );
                }
        }
@@ -651,6 +647,11 @@ class ResourceLoader {
                return false; // cache miss
        }
 
+       protected function makeComment( $text ) {
+               $encText = str_replace( '*/', '* /', $text );
+               return "/*\n$encText\n*/\n";
+       }
+
        /**
         * Generates code for a response
         *
@@ -675,7 +676,7 @@ class ResourceLoader {
                                $blobs = MessageBlobStore::get( $this, $modules, $context->getLanguage() );
                        } catch ( Exception $e ) {
                                // Add exception to the output as a comment
-                               $exceptions .= "/*\n{$e->__toString()}\n*/\n";
+                               $exceptions .= $this->makeComment( $e->__toString() );
                        }
                } else {
                        $blobs = array();
@@ -754,7 +755,7 @@ class ResourceLoader {
                                }
                        } catch ( Exception $e ) {
                                // Add exception to the output as a comment
-                               $exceptions .= "/*\n{$e->__toString()}\n*/\n";
+                               $exceptions .= $this->makeComment( $e->__toString() );
 
                                // Register module as missing
                                $missing[] = $name;
index 80b767b..ccfc378 100644 (file)
@@ -44,30 +44,7 @@ class ResourceLoaderUserCSSPrefsModule extends ResourceLoaderModule {
                }
 
                global $wgUser;
-
-               if ( $context->getUser() === $wgUser->getName() ) {
-                       return $this->modifiedTime[$hash] = wfTimestamp( TS_UNIX, $wgUser->getTouched() );
-               } else {
-                       return 1;
-               }
-       }
-
-       /**
-        * Fetch the context's user options, or if it doesn't match current user,
-        * the default options.
-        *
-        * @param $context ResourceLoaderContext: Context object
-        * @return Array: List of user options keyed by option name
-        */
-       protected function contextUserOptions( ResourceLoaderContext $context ) {
-               global $wgUser;
-
-               // Verify identity -- this is a private module
-               if ( $context->getUser() === $wgUser->getName() ) {
-                       return $wgUser->getOptions();
-               } else {
-                       return User::getDefaultOptions();
-               }
+               return $this->modifiedTime[$hash] = wfTimestamp( TS_UNIX, $wgUser->getTouched() );
        }
        
        /**
@@ -75,10 +52,10 @@ class ResourceLoaderUserCSSPrefsModule extends ResourceLoaderModule {
         * @return array
         */
        public function getStyles( ResourceLoaderContext $context ) {
-               global $wgAllowUserCssPrefs;
+               global $wgAllowUserCssPrefs, $wgUser;
 
                if ( $wgAllowUserCssPrefs ) {
-                       $options = $this->contextUserOptions( $context );
+                       $options = $wgUser->getOptions();
 
                        // Build CSS rules
                        $rules = array();
index 96b791e..933c55e 100644 (file)
@@ -44,30 +44,7 @@ class ResourceLoaderUserOptionsModule extends ResourceLoaderModule {
                }
 
                global $wgUser;
-
-               if ( $context->getUser() === $wgUser->getName() ) {
-                       return $this->modifiedTime[$hash] = wfTimestamp( TS_UNIX, $wgUser->getTouched() );
-               } else {
-                       return 1;
-               }
-       }
-
-       /**
-        * Fetch the context's user options, or if it doesn't match current user,
-        * the default options.
-        *
-        * @param $context ResourceLoaderContext: Context object
-        * @return Array: List of user options keyed by option name
-        */
-       protected function contextUserOptions( ResourceLoaderContext $context ) {
-               global $wgUser;
-
-               // Verify identity -- this is a private module
-               if ( $context->getUser() === $wgUser->getName() ) {
-                       return $wgUser->getOptions();
-               } else {
-                       return User::getDefaultOptions();
-               }
+               return $this->modifiedTime[$hash] = wfTimestamp( TS_UNIX, $wgUser->getTouched() );
        }
 
        /**
@@ -75,8 +52,9 @@ class ResourceLoaderUserOptionsModule extends ResourceLoaderModule {
         * @return string
         */
        public function getScript( ResourceLoaderContext $context ) {
+               global $wgUser;
                return Xml::encodeJsCall( 'mw.user.options.set',
-                       array( $this->contextUserOptions( $context ) ) );
+                       array( $wgUser->getOptions() ) );
        }
 
        /**
index de8ed7e..fabe4c4 100644 (file)
@@ -111,14 +111,7 @@ class SpecialUpload extends SpecialPage {
 
                // If it was posted check for the token (no remote POST'ing with user credentials)
                $token = $request->getVal( 'wpEditToken' );
-               if( $this->mSourceType == 'file' && $token == null ) {
-                       // Skip token check for file uploads as that can't be faked via JS...
-                       // Some client-side tools don't expect to need to send wpEditToken
-                       // with their submissions, as that's new in 1.16.
-                       $this->mTokenOk = true;
-               } else {
-                       $this->mTokenOk = $this->getUser()->matchEditToken( $token );
-               }
+               $this->mTokenOk = $this->getUser()->matchEditToken( $token );
 
                $this->uploadFormTextTop = '';
                $this->uploadFormTextAfterSummary = '';
index ce8f694..470a513 100644 (file)
@@ -47,6 +47,8 @@ class BackupDumper {
        var $skipFooter = false; // don't output </mediawiki>
        var $startId    = 0;
        var $endId      = 0;
+       var $revStartId = 0;
+       var $revEndId   = 0;
        var $sink       = null; // Output filters
        var $stubText   = false; // include rev_text_id instead of text; for 2-pass dump
        var $dumpUploads = false;