aboutsummaryrefslogtreecommitdiffstats
path: root/includes/linker/Linker.php
diff options
context:
space:
mode:
authorC. Scott Ananian <cscott@cscott.net>2024-02-09 15:19:38 -0500
committerBartosz DziewoƄski <dziewonski@fastmail.fm>2024-06-10 18:47:32 +0000
commitb855c62f66227820136ef99faf728ca3dd1258e0 (patch)
tree5b0ef28ebe3214089a701bf64d26c26f7c35ffc0 /includes/linker/Linker.php
parent0afc5f328051fa24019fec2e0f7f01da624a1834 (diff)
downloadmediawikicore-b855c62f66227820136ef99faf728ca3dd1258e0.tar.gz
mediawikicore-b855c62f66227820136ef99faf728ca3dd1258e0.zip
Move Linker::makeExternalLink() to the LinkRenderer service
Move Linker::makeExternalLink to the LinkRenderer service, as has been done with the other static methods of Linker. In order to allow phan's SecurityCheckPlugin to perform a more accurate analysis of taintedness, tweak the API of Linker::makeExternalLink to clearly indicate via the type system whether the link text has already been escaped or not: a `string` argument will always be escaped, and if the argument is already escaped it should be passed as an HtmlArmor object. In refactoring, `Message` arguments were also common, and accept them as-is to avoid the caller having to think about whether to call Message::text() or Message::escaped(). This allows us to provide a more precise taint type to the $text argument, avoids an opaque boolean argument, and avoids spurious errors from SecurityCheck. We also require the caller to explicitly pass a Title context, instead of implicitly relying on the global $wgTitle. This works cleanly everywhere except for CommentParser, which has a $selfLinkTarget which generally works as the title context for the external link, but which is nullable. The original Linker::makeExternalLink() used $wgTitle as a fallback, but $wgTitle can also be null in some circumstances. The title context only determines how $wgNoFollowNsExceptions is handled, so existing code basically just ignored $wgNoFollowNsExceptions when $wgTitle was null, which isn't terrible. A future refactor could/should clean up CommentParser to ensure that there is always a non-null title context that can be used. Change-Id: I9bcf4780f388ba639a9cc882dd9dd42eda5736ae
Diffstat (limited to 'includes/linker/Linker.php')
-rw-r--r--includes/linker/Linker.php46
1 files changed, 10 insertions, 36 deletions
diff --git a/includes/linker/Linker.php b/includes/linker/Linker.php
index b632c3f72ec7..b737520dce6b 100644
--- a/includes/linker/Linker.php
+++ b/includes/linker/Linker.php
@@ -1137,47 +1137,21 @@ class Linker {
* @param LinkTarget|null $title LinkTarget object used for title specific link attributes
* @param-taint $title none
* @return string
+ * @deprecated since 1.43; use LinkRenderer::makeExternalLink(), passing
+ * in an HtmlArmor instance if $escape was false.
*/
public static function makeExternalLink( $url, $text, $escape = true,
$linktype = '', $attribs = [], $title = null
) {
global $wgTitle;
- $class = 'external';
- if ( $linktype ) {
- $class .= " $linktype";
- }
- if ( isset( $attribs['class'] ) && $attribs['class'] ) {
- $class .= " {$attribs['class']}";
- }
- $attribs['class'] = $class;
-
- if ( $escape ) {
- $text = htmlspecialchars( $text, ENT_COMPAT );
- }
-
- if ( !$title ) {
- $title = $wgTitle;
- }
- $newRel = Parser::getExternalLinkRel( $url, $title );
- if ( !isset( $attribs['rel'] ) || $attribs['rel'] === '' ) {
- $attribs['rel'] = $newRel;
- } elseif ( $newRel !== null ) {
- // Merge the rel attributes.
- $newRels = explode( ' ', $newRel );
- $oldRels = explode( ' ', $attribs['rel'] );
- $combined = array_unique( array_merge( $newRels, $oldRels ) );
- $attribs['rel'] = implode( ' ', $combined );
- }
- $link = '';
- $success = ( new HookRunner( MediaWikiServices::getInstance()->getHookContainer() ) )->onLinkerMakeExternalLink(
- $url, $text, $link, $attribs, $linktype );
- if ( !$success ) {
- wfDebug( "Hook LinkerMakeExternalLink changed the output of link "
- . "with url {$url} and text {$text} to {$link}" );
- return $link;
- }
- $attribs['href'] = $url;
- return Html::rawElement( 'a', $attribs, $text );
+ $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
+ return $linkRenderer->makeExternalLink(
+ $url,
+ $escape ? $text : new HtmlArmor( $text ),
+ $title ?? $wgTitle,
+ $linktype,
+ $attribs
+ );
}
/**