From: Roan Kattouw Date: Sun, 2 Dec 2007 00:22:32 +0000 (+0000) Subject: Reverting prop=revisions diff generation: way too expensive and DoS-vulnerable X-Git-Tag: 1.31.0-rc.0~50622 X-Git-Url: https://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/banques/?a=commitdiff_plain;h=09149d5082c85f97a6a3d995d3c2fbabcf6803ed;p=lhc%2Fweb%2Fwiklou.git Reverting prop=revisions diff generation: way too expensive and DoS-vulnerable --- diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 3018e5a640..01d3e03ea5 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -86,7 +86,6 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN * Show a warning message when creating/editing a user (talk) page but the user does not exists * (bug 8396) Ignore out-of-date serialised message caches -* (bug 943) RSS feed for Recentchangeslinked === Bug fixes in 1.12 === @@ -306,8 +305,6 @@ Full API documentation is available at http://www.mediawiki.org/wiki/API * Outputting list of all user preferences rather than having to request them by name * (bug 11206) api.php should honor maxlag -* Added diff generation to prop=revisions -* Added support for traditional, unified and array diffs to prop=revisions * Make prop=info check for restrictions in the old format too. * Add apihighlimits permission, default for sysops and bots * Add limit=max to use maximal limit diff --git a/includes/api/ApiQueryRevisions.php b/includes/api/ApiQueryRevisions.php index dc75c21fd3..1c14c8770b 100644 --- a/includes/api/ApiQueryRevisions.php +++ b/includes/api/ApiQueryRevisions.php @@ -45,14 +45,14 @@ class ApiQueryRevisions extends ApiQueryBase { $fld_comment = false, $fld_user = false, $fld_content = false; public function execute() { - $limit = $startid = $endid = $start = $end = $dir = $prop = $user = $excludeuser = $diffto = $difftoprev = $diffformat = $token = null; + $limit = $startid = $endid = $start = $end = $dir = $prop = $user = $excludeuser = $token = null; extract($this->extractRequestParams()); // If any of those parameters are used, work in 'enumeration' mode. // Enum mode can only be used when exactly one page is provided. // Enumerating revisions on multiple pages make it extremely // difficult to manage continuations and require additional SQL indexes - $enumRevMode = (!is_null($user) || !is_null($excludeuser) || !is_null($limit) || !is_null($startid) || !is_null($endid) || $dir === 'newer' || !is_null($start) || !is_null($end) | $difftoprev); + $enumRevMode = (!is_null($user) || !is_null($excludeuser) || !is_null($limit) || !is_null($startid) || !is_null($endid) || $dir === 'newer' || !is_null($start) || !is_null($end)); $pageSet = $this->getPageSet(); @@ -67,7 +67,7 @@ class ApiQueryRevisions extends ApiQueryBase { $this->dieUsage('The revids= parameter may not be used with the list options (limit, startid, endid, dirNewer, start, end).', 'revids'); if ($pageCount > 1 && $enumRevMode) - $this->dieUsage('titles, pageids or a generator was used to supply multiple pages, but the limit, startid, endid, dirNewer, user, excludeuser, start, end and difftoprev parameters may only be used on a single page.', 'multpages'); + $this->dieUsage('titles, pageids or a generator was used to supply multiple pages, but the limit, startid, endid, dirNewer, user, excludeuser, start and end parameters may only be used on a single page.', 'multpages'); $this->addTables('revision'); $this->addWhere('rev_deleted=0'); @@ -90,43 +90,6 @@ class ApiQueryRevisions extends ApiQueryBase { $this->tok_rollback = $this->getTokenFlag($token, 'rollback'); } - if($diffto || $difftoprev) - switch($diffformat) - { - // To add your own formatter, create a subclass of DiffFormatter - // in DifferenceEngine.php, then add it here - case 'traditional': - $this->formatter = new DiffFormatter; - break; - case 'unified': - $this->formatter = new UnifiedDiffFormatter; - break; - case 'array': - $this->formatter = new ArrayDiffFormatter; - break; - } - if($diffto) - { - global $wgContLang; - $difftoRev = Revision::newFromID($diffto); - if(!($difftoRev instanceof Revision)) - $this->dieUsage("There is no revision with ID $diffto", 'nosuchrev'); - $this->diffOldText = $difftoRev->revText(); - if($this->diffOldText == '') // deleted revision - $this->dieUsage("There is no revision with ID $diffto", 'nosuchrev'); // fake non-existence - $this->diffOldText = explode("\n", $wgContLang->segmentForDiff($this->diffOldText)); - $this->diffto = $diffto; - } - else - $this->diffto = false; - if($difftoprev) - { - $this->revCache = array(); - $this->difftoprev = true; - } - else - $this->difftoprev = false; - if (isset ($prop['user'])) { $this->addFields('rev_user'); $this->addFields('rev_user_text'); @@ -135,7 +98,7 @@ class ApiQueryRevisions extends ApiQueryBase { else if($this->tok_rollback) $this->addFields('rev_user_text'); - if (isset ($prop['content']) || !is_null($diffto) || $difftoprev) { + if (isset ($prop['content'])) { // For each page we will request, the user must have read rights for that page foreach ($pageSet->getGoodTitles() as $title) { @@ -151,13 +114,13 @@ class ApiQueryRevisions extends ApiQueryBase { $this->addFields('old_text'); $this->addFields('old_flags'); - $this->fld_content = isset($prop['content']); + $this->fld_content = true; $this->expandTemplates = $expandtemplates; } - $userMax = ($this->fld_content || $diffto || $difftoprev ? 50 : 500); - $botMax = ($this->fld_content || $diffto || $difftoprev ? 200 : 10000); + $userMax = ($this->fld_content ? 50 : 500); + $botMax = ($this->fld_content ? 200 : 10000); if ($enumRevMode) { @@ -250,54 +213,6 @@ class ApiQueryRevisions extends ApiQueryBase { } $db->freeResult($res); - if($this->difftoprev) - { - global $wgContLang; - ksort($this->revCache, SORT_NUMERIC); - $previousRevID = null; - $oldText = null; - $data =& $this->getResult()->getData(); - $pageID = current(array_keys($pageSet->getGoodTitles())); - $this->diffArr = array(); - foreach($this->revCache as $revid => $revtext) - { - $r = array(); - if(is_null($previousRevID)) - { - // First run - $previousRevID = $revid; - $oldText = explode("\n", $wgContLang->segmentForDiff($revtext)); - continue; - } - $newText = explode("\n", $wgContLang->segmentForDiff($revtext)); - $diff = new Diff($oldText, $newText); - $r['from'] = $previousRevID; - $formatted = $this->formatter->format($diff); - if(!is_array($formatted)) - ApiResult::setContent($r, $wgContLang->unsegmentForDiff($this->formatter->format($diff))); - else - { - $r['differences'] = $formatted; - $this->getResult()->setIndexedTagName($r['differences'], 'diff'); - } - $this->diffArr[$revid] = $r; - - $previousRevID = $revid; - $oldText = $newText; - } - - if ( $this->diffArr ) { - # Populate the query result with the contents of $this->diffArr. - $knownrevs = array_keys($this->diffArr); - $i = count($knownrevs) - 1; - foreach($data['query']['pages'][$pageID]['revisions'] as &$rev) { - if ( $i >= 0 && isset ( $this->diffArr[$knownrevs[$i]] ) ) - $rev['difftoprev'] = $this->diffArr[$knownrevs[$i]]; - $i --; - } - } - } - // Ensure that all revisions are shown as '' elements $result = $this->getResult(); if ($result->getIsRawMode()) { @@ -348,35 +263,15 @@ class ApiQueryRevisions extends ApiQueryBase { $vals['rollbacktoken'] = $wgUser->editToken(array($title->getPrefixedText(), $row->rev_user_text)); } - if ($this->fld_content || $this->diffto || $this->difftoprev) - $text = Revision :: getRevisionText($row); + if ($this->fld_content) { + $text = Revision :: getRevisionText($row); if ($this->expandTemplates) { global $wgParser; $text = $wgParser->preprocess( $text, $title, new ParserOptions() ); } ApiResult :: setContent($vals, $text); - } - - if($this->diffto) - { - global $wgContLang; - $newText = explode("\n", $wgContLang->segmentForDiff($text)); - $diff = new Diff($this->diffOldText, $newText); - $vals['diffto']['from'] = $this->diffto; - $arraydiff = $this->formatter instanceof ArrayDiffFormatter; - if( $arraydiff ) { - $changes = $wgContLang->unsegmentForDiff($this->formatter->format($diff)); - $this->getResult()->setIndexedTagName( $changes, 'change' ); - $vals['diffto'] = $changes; - } else { - ApiResult::setContent($vals['diffto'], $wgContLang->unsegmentForDiff($this->formatter->format($diff))); - } - } - if($this->difftoprev) - // Cache the revision's content for later use - $this->revCache[$row->rev_id] = $text; - + } return $vals; } @@ -428,18 +323,6 @@ class ApiQueryRevisions extends ApiQueryBase { ), 'expandtemplates' => false, - 'diffto' => array( - ApiBase :: PARAM_TYPE => 'integer' - ), - 'difftoprev' => false, - 'diffformat' => array( - ApiBase :: PARAM_TYPE => array( - 'traditional', - 'unified', - 'array', - ), - ApiBase :: PARAM_DFLT => 'unified' - ), 'token' => array( ApiBase :: PARAM_TYPE => array( 'rollback' @@ -461,9 +344,6 @@ class ApiQueryRevisions extends ApiQueryBase { 'user' => 'only include revisions made by user', 'excludeuser' => 'exclude revisions made by user', 'expandtemplates' => 'expand templates in revision content', - 'diffto' => 'Revision number to compare all revisions with', - 'difftoprev' => 'Diff each revision to the previous one (enum)', - 'diffformat' => 'Format to use for diffs', 'token' => 'Which tokens to obtain for each revision', ); }