build: Upgrade phan-taint-check-plugin from 1.5.x to 2.0.1

The method ReplaceTextUtils::link (which is already complicated because
it tries to support ancient MediaWiki) can perform different levels of
escaping depending on whether the HtmlArmor class exists. This is confusing
for taint-check and for humans, and can inevitably lead to errors. Plus
it's bad practice to have a method returning something with a variable
level of taintedness, especially if that depends on something ephemeral
like if a class exists or not.

Thus, the HtmlArmor part is removed, the text is escaped for Linker::link,
and the method now requires non-escaped HTML to be passed in.

Change-Id: I6e2783827580e3d470d316f1d3879679eb67aeda
This commit is contained in:
James D. Forrester 2019-07-10 16:31:01 -07:00 committed by Daimona Eaytoy
parent dddb12e32a
commit 048be08fa5
4 changed files with 39 additions and 17 deletions

View file

@ -18,6 +18,6 @@
]
},
"extra": {
"phan-taint-check-plugin": "1.5.0"
"phan-taint-check-plugin": "2.0.1"
}
}

View file

@ -30,6 +30,10 @@ class ReplaceTextHooks {
*/
public static function addToAdminLinks( ALTree &$adminLinksTree ) {
$generalSection = $adminLinksTree->getSection( wfMessage( 'adminlinks_general' )->text() );
if ( !$generalSection ) {
return true;
}
$extensionsRow = $generalSection->getRow( 'extensions' );
if ( is_null( $extensionsRow ) ) {

View file

@ -25,17 +25,15 @@ class ReplaceTextUtils {
/**
* Shim for compatibility
* @param Title $title to link to
* @param string|null $text to show
* @param string|null $text to show, not escaped
* @return string HTML for link
*/
public static function link( Title $title, $text = null ) {
if ( method_exists( '\MediaWiki\MediaWikiServices', 'getLinkRenderer' ) ) {
$linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
if ( class_exists( 'HtmlArmor' ) && !is_null( $text ) ) {
$text = new HtmlArmor( $text );
}
return $linkRenderer->makeLink( $title, $text );
};
return Linker::link( $title, $text );
$escText = htmlspecialchars( $text );
return Linker::link( $title, $escText );
}
}

View file

@ -52,21 +52,31 @@ class SpecialReplaceText extends SpecialPage {
throw new PermissionsError( 'replacetext' );
}
$out = $this->getOutput();
// Replace Text can't be run with certain settings, due to the
// changes they make to the DB storage setup.
if ( $wgCompressRevisions ) {
$errorMsg = "Error: text replacements cannot be run if \$wgCompressRevisions is set to true.";
$this->getOutput()->addWikiText( "<div class=\"errorbox\">$errorMsg</div>" );
if ( method_exists( $out, 'addWikiTextAsContent' ) ) {
$out->addWikiTextAsContent( "<div class=\"errorbox\">$errorMsg</div>" );
} else {
// @phan-suppress-next-line PhanUndeclaredMethod
$out->addWikiText( "<div class=\"errorbox\">$errorMsg</div>" );
}
return;
}
if ( !empty( $wgExternalStores ) ) {
$errorMsg = "Error: text replacements cannot be run if \$wgExternalStores is non-empty.";
$this->getOutput()->addWikiText( "<div class=\"errorbox\">$errorMsg</div>" );
if ( method_exists( $out, 'addWikiTextAsContent' ) ) {
$out->addWikiTextAsContent( "<div class=\"errorbox\">$errorMsg</div>" );
} else {
// @phan-suppress-next-line PhanUndeclaredMethod
$out->addWikiText( "<div class=\"errorbox\">$errorMsg</div>" );
}
return;
}
$this->setHeaders();
$out = $this->getOutput();
if ( !is_null( $out->getResourceLoader()->getModule( 'mediawiki.special' ) ) ) {
$out->addModuleStyles( 'mediawiki.special' );
}
@ -140,7 +150,7 @@ class SpecialReplaceText extends SpecialPage {
$out->addHTML(
ReplaceTextUtils::link(
$this->getPageTitle(),
$this->msg( 'replacetext_return' )->escaped()
$this->msg( 'replacetext_return' )->text()
)
);
return;
@ -188,8 +198,10 @@ class SpecialReplaceText extends SpecialPage {
}
if ( $bad_cat_name ) {
$link = ReplaceTextUtils::link( $category_title,
htmlspecialchars( ucfirst( $this->category ) ) );
$link = ReplaceTextUtils::link(
$category_title,
ucfirst( $this->category )
);
$out->addHTML(
$this->msg( 'replacetext_nosuchcategory' )->rawParams( $link )->escaped()
);
@ -209,14 +221,22 @@ class SpecialReplaceText extends SpecialPage {
'<p>' .
ReplaceTextUtils::link(
$this->getPageTitle(),
$this->msg( 'replacetext_return' )->escaped() )
$this->msg( 'replacetext_return' )->text()
)
. '</p>'
);
} else {
$warning_msg = $this->getAnyWarningMessageBeforeReplace( $titles_for_edit, $titles_for_move );
if ( !is_null( $warning_msg ) ) {
if ( method_exists( $out, 'addWikiTextAsContent' ) ) {
$out->addWikiTextAsContent(
"<div class=\"errorbox\">$warning_msg</div><br clear=\"both\" />"
);
} else {
// @phan-suppress-next-line PhanUndeclaredMethod
$out->addWikiText( "<div class=\"errorbox\">$warning_msg</div><br clear=\"both\" />" );
}
}
$this->pageListForm( $titles_for_edit, $titles_for_move, $unmoveable_titles );
}
@ -775,8 +795,8 @@ class SpecialReplaceText extends SpecialPage {
return $context;
}
private function convertWhiteSpaceToHTML( $msg ) {
$msg = htmlspecialchars( $msg );
private function convertWhiteSpaceToHTML( $message ) {
$msg = htmlspecialchars( $message );
$msg = preg_replace( '/^ /m', '&#160; ', $msg );
$msg = preg_replace( '/ $/m', ' &#160;', $msg );
$msg = preg_replace( '/ /', '&#160; ', $msg );