Merge "Make EditPage robust against null content."
authorReedy <reedy@wikimedia.org>
Thu, 18 Oct 2012 19:14:30 +0000 (19:14 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 18 Oct 2012 19:14:30 +0000 (19:14 +0000)
1  2 
includes/EditPage.php

diff --combined includes/EditPage.php
@@@ -471,7 -471,7 +471,7 @@@ class EditPage 
                $content = $this->getContentObject();
  
                # Use the normal message if there's nothing to display
 -              if ( $this->firsttime && $content->isEmpty() ) {
 +              if ( $this->firsttime && ( $content === false || $content->isEmpty() ) ) {
                        $action = $this->mTitle->exists() ? 'edit' :
                                ( $this->mTitle->isTalkPage() ? 'createtalk' : 'createpage' );
                        throw new PermissionsError( $action, $permErrors );
         * to the original text of the edit.
         *
         * This difers from Article::getContent() that when a missing revision is
-        * encountered the result will be an empty string and not the
+        * encountered the result will be null and not the
         * 'missing-revision' message.
         *
         * @since 1.19
-        * @return string
+        * @return Content|null
         */
        private function getOriginalContent() {
                if ( $this->section == 'new' ) {
                $parserOptions = ParserOptions::newFromUser( $wgUser );
                $content = $page->getContent( Revision::RAW );
  
+               if ( !$content ) {
+                       return $handler->makeEmptyContent();
+               }
                return $content->preloadTransform( $title, $parserOptions );
        }
  
  
                // This is the revision the editor started from
                $baseRevision = $this->getBaseRevision();
-               if ( is_null( $baseRevision ) ) {
+               $baseContent = $baseRevision ? $baseRevision->getContent() : null;
+               if ( is_null( $baseContent ) ) {
                        wfProfileOut( __METHOD__ );
                        return false;
                }
-               $baseContent = $baseRevision->getContent();
  
                // The current state, we want to merge updates into it
                $currentRevision = Revision::loadFromTitle( $db, $this->mTitle );
-               if ( is_null( $currentRevision ) ) {
+               $currentContent = $currentRevision ? $currentRevision->getContent() : null;
+               if ( is_null( $currentContent ) ) {
                        wfProfileOut( __METHOD__ );
                        return false;
                }
-               $currentContent = $currentRevision->getContent();
  
                $handler = ContentHandler::getForModelID( $baseContent->getModel() );
  
        }
  
        /**
 -       * Gets an editable textual representation of the given Content object.
 +       * Gets an editable textual representation of $content.
         * The textual representation can be turned by into a Content object by the
         * toEditContent() method.
         *
 +       * If $content is null or false or a string, $content is returned unchanged.
 +       *
         * If the given Content object is not of a type that can be edited using the text base EditPage,
         * an exception will be raised. Set $this->allowNonTextContent to true to allow editing of non-textual
         * content.
         *
 -       * @param Content $content
 +       * @param Content|null|false|string $content
         * @return String the editable text form of the content.
         *
         * @throws MWException if $content is not an instance of TextContent and $this->allowNonTextContent is not true.
         */
 -      protected function toEditText( Content $content ) {
 +      protected function toEditText( $content ) {
 +              if ( $content === null || $content === false ) {
 +                      return $content;
 +              }
 +
 +              if ( is_string( $content ) ) {
 +                      return $content;
 +              }
 +
                if ( !$this->allowNonTextContent && !( $content instanceof TextContent ) ) {
                        throw new MWException( "This content model can not be edited as text: "
                                                                . ContentHandler::getLocalizedName( $content->getModel() ) );
                                                        $this->section, $textboxContent,
                                                        $this->summary, $this->edittime );
  
 -              ContentHandler::runLegacyHooks( 'EditPageGetDiffText', array( $this, &$newContent ) );
 -              wfRunHooks( 'EditPageGetDiffContent', array( $this, &$newContent ) );
 +              if ( $newContent ) {
 +                      ContentHandler::runLegacyHooks( 'EditPageGetDiffText', array( $this, &$newContent ) );
 +                      wfRunHooks( 'EditPageGetDiffContent', array( $this, &$newContent ) );
  
 -              $popts = ParserOptions::newFromUserAndLang( $wgUser, $wgContLang );
 -              $newContent = $newContent->preSaveTransform( $this->mTitle, $wgUser, $popts );
 +                      $popts = ParserOptions::newFromUserAndLang( $wgUser, $wgContLang );
 +                      $newContent = $newContent->preSaveTransform( $this->mTitle, $wgUser, $popts );
 +              }
  
                if ( ( $oldContent && !$oldContent->isEmpty() ) || ( $newContent && !$newContent->isEmpty() ) ) {
                        $oldtitle = wfMessage( $oldtitlemsg )->parse();
                        $newtitle = wfMessage( 'yourtext' )->parse();
  
 +                      if ( !$oldContent ) {
 +                              $oldContent = $newContent->getContentHandler()->makeEmptyContent();
 +                      }
 +
 +                      if ( !$newContent ) {
 +                              $newContent = $oldContent->getContentHandler()->makeEmptyContent();
 +                      }
 +
                        $de = $oldContent->getContentHandler()->createDifferenceEngine( $this->mArticle->getContext() );
                        $de->setContent( $oldContent, $newContent );