From: jenkins-bot Date: Thu, 4 Jan 2018 17:27:45 +0000 (+0000) Subject: Merge "[MCR] fix RevisionStore::checkDatabaseWikiId for DB names with dashes." X-Git-Tag: 1.31.0-rc.0~1003 X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=643ebd78e43d04553a1f581e1b6607c2706dcfce;hp=ba00b23a1d6fea3f05c617d3df73d60ab28dfdf4 Merge "[MCR] fix RevisionStore::checkDatabaseWikiId for DB names with dashes." --- diff --git a/includes/Storage/RevisionStore.php b/includes/Storage/RevisionStore.php index ce56efceaa..2e953fc15d 100644 --- a/includes/Storage/RevisionStore.php +++ b/includes/Storage/RevisionStore.php @@ -1476,10 +1476,20 @@ class RevisionStore implements IDBAccessObject, RevisionFactory, RevisionLookup $storeWiki = $storeWiki ?: wfWikiID(); $dbWiki = $dbWiki ?: wfWikiID(); - if ( $dbWiki !== $storeWiki ) { - throw new MWException( "RevisionStore for $storeWiki " - . "cannot be used with a DB connection for $dbWiki" ); + if ( $dbWiki === $storeWiki ) { + return; + } + + // HACK: counteract encoding imposed by DatabaseDomain + $storeWiki = str_replace( '?h', '-', $storeWiki ); + $dbWiki = str_replace( '?h', '-', $dbWiki ); + + if ( $dbWiki === $storeWiki ) { + return; } + + throw new MWException( "RevisionStore for $storeWiki " + . "cannot be used with a DB connection for $dbWiki" ); } /** diff --git a/tests/phpunit/includes/Storage/RevisionStoreDbTest.php b/tests/phpunit/includes/Storage/RevisionStoreDbTest.php index ee8fdc781f..28a8d88458 100644 --- a/tests/phpunit/includes/Storage/RevisionStoreDbTest.php +++ b/tests/phpunit/includes/Storage/RevisionStoreDbTest.php @@ -4,17 +4,26 @@ namespace MediaWiki\Tests\Storage; use CommentStoreComment; use Exception; +use HashBagOStuff; use InvalidArgumentException; use MediaWiki\Linker\LinkTarget; use MediaWiki\MediaWikiServices; use MediaWiki\Storage\IncompleteRevisionException; use MediaWiki\Storage\MutableRevisionRecord; use MediaWiki\Storage\RevisionRecord; +use MediaWiki\Storage\RevisionStore; use MediaWiki\Storage\SlotRecord; +use MediaWiki\Storage\SqlBlobStore; use MediaWikiTestCase; use Revision; use TestUserRegistry; use Title; +use WANObjectCache; +use Wikimedia\Rdbms\Database; +use Wikimedia\Rdbms\DatabaseSqlite; +use Wikimedia\Rdbms\FakeResultWrapper; +use Wikimedia\Rdbms\LoadBalancer; +use Wikimedia\Rdbms\TransactionProfiler; use WikiPage; use WikitextContent; @@ -23,6 +32,107 @@ use WikitextContent; */ class RevisionStoreDbTest extends MediaWikiTestCase { + /** + * @return LoadBalancer + */ + private function getLoadBalancerMock( array $server ) { + $lb = $this->getMockBuilder( LoadBalancer::class ) + ->setMethods( [ 'reallyOpenConnection' ] ) + ->setConstructorArgs( [ [ 'servers' => [ $server ] ] ] ) + ->getMock(); + + $lb->method( 'reallyOpenConnection' )->willReturnCallback( + function ( array $server, $dbNameOverride = false ) { + return $this->getDatabaseMock( $server ); + } + ); + + return $lb; + } + + /** + * @return Database + */ + private function getDatabaseMock( array $params ) { + $db = $this->getMockBuilder( DatabaseSqlite::class ) + ->setMethods( [ 'select', 'doQuery', 'open', 'closeConnection', 'isOpen' ] ) + ->setConstructorArgs( [ $params ] ) + ->getMock(); + + $db->method( 'select' )->willReturn( new FakeResultWrapper( [] ) ); + $db->method( 'isOpen' )->willReturn( true ); + + return $db; + } + + public function provideDomainCheck() { + yield [ false, 'test', '' ]; + yield [ 'test', 'test', '' ]; + + yield [ false, 'test', 'foo_' ]; + yield [ 'test-foo_', 'test', 'foo_' ]; + + yield [ false, 'dash-test', '' ]; + yield [ 'dash-test', 'dash-test', '' ]; + + yield [ false, 'underscore_test', 'foo_' ]; + yield [ 'underscore_test-foo_', 'underscore_test', 'foo_' ]; + } + + /** + * @dataProvider provideDomainCheck + * @covers \MediaWiki\Storage\RevisionStore::checkDatabaseWikiId + */ + public function testDomainCheck( $wikiId, $dbName, $dbPrefix ) { + $this->setMwGlobals( + [ + 'wgDBname' => $dbName, + 'wgDBprefix' => $dbPrefix, + ] + ); + + $loadBalancer = $this->getLoadBalancerMock( + [ + 'host' => '*dummy*', + 'dbDirectory' => '*dummy*', + 'user' => 'test', + 'password' => 'test', + 'flags' => 0, + 'variables' => [], + 'schema' => '', + 'cliMode' => true, + 'agent' => '', + 'load' => 100, + 'profiler' => null, + 'trxProfiler' => new TransactionProfiler(), + 'connLogger' => new \Psr\Log\NullLogger(), + 'queryLogger' => new \Psr\Log\NullLogger(), + 'errorLogger' => new \Psr\Log\NullLogger(), + 'type' => 'test', + 'dbname' => $dbName, + 'tablePrefix' => $dbPrefix, + ] + ); + $db = $loadBalancer->getConnection( DB_REPLICA ); + + $blobStore = $this->getMockBuilder( SqlBlobStore::class ) + ->disableOriginalConstructor() + ->getMock(); + + $store = new RevisionStore( + $loadBalancer, + $blobStore, + new WANObjectCache( [ 'cache' => new HashBagOStuff() ] ), + $wikiId + ); + + $count = $store->countRevisionsByPageId( $db, 0 ); + + // Dummy check to make PhpUnit happy. We are really only interested in + // countRevisionsByPageId not failing due to the DB domain check. + $this->assertSame( 0, $count ); + } + private function assertLinkTargetsEqual( LinkTarget $l1, LinkTarget $l2 ) { $this->assertEquals( $l1->getDBkey(), $l2->getDBkey() ); $this->assertEquals( $l1->getNamespace(), $l2->getNamespace() );