Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F35676993
T320987.patch
Ladsgroup (Amir Sarabadani)
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Authored By
Ladsgroup
Oct 31 2022, 10:31 AM
2022-10-31 10:31:41 (UTC+0)
Size
4 KB
Referenced Files
None
Subscribers
None
T320987.patch
View Options
From 6c81cda26e713e51384e9a4556b6d78ea820263c Mon Sep 17 00:00:00 2001
From: Amir Sarabadani <ladsgroup@gmail.com>
Date: Mon, 31 Oct 2022 11:28:37 +0100
Subject: [PATCH] [SECURITY] Use rev_page_timestamp in SpecialMobileHistory
Like the core counterpart to avoid really slow queries.
Also cleaning up and modernize all the db query stack. Using
SelectQueryBuilder, simplify, use buildComparison, etc.
Bug: T320987
Change-Id: I8eb91a0f490ef96a49d3aa8d6844d74a0ea06e04
---
extension.json | 1 +
includes/specials/SpecialMobileHistory.php | 58 ++++++++--------------
2 files changed, 23 insertions(+), 36 deletions(-)
diff --git a/extension.json b/extension.json
index 8db0a885a..33cf3094c 100644
--- a/extension.json
+++ b/extension.json
@@ -31,6 +31,7 @@
"History": {
"class": "SpecialMobileHistory",
"services": [
+ "DBLoadBalancer",
"NamespaceInfo",
"RevisionFactory"
]
diff --git a/includes/specials/SpecialMobileHistory.php b/includes/specials/SpecialMobileHistory.php
index 340f19262..8e0cdeade 100644
--- a/includes/specials/SpecialMobileHistory.php
+++ b/includes/specials/SpecialMobileHistory.php
@@ -3,7 +3,9 @@
use MediaWiki\MediaWikiServices;
use MediaWiki\Revision\RevisionFactory;
use MediaWiki\Revision\RevisionRecord;
+use Wikimedia\Rdbms\ILoadBalancer;
use Wikimedia\Rdbms\IResultWrapper;
+use Wikimedia\Rdbms\SelectQueryBuilder;
/**
* Mobile formatted history of a page
@@ -12,7 +14,6 @@ class SpecialMobileHistory extends MobileSpecialPageFeed {
/** @var bool Whether the mobile special page has a desktop special page */
protected $hasDesktopVersion = true;
protected const LIMIT = 50;
- private const DB_REVISIONS_TABLE = 'revision';
/** @var string|null Timestamp to offset results from */
protected $offset;
@@ -33,35 +34,18 @@ class SpecialMobileHistory extends MobileSpecialPageFeed {
/** @var RevisionFactory */
private $revisionFactory;
- /**
- * @param NamespaceInfo $namespaceInfo
- * @param RevisionFactory $revisionFactory
- */
+ /** @var ILoadBalancer */
+ private $dbLoadBalancer;
+
public function __construct(
- NamespaceInfo $namespaceInfo, RevisionFactory $revisionFactory
+ ILoadBalancer $dbLoadBalancer, NamespaceInfo $namespaceInfo, RevisionFactory $revisionFactory
) {
$this->namespaceInfo = $namespaceInfo;
$this->revisionFactory = $revisionFactory;
+ $this->dbLoadBalancer = $dbLoadBalancer;
parent::__construct( $this->specialPageName );
}
- /**
- * Returns a list of query conditions that should be run against the revision table
- *
- * @return array List of conditions
- */
- protected function getQueryConditions() {
- $conds = [];
- if ( $this->title ) {
- $conds['rev_page'] = $this->title->getArticleID();
- }
- if ( $this->offset ) {
- $dbr = wfGetDB( DB_REPLICA, self::DB_REVISIONS_TABLE );
- $conds[] = 'rev_timestamp <= ' . $dbr->addQuotes( $this->offset );
- }
- return $conds;
- }
-
/**
* Gets HTML to place in the header bar
* @param Title $title The page to link to
@@ -175,25 +159,27 @@ class SpecialMobileHistory extends MobileSpecialPageFeed {
/**
* Executes the database query and returns the result.
- * @see getQueryConditions()
* @return IResultWrapper
*/
protected function doQuery() {
- $dbr = wfGetDB( DB_REPLICA, self::DB_REVISIONS_TABLE );
- $conds = $this->getQueryConditions();
- $options = [
- 'ORDER BY' => 'rev_timestamp DESC'
- ];
-
- $options['LIMIT'] = self::LIMIT + 1;
-
+ $dbr = $this->dbLoadBalancer->getConnection( DB_REPLICA );
$revQuery = $this->revisionFactory->getQueryInfo();
+ $queryBuilder = $dbr->newSelectQueryBuilder()
+ ->tables( $revQuery['tables'] )
+ ->fields( $revQuery['fields'] )
+ ->joinConds( $revQuery['joins'] );
- $res = $dbr->select(
- $revQuery['tables'], $revQuery['fields'], $conds, __METHOD__, $options, $revQuery['joins']
- );
+ if ( $this->title ) {
+ $queryBuilder->where( [ 'rev_page', $this->title->getArticleID() ] );
+ }
+ if ( $this->offset ) {
+ $queryBuilder->where( $dbr->buildComparison('<=', [ 'rev_timestamp' => $this->offset ] ) );
+ }
+ $queryBuilder->orderBy( 'rev_timestamp', SelectQueryBuilder::SORT_DESC )
+ ->limit( self::LIMIT + 1 )
+ ->useIndex( [ 'revision' => 'rev_page_timestamp' ] );
- return $res;
+ return $queryBuilder->caller( __METHOD__ )->fetchResultSet();
}
/**
--
2.25.1
File Metadata
Details
Attached
Mime Type
text/x-diff
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
9853223
Default Alt Text
T320987.patch (4 KB)
Attached To
Mode
T320987: CVE-2023-22909: [Unplanned, S] Mobile frontend's history makes really slow db queries
Attached
Detach File
Event Timeline
Log In to Comment