From d0e16713bcf0a065d22caad2125cc25d4d9245ef Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Fri, 1 Aug 2014 12:23:09 -0400 Subject: [PATCH] Check for result size failure in ApiQuery If someone sets $wgAPIMaxResultSize crazily small and then queries a large number of pages, it can cause ApiQuery to fail to populate the 'pages' node. Then submodules might add data to the node, leading to errors from the XML formatter (or bogus output from other formatters). While that particular failure mode is probably going away soon, it's still good to catch the error situation. Bug: 68989 Change-Id: If0b2eda421fd86dd7acc4fe48cec47741e214221 --- includes/api/ApiQuery.php | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/includes/api/ApiQuery.php b/includes/api/ApiQuery.php index 94727cb470..606012c485 100644 --- a/includes/api/ApiQuery.php +++ b/includes/api/ApiQuery.php @@ -348,29 +348,29 @@ class ApiQuery extends ApiBase { $pageSet = $this->getPageSet(); $result = $this->getResult(); - // We don't check for a full result set here because we can't be adding - // more than 380K. The maximum revision size is in the megabyte range, - // and the maximum result size must be even higher than that. + // We can't really handle max-result-size failure here, but we need to + // check anyway in case someone set the limit stupidly low. + $fit = true; $values = $pageSet->getNormalizedTitlesAsResult( $result ); if ( $values ) { - $result->addValue( 'query', 'normalized', $values ); + $fit = $fit && $result->addValue( 'query', 'normalized', $values ); } $values = $pageSet->getConvertedTitlesAsResult( $result ); if ( $values ) { - $result->addValue( 'query', 'converted', $values ); + $fit = $fit && $result->addValue( 'query', 'converted', $values ); } $values = $pageSet->getInterwikiTitlesAsResult( $result, $this->mParams['iwurl'] ); if ( $values ) { - $result->addValue( 'query', 'interwiki', $values ); + $fit = $fit && $result->addValue( 'query', 'interwiki', $values ); } $values = $pageSet->getRedirectTitlesAsResult( $result ); if ( $values ) { - $result->addValue( 'query', 'redirects', $values ); + $fit = $fit && $result->addValue( 'query', 'redirects', $values ); } $values = $pageSet->getMissingRevisionIDsAsResult( $result ); if ( $values ) { - $result->addValue( 'query', 'badrevids', $values ); + $fit = $fit && $result->addValue( 'query', 'badrevids', $values ); } // Page elements @@ -426,12 +426,21 @@ class ApiQuery extends ApiBase { // json treats all map keys as strings - converting to match $pageIDs = array_map( 'strval', $pageIDs ); $result->setIndexedTagName( $pageIDs, 'id' ); - $result->addValue( 'query', 'pageids', $pageIDs ); + $fit = $fit && $result->addValue( 'query', 'pageids', $pageIDs ); } $result->setIndexedTagName( $pages, 'page' ); - $result->addValue( 'query', 'pages', $pages ); + $fit = $fit && $result->addValue( 'query', 'pages', $pages ); } + + if ( !$fit ) { + $this->dieUsage( + 'The value of $wgAPIMaxResultSize on this wiki is ' . + 'too small to hold basic result information', + 'badconfig' + ); + } + if ( $this->mParams['export'] ) { $this->doExport( $pageSet, $result ); } -- 2.20.1