(bug 41337) Fix fatal error in Special:Preferences
authorAlexandre Emsenhuber <ialex.wiki@gmail.com>
Thu, 1 Nov 2012 21:07:37 +0000 (22:07 +0100)
committerAntoine Musso <hashar@free.fr>
Wed, 15 May 2013 08:47:43 +0000 (10:47 +0200)
The error is Fatal error: Call to a member function msg() on a
non-object at includes/Preferences.php on line 1207.

The problem is that fields created in Preferences::getPreferences() for
validation don't have their parent set and thus an error occurs when the
validation fails since they want to use their parent to get a Message
object.

This commit adds a dummy parent object to these fields to fix the error.

bug: 41337
Change-Id: I5826d6e3f1262c8d26af0cfe7074a939f80bcaca

includes/Preferences.php
tests/phpunit/includes/specials/SpecialPreferencesTest.php [new file with mode: 0644]

index bb386f2..d83f43a 100644 (file)
@@ -90,10 +90,14 @@ class Preferences {
                        }
                }
 
+               ## Make sure that form fields have their parent set. See bug 41337.
+               $dummyForm = new HTMLForm( array(), $context );
+
                ## Prod in defaults from the user
                foreach ( $defaultPreferences as $name => &$info ) {
                        $prefFromUser = self::getOptionFromUser( $name, $info, $user );
                        $field = HTMLForm::loadInputFromParameters( $name, $info ); // For validation
+                       $field->mParent = $dummyForm;
                        $defaultOptions = User::getDefaultOptions();
                        $globalDefault = isset( $defaultOptions[$name] )
                                ? $defaultOptions[$name]
diff --git a/tests/phpunit/includes/specials/SpecialPreferencesTest.php b/tests/phpunit/includes/specials/SpecialPreferencesTest.php
new file mode 100644 (file)
index 0000000..d4bba61
--- /dev/null
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Test class for SpecialPreferences class.
+ *
+ * Copyright © 2013, Antoine Musso
+ * Copyright © 2013, Wikimedia Foundation Inc.
+ *
+ */
+
+class SpecialPreferencesTest extends MediaWikiTestCase {
+
+       /**
+        * Make sure a nickname which is longer than $wgMaxSigChars
+        * is not throwing a fatal error.
+        *
+        * Test specifications by Alexandre "ialex" Emsenhuber.
+        */
+       function testBug41337() {
+
+               // Set a low limit
+               $this->setMwGlobals( 'wgMaxSigChars', 2 );
+
+               $user = $this->getMock( 'User' );
+               $user->expects( $this->any() )
+                       ->method('isAnon')
+                       ->will( $this->returnValue(false) );
+
+               # Yeah foreach requires an array, not NULL =(
+               $user->expects( $this->any() )
+                       ->method('getEffectiveGroups')
+                       ->will( $this->returnValue( array() ) );
+
+               # The mocked user has a long nickname
+               $user->expects( $this->any() )
+                       ->method('getOption')
+                       ->will( $this->returnValueMap( array(
+                               array( 'nickname', null, false, 'superlongnickname' ),
+                       )
+                       ) );
+
+               # Validate the mock (FIXME should probably be removed)
+               $this->assertFalse( $user->isAnon() );
+               $this->assertEquals( array(),
+                       $user->getEffectiveGroups() );
+               $this->assertEquals( 'superlongnickname',
+                       $user->getOption( 'nickname' ) );
+
+               # Forge a request to call the special page
+               $context = new RequestContext();
+               $context->setRequest( new FauxRequest() );
+               $context->setUser( $user );
+               $context->setTitle( Title::newFromText( 'Test' ) );
+
+               # Do the call, should not spurt a fatal error.
+               $special = new SpecialPreferences();
+               $special->setContext( $context );
+               $special->execute( array() );
+       }
+
+}