From: Roan Kattouw Date: Thu, 25 Oct 2018 00:09:59 +0000 (-0700) Subject: WikiPage: Truncate redirect fragments before inserting them into the DB X-Git-Tag: 1.34.0-rc.0~3659^2 X-Git-Url: http://git.cyclocoop.org/%22.htmlspecialchars%28%24url_syndic%29.%22?a=commitdiff_plain;h=13a1d8957b9d639c69cef251b831ed03319182b1;p=lhc%2Fweb%2Fwiklou.git WikiPage: Truncate redirect fragments before inserting them into the DB The rd_fragment field is 255 bytes wide, but there is no limit on how long title fragments can be. We don't want to let the database silently truncate the fragment for us, because that can result in invalid UTF-8. Instead, truncate it before insertion in a UTF-8-aware way. Bug: T207876 Change-Id: I12745f3f4c174eaced56d80f3661a71d0e5637e6 --- diff --git a/includes/page/WikiPage.php b/includes/page/WikiPage.php index 18797d9443..d03d317043 100644 --- a/includes/page/WikiPage.php +++ b/includes/page/WikiPage.php @@ -1045,20 +1045,22 @@ class WikiPage implements Page, IDBAccessObject { $dbw->startAtomic( __METHOD__ ); if ( !$oldLatest || $oldLatest == $this->lockAndGetLatest() ) { + $contLang = MediaWikiServices::getInstance()->getContentLanguage(); + $truncatedFragment = $contLang->truncateForDatabase( $rt->getFragment(), 255 ); $dbw->upsert( 'redirect', [ 'rd_from' => $this->getId(), 'rd_namespace' => $rt->getNamespace(), 'rd_title' => $rt->getDBkey(), - 'rd_fragment' => $rt->getFragment(), + 'rd_fragment' => $truncatedFragment, 'rd_interwiki' => $rt->getInterwiki(), ], [ 'rd_from' ], [ 'rd_namespace' => $rt->getNamespace(), 'rd_title' => $rt->getDBkey(), - 'rd_fragment' => $rt->getFragment(), + 'rd_fragment' => $truncatedFragment, 'rd_interwiki' => $rt->getInterwiki(), ], __METHOD__ diff --git a/tests/phpunit/includes/page/WikiPageDbTestBase.php b/tests/phpunit/includes/page/WikiPageDbTestBase.php index d9c92f540a..fee45838b5 100644 --- a/tests/phpunit/includes/page/WikiPageDbTestBase.php +++ b/tests/phpunit/includes/page/WikiPageDbTestBase.php @@ -816,6 +816,15 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase { "#REDIRECT [[Media:hello_world]]", "File:Hello world" ], + // Test fragments longer than 255 bytes (T207876) + [ + 'WikiPageTest_testGetRedirectTarget_4', + CONTENT_MODEL_WIKITEXT, + // phpcs:ignore Generic.Files.LineLength + '#REDIRECT [[Foobar#🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿]]', + // phpcs:ignore Generic.Files.LineLength + 'Foobar#🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬󠁦󠁲󠁿🏴󠁮󠁬...' + ] ]; } @@ -836,7 +845,7 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase { # now, test the actual redirect $t = $page->getRedirectTarget(); - $this->assertEquals( $target, is_null( $t ) ? null : $t->getPrefixedText() ); + $this->assertEquals( $target, is_null( $t ) ? null : $t->getFullText() ); } /**