r85392 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r85391‎ | r85392 | r85393 >
Date:23:09, 4 April 2011
Author:happy-melon
Status:reverted (Comments)
Tags:
Comment:
Fix for catchable fatals thrown on invalid titles, follow-up to miscellaneous Context commit pulled out of a hat (let's go for r85252). We must always have a Title object, even on invalid titles, for the purposes of not melting the Skin. The previous method was to make that a barely-existent half-title from SpecialPage::getTitleFor( 'Badtitle' ), where that is a special page which is not actually defined, but exists in the localisation alias lists. Instead, subclass Title as an explicit BadTitle which we can test for. The badtitle error page, which has empty string for its name in all forms, would probably be quite a good test of our JavaScript error checking.
Modified paths:
  • /trunk/extensions/CreateBox/CreateBox.php (modified) (history)
  • /trunk/phase3/includes/AutoLoader.php (modified) (history)
  • /trunk/phase3/includes/Title.php (modified) (history)
  • /trunk/phase3/includes/Wiki.php (modified) (history)
  • /trunk/phase3/languages/messages/MessagesEn.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/Title.php
@@ -4215,3 +4215,37 @@
42164216 return $unprefixed;
42174217 }
42184218 }
 4219+
 4220+/**
 4221+ * A BadTitle is generated in MediaWiki::parseTitle() if the title is invalid; the
 4222+ * software uses this to display an error page. Internally it's basically a Title
 4223+ * for an empty special page
 4224+ */
 4225+class BadTitle extends Title {
 4226+ public function __construct(){
 4227+ $this->mTextform = '';
 4228+ $this->mUrlform = '';
 4229+ $this->mDbkeyform = '';
 4230+ $this->mNamespace = NS_SPECIAL; // Stops talk page link, etc, being shown
 4231+ }
 4232+
 4233+ public function exists(){
 4234+ return false;
 4235+ }
 4236+
 4237+ public function getPrefixedText(){
 4238+ return '';
 4239+ }
 4240+
 4241+ public function getText(){
 4242+ return '';
 4243+ }
 4244+
 4245+ public function getPrefixedURL(){
 4246+ return '';
 4247+ }
 4248+
 4249+ public function getPrefixedDBKey(){
 4250+ return '';
 4251+ }
 4252+}
\ No newline at end of file
Index: trunk/phase3/includes/Wiki.php
@@ -137,8 +137,9 @@
138138 $ret = Title::newFromURL( $title );
139139 // check variant links so that interwiki links don't have to worry
140140 // about the possible different language variants
141 - if ( count( $wgContLang->getVariants() ) > 1 && !is_null( $ret ) && $ret->getArticleID() == 0 )
 141+ if ( count( $wgContLang->getVariants() ) > 1 && !is_null( $ret ) && $ret->getArticleID() == 0 ){
142142 $wgContLang->findVariantLink( $title, $ret );
 143+ }
143144 }
144145 // For non-special titles, check for implicit titles
145146 if ( is_null( $ret ) || $ret->getNamespace() != NS_SPECIAL ) {
@@ -151,6 +152,10 @@
152153 $ret = $rev ? $rev->getTitle() : $ret;
153154 }
154155 }
 156+
 157+ if( $ret === null || ( $ret->getDBkey() == '' && $ret->getInterwiki() == '' ) ){
 158+ $ret = new BadTitle;
 159+ }
155160 return $ret;
156161 }
157162
@@ -178,8 +183,7 @@
179184 wfProfileIn( __METHOD__ );
180185
181186 // Invalid titles. Bug 21776: The interwikis must redirect even if the page name is empty.
182 - if ( is_null( $this->context->title ) || ( ( $this->context->title->getDBkey() == '' ) && ( $this->context->title->getInterwiki() == '' ) ) ) {
183 - $this->context->title = SpecialPage::getTitleFor( 'Badtitle' );
 187+ if ( $this->context->title instanceof BadTitle ) {
184188 // Die now before we mess up $wgArticle and the skin stops working
185189 throw new ErrorPageError( 'badtitle', 'badtitletext' );
186190
@@ -193,12 +197,12 @@
194198 unset( $query['title'] );
195199 $url = $this->context->title->getFullURL( $query );
196200 }
197 - /* Check for a redirect loop */
 201+ // Check for a redirect loop
198202 if ( !preg_match( '/^' . preg_quote( $this->getVal( 'Server' ), '/' ) . '/', $url ) && $this->context->title->isLocal() ) {
199203 // 301 so google et al report the target as the actual url.
200204 $this->context->output->redirect( $url, 301 );
201205 } else {
202 - $this->context->title = SpecialPage::getTitleFor( 'Badtitle' );
 206+ $this->context->title = new BadTitle;
203207 wfProfileOut( __METHOD__ );
204208 throw new ErrorPageError( 'badtitle', 'badtitletext' );
205209 }
@@ -244,14 +248,14 @@
245249 }
246250 // Special pages
247251 } else if ( NS_SPECIAL == $this->context->title->getNamespace() ) {
248 - /* actions that need to be made when we have a special pages */
 252+ // actions that need to be made when we have a special pages
249253 SpecialPage::executePath( $this->context->title, $this->context );
250254 } else {
251 - /* No match to special cases */
 255+ // No match to special cases
252256 wfProfileOut( __METHOD__ );
253257 return false;
254258 }
255 - /* Did match a special case */
 259+ // Did match a special case
256260 wfProfileOut( __METHOD__ );
257261 return true;
258262 }
@@ -514,10 +518,10 @@
515519 break;
516520 case 'submit':
517521 if ( session_id() == '' ) {
518 - /* Send a cookie so anons get talk message notifications */
 522+ // Send a cookie so anons get talk message notifications
519523 wfSetupSession();
520524 }
521 - /* Continue... */
 525+ // Continue...
522526 case 'edit':
523527 if ( wfRunHooks( 'CustomEditor', array( $article, $this->context->user ) ) ) {
524528 $internal = $this->context->request->getVal( 'internaledit' );
Index: trunk/phase3/includes/AutoLoader.php
@@ -22,6 +22,7 @@
2323 'AuthPlugin' => 'includes/AuthPlugin.php',
2424 'AuthPluginUser' => 'includes/AuthPlugin.php',
2525 'Autopromote' => 'includes/Autopromote.php',
 26+ 'BadTitle' => 'includes/Title.php',
2627 'BacklinkCache' => 'includes/BacklinkCache.php',
2728 'Block' => 'includes/Block.php',
2829 'CacheDependency' => 'includes/CacheDependency.php',
Index: trunk/phase3/languages/messages/MessagesEn.php
@@ -382,7 +382,6 @@
383383 'Allmessages' => array( 'AllMessages' ),
384384 'Allpages' => array( 'AllPages' ),
385385 'Ancientpages' => array( 'AncientPages' ),
386 - 'Badtitle' => array( 'Badtitle' ),
387386 'Blankpage' => array( 'BlankPage' ),
388387 'Block' => array( 'Block', 'BlockIP', 'BlockUser' ),
389388 'Blockme' => array( 'BlockMe' ),
Index: trunk/extensions/CreateBox/CreateBox.php
@@ -63,7 +63,7 @@
6464 $title = Title::newFromText( $prefix . $text );
6565 if( is_null( $title ) ) {
6666 global $wgTitle;
67 - $wgTitle = SpecialPage::getTitleFor( 'Badtitle' );
 67+ $wgTitle = new BadTitle;
6868 throw new ErrorPageError( 'badtitle', 'badtitletext' );
6969 } elseif( $title->getArticleID() == 0 ) {
7070 acRedirect( $title, 'edit' );

Follow-up revisions

RevisionCommit summaryAuthorDate
r95521Undo r85392 ('revert' is a strong word since a lot has changed in the interve...happy-melon21:03, 25 August 2011

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r85252Followup r85250; Revert a static method back to use of $wgRequest... :/ damni...dantman12:55, 3 April 2011

Comments

#Comment by Brion VIBBER (talk | contribs)   23:42, 21 June 2011

Subclassing Title in general can be a bit dangerous as titles frequently get round-tripped through text or (ns, dbkey) forms... here, we export the title to JavaScript through mediawiki's config globals (wgCanonicalNamespace, wgCanonicalSpecialPageName, wgNamespaceNumber, wgPageName, and wgTitle).

Exporting a broken empty title seems a bit funky to me, and could cause issues with JavaScript that might be expecting to process the title params in some generic way; for instance some gadget or site JS bit might fail while running due to mucking up the title and die early, possibly failing to execute later bits that do UI customization that should still be on such an error page.

The current code in 1.17 exports 'Special:Badtitle', which is a valid parseable title and can be detected programatically using its canonical special page name.

#Comment by Happy-melon (talk | contribs)   21:04, 25 August 2011

Reverted in r95521.

Status & tagging log