From 2b440f71ea79a15ff4f7b58fdcba9614e1045999 Mon Sep 17 00:00:00 2001 From: daniel Date: Mon, 29 Oct 2012 18:38:11 +0100 Subject: [PATCH] (Bug 41244) Gracefully handle failure to load text blob. This change fixes fatal errors ocurring when Revision::loadText returns false because of a failure to load the text blob. Revision::getContent() should simply return null in such a case. Change-Id: I1e13de14ff15b124b5a2e07155d368595a16fda7 --- includes/Revision.php | 29 ++++++++++++------- .../phpunit/includes/RevisionStorageTest.php | 19 ++++++++++++ 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/includes/Revision.php b/includes/Revision.php index 02eec315ed..fd356e12c8 100644 --- a/includes/Revision.php +++ b/includes/Revision.php @@ -52,7 +52,7 @@ class Revision implements IDBAccessObject { protected $mContentFormat; /** - * @var Content + * @var Content|null|bool */ protected $mContent; @@ -982,25 +982,30 @@ class Revision implements IDBAccessObject { } /** - * Gets the content object for the revision + * Gets the content object for the revision (or null on failure). + * + * Note that for mutable Content objects, each call to this method will return a + * fresh clone. * * @since 1.21 - * @return Content|null + * @return Content|null the Revision's content, or null on failure. */ protected function getContentInternal() { if( is_null( $this->mContent ) ) { // Revision is immutable. Load on demand: - - $handler = $this->getContentHandler(); - $format = $this->getContentFormat(); - if( is_null( $this->mText ) ) { - // Load text on demand: $this->mText = $this->loadText(); } - $this->mContent = ( $this->mText === null || $this->mText === false ) ? null - : $handler->unserializeContent( $this->mText, $format ); + if ( $this->mText !== null && $this->mText !== false ) { + // Unserialize content + $handler = $this->getContentHandler(); + $format = $this->getContentFormat(); + + $this->mContent = $handler->unserializeContent( $this->mText, $format ); + } else { + $this->mContent = false; // negative caching! + } } // NOTE: copy() will return $this for immutable content objects @@ -1399,7 +1404,11 @@ class Revision implements IDBAccessObject { * Lazy-load the revision's text. * Currently hardcoded to the 'text' table storage engine. * +<<<<<<< HEAD * @return String|boolean the revision text, or false on failure +======= + * @return String|bool the revision's text, or false on failure +>>>>>>> (Bug 41244) Gracefully handle failure to load text blob. */ protected function loadText() { wfProfileIn( __METHOD__ ); diff --git a/tests/phpunit/includes/RevisionStorageTest.php b/tests/phpunit/includes/RevisionStorageTest.php index fbaa34cee2..4fa42f35a2 100644 --- a/tests/phpunit/includes/RevisionStorageTest.php +++ b/tests/phpunit/includes/RevisionStorageTest.php @@ -268,6 +268,25 @@ class RevisionStorageTest extends MediaWikiTestCase { $this->assertEquals( 'hello hello.', $rev->getText() ); } + /** + * @covers Revision::getContent + */ + public function testGetContent_failure() + { + $rev = new Revision( array( + 'page' => $this->the_page->getId(), + 'content_model' => $this->the_page->getContentModel(), + 'text_id' => 123456789, // not in the test DB + ) ); + + $this->assertNull( $rev->getContent(), + "getContent() should return null if the revision's text blob could not be loaded." ); + + //NOTE: check this twice, once for lazy initialization, and once with the cached value. + $this->assertNull( $rev->getContent(), + "getContent() should return null if the revision's text blob could not be loaded." ); + } + /** * @covers Revision::getContent */ -- 2.20.1