r23859 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r23858‎ | r23859 | r23860 >
Date:03:35, 8 July 2007
Author:yurik
Status:old
Tags:
Comment:
API:
* added link enumeration (list=alllinks)
* marked potential security vulnerability
Modified paths:
  • /trunk/phase3/RELEASE-NOTES (modified) (history)
  • /trunk/phase3/includes/AutoLoader.php (modified) (history)
  • /trunk/phase3/includes/api/ApiPageSet.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQuery.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryAllLinks.php (added) (history)
  • /trunk/phase3/includes/api/ApiQueryAllpages.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryBacklinks.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryCategoryMembers.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/api/ApiQuery.php
@@ -59,6 +59,7 @@
6060
6161 private $mQueryListModules = array (
6262 'allpages' => 'ApiQueryAllpages',
 63+ 'alllinks' => 'ApiQueryAllLinks',
6364 'backlinks' => 'ApiQueryBacklinks',
6465 'categorymembers' => 'ApiQueryCategoryMembers',
6566 'embeddedin' => 'ApiQueryBacklinks',
Index: trunk/phase3/includes/api/ApiQueryAllpages.php
@@ -54,17 +54,16 @@
5555
5656 $db = $this->getDB();
5757
58 - $limit = $from = $namespace = $filterredir = $prefix = null;
59 - extract($this->extractRequestParams());
 58+ $params = $this->extractRequestParams();
6059
6160 $this->addTables('page');
62 - if (!$this->addWhereIf('page_is_redirect = 1', $filterredir === 'redirects'))
63 - $this->addWhereIf('page_is_redirect = 0', $filterredir === 'nonredirects');
64 - $this->addWhereFld('page_namespace', $namespace);
65 - if (isset ($from))
66 - $this->addWhere('page_title>=' . $db->addQuotes(ApiQueryBase :: titleToKey($from)));
67 - if (isset ($prefix))
68 - $this->addWhere("page_title LIKE '{$db->strencode(ApiQueryBase :: titleToKey($prefix))}%'");
 61+ if (!$this->addWhereIf('page_is_redirect = 1', $params['filterredir'] === 'redirects'))
 62+ $this->addWhereIf('page_is_redirect = 0', $params['filterredir'] === 'nonredirects');
 63+ $this->addWhereFld('page_namespace', $params['namespace']);
 64+ if (!is_null($params['from']))
 65+ $this->addWhere('page_title>=' . $db->addQuotes(ApiQueryBase :: titleToKey($params['from'])));
 66+ if (isset ($params['prefix']))
 67+ $this->addWhere("page_title LIKE '" . $db->strencode(ApiQueryBase :: titleToKey($params['prefix'])) . "%'");
6968
7069 if (is_null($resultPageSet)) {
7170 $this->addFields(array (
@@ -77,7 +76,8 @@
7877 }
7978
8079 $this->addOption('USE INDEX', 'name_title');
81 - $this->addOption('LIMIT', $limit +1);
 80+ $limit = $params['limit'];
 81+ $this->addOption('LIMIT', $limit+1);
8282 $this->addOption('ORDER BY', 'page_namespace, page_title');
8383
8484 $res = $this->select(__METHOD__);
@@ -87,6 +87,7 @@
8888 while ($row = $db->fetchObject($res)) {
8989 if (++ $count > $limit) {
9090 // We've reached the one extra which shows that there are additional pages to be had. Stop here...
 91+ // TODO: Security issue - if the user has no right to view next title, it will still be shown
9192 $this->setContinueEnumParameter('from', ApiQueryBase :: keyToTitle($row->page_title));
9293 break;
9394 }
Index: trunk/phase3/includes/api/ApiQueryCategoryMembers.php
@@ -92,6 +92,7 @@
9393 while ($row = $db->fetchObject($res)) {
9494 if (++ $count > $limit) {
9595 // We've reached the one extra which shows that there are additional pages to be had. Stop here...
 96+ // TODO: Security issue - if the user has no right to view next title, it will still be shown
9697 $this->setContinueEnumParameter('continue', $this->getContinueStr($row, $lastSortKey));
9798 break;
9899 }
Index: trunk/phase3/includes/api/ApiPageSet.php
@@ -266,7 +266,6 @@
267267 */
268268 public function populateFromPageIDs($pageIDs) {
269269 $this->profileIn();
270 - $pageIDs = array_map('intval', $pageIDs); // paranoia
271270 $this->initFromPageIds($pageIDs);
272271 $this->profileOut();
273272 }
@@ -361,7 +360,8 @@
362361 private function initFromPageIds($pageids) {
363362 if(empty($pageids))
364363 return;
365 -
 364+
 365+ $pageids = array_map('intval', $pageids); // paranoia
366366 $set = array (
367367 'page_id' => $pageids
368368 );
Index: trunk/phase3/includes/api/ApiQueryBacklinks.php
@@ -162,6 +162,7 @@
163163 $continue = $this->getContinueRedirStr(false, 0, $ns, $t, $row->page_id);
164164 } else
165165 $continue = $this->getContinueStr($row->page_id);
 166+ // TODO: Security issue - if the user has no right to view next title, it will still be shown
166167 $this->setContinueEnumParameter('continue', $continue);
167168 break;
168169 }
Index: trunk/phase3/includes/api/ApiQueryAllLinks.php
@@ -0,0 +1,181 @@
 2+<?php
 3+
 4+/*
 5+ * Created on July 7, 2007
 6+ *
 7+ * API for MediaWiki 1.8+
 8+ *
 9+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
 10+ *
 11+ * This program is free software; you can redistribute it and/or modify
 12+ * it under the terms of the GNU General Public License as published by
 13+ * the Free Software Foundation; either version 2 of the License, or
 14+ * (at your option) any later version.
 15+ *
 16+ * This program is distributed in the hope that it will be useful,
 17+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 18+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 19+ * GNU General Public License for more details.
 20+ *
 21+ * You should have received a copy of the GNU General Public License along
 22+ * with this program; if not, write to the Free Software Foundation, Inc.,
 23+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 24+ * http://www.gnu.org/copyleft/gpl.html
 25+ */
 26+
 27+if (!defined('MEDIAWIKI')) {
 28+ // Eclipse helper - will be ignored in production
 29+ require_once ('ApiQueryBase.php');
 30+}
 31+
 32+/**
 33+ * Query module to enumerate all available pages.
 34+ *
 35+ * @addtogroup API
 36+ */
 37+class ApiQueryAllLinks extends ApiQueryGeneratorBase {
 38+
 39+ public function __construct($query, $moduleName) {
 40+ parent :: __construct($query, $moduleName, 'al');
 41+ }
 42+
 43+ public function execute() {
 44+ $this->run();
 45+ }
 46+
 47+ public function executeGenerator($resultPageSet) {
 48+ $this->run($resultPageSet);
 49+ }
 50+
 51+ private function run($resultPageSet = null) {
 52+
 53+ $db = $this->getDB();
 54+ $params = $this->extractRequestParams();
 55+ $this->debugPrint($params);
 56+
 57+ $prop = array_flip($params['prop']);
 58+ $fld_ids = isset($prop['ids']);
 59+ $fld_title = isset($prop['title']);
 60+
 61+ if ($params['unique']) {
 62+ if (!is_null($resultPageSet))
 63+ $this->dieUsage($this->getModuleName() . ' cannot be used as a generator in unique links mode', 'params');
 64+ if ($fld_ids)
 65+ $this->dieUsage($this->getModuleName() . ' cannot return corresponding page ids in unique links mode', 'params');
 66+ $this->addOption('DISTINCT');
 67+ }
 68+
 69+ $this->addTables('pagelinks');
 70+ $this->addWhereFld('pl_namespace', $params['namespace']);
 71+
 72+ if (!is_null($params['from']))
 73+ $this->addWhere('pl_title>=' . $db->addQuotes(ApiQueryBase :: titleToKey($params['from'])));
 74+ if (isset ($params['prefix']))
 75+ $this->addWhere("pl_title LIKE '" . $db->strencode(ApiQueryBase :: titleToKey($params['prefix'])) . "%'");
 76+
 77+ if (is_null($resultPageSet)) {
 78+ $this->addFields(array (
 79+ 'pl_namespace',
 80+ 'pl_title'
 81+ ));
 82+ $this->addFieldsIf('pl_from', $fld_ids);
 83+ } else {
 84+ $this->addFields('pl_from');
 85+ $pageids = array();
 86+ }
 87+
 88+ $this->addOption('USE INDEX', 'pl_namespace');
 89+ $limit = $params['limit'];
 90+ $this->addOption('LIMIT', $limit+1);
 91+ $this->addOption('ORDER BY', 'pl_namespace, pl_title');
 92+
 93+ $res = $this->select(__METHOD__);
 94+
 95+ $data = array ();
 96+ $count = 0;
 97+ while ($row = $db->fetchObject($res)) {
 98+ if (++ $count > $limit) {
 99+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
 100+ // TODO: Security issue - if the user has no right to view next title, it will still be shown
 101+ $this->setContinueEnumParameter('from', ApiQueryBase :: keyToTitle($row->pl_title));
 102+ break;
 103+ }
 104+
 105+ if (is_null($resultPageSet)) {
 106+ $title = Title :: makeTitle($row->pl_namespace, $row->pl_title);
 107+ if ($title->userCanRead()) {
 108+ $vals = array();
 109+ if ($fld_ids)
 110+ $vals['fromid'] = intval($row->pl_from);
 111+ if ($fld_title) {
 112+ $vals['ns'] = intval($title->getNamespace());
 113+ $vals['title'] = $title->getPrefixedText();
 114+ }
 115+ $data[] = $vals;
 116+ }
 117+ } else {
 118+ $pageids[] = $row->pl_from;
 119+ }
 120+ }
 121+ $db->freeResult($res);
 122+
 123+ if (is_null($resultPageSet)) {
 124+ $result = $this->getResult();
 125+ $result->setIndexedTagName($data, 'l');
 126+ $result->addValue('query', $this->getModuleName(), $data);
 127+ } else {
 128+ $resultPageSet->populateFromPageIDs($pageids);
 129+ }
 130+ }
 131+
 132+ protected function getAllowedParams() {
 133+ return array (
 134+ 'from' => null,
 135+ 'prefix' => null,
 136+ 'unique' => false,
 137+ 'prop' => array (
 138+ ApiBase :: PARAM_ISMULTI => true,
 139+ ApiBase :: PARAM_DFLT => 'title',
 140+ ApiBase :: PARAM_TYPE => array (
 141+ 'ids',
 142+ 'title'
 143+ )
 144+ ),
 145+ 'namespace' => array (
 146+ ApiBase :: PARAM_DFLT => 0,
 147+ ApiBase :: PARAM_TYPE => 'namespace'
 148+ ),
 149+ 'limit' => array (
 150+ ApiBase :: PARAM_DFLT => 10,
 151+ ApiBase :: PARAM_TYPE => 'limit',
 152+ ApiBase :: PARAM_MIN => 1,
 153+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
 154+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
 155+ )
 156+ );
 157+ }
 158+
 159+ protected function getParamDescription() {
 160+ return array (
 161+ 'from' => 'The page title to start enumerating from.',
 162+ 'prefix' => 'Search for all page titles that begin with this value.',
 163+ 'unique' => 'Only show unique links. Cannot be used with generator or prop=ids',
 164+ 'namespace' => 'The namespace to enumerate.',
 165+ 'limit' => 'How many total links to return.'
 166+ );
 167+ }
 168+
 169+ protected function getDescription() {
 170+ return 'Enumerate all pages sequentially in a given namespace';
 171+ }
 172+
 173+ protected function getExamples() {
 174+ return array (
 175+ 'api.php?action=query&list=alllinks&alunique&alfrom=B',
 176+ );
 177+ }
 178+
 179+ public function getVersion() {
 180+ return __CLASS__ . ': $Id$';
 181+ }
 182+}
Property changes on: trunk/phase3/includes/api/ApiQueryAllLinks.php
___________________________________________________________________
Added: svn:eol-style
1183 + native
Added: svn:keywords
2184 + Id
Index: trunk/phase3/includes/AutoLoader.php
@@ -306,6 +306,7 @@
307307 'ApiPageSet' => 'includes/api/ApiPageSet.php',
308308 'ApiQuery' => 'includes/api/ApiQuery.php',
309309 'ApiQueryAllpages' => 'includes/api/ApiQueryAllpages.php',
 310+ 'ApiQueryAllLinks' => 'includes/api/ApiQueryAllLinks.php',
310311 'ApiQueryBase' => 'includes/api/ApiQueryBase.php',
311312 'ApiQueryGeneratorBase' => 'includes/api/ApiQueryBase.php',
312313 'ApiQueryBacklinks' => 'includes/api/ApiQueryBacklinks.php',
Index: trunk/phase3/RELEASE-NOTES
@@ -308,6 +308,7 @@
309309 * Added prop=imageinfo - gets image properties and upload history
310310 * (bug 10211) Added db server replication lag information in meta=siteinfo
311311 * Added external url search within wiki pages (list=exturlusage)
 312+* Added link enumeration (list=alllinks)
312313
313314 == Maintenance script changes since 1.10 ==
314315

Follow-up revisions

RevisionCommit summaryAuthorDate
r23912Merged revisions 23662-23909 via svnmerge from...david18:11, 9 July 2007

Status & tagging log