Thank you so much! That looks like it exactly.
https://developer.wordpress.org/reference/hooks/kses_allowed_protocols/
Filters the list of protocols allowed in HTML attributes.
https://core.trac.wordpress.org/browser/tags/5.2/src/wp-includes/functions.php#L5811
$protocols = array_unique( (array) apply_filters( 'kses_allowed_protocols', $protocols ) );
From reading https://developer.wordpress.org/reference/functions/apply_filters/, the filter called ‘kses_allowed_protocols’ is being applied to the array of $protocols…makes sense.
* @return string[] Array of allowed protocols. Defaults to an array containing 'http', 'https',
* 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet',
* 'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', 'webcal', and 'urn'. This covers
* all common link protocols, except for 'javascript' which should not be
* allowed for untrusted users.
The comment matches the list of values given for $protocols before the filter is applied.
$protocols = array( 'http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', 'webcal', 'urn' );
...
$protocols = array_unique( (array) apply_filters( 'kses_allowed_protocols', $protocols ) );
In any case, this list includes svn, but not git. I just tried an svn link instead, and that works perfectly. Bingo, I think we’ve got it.
Hmm, still don’t know why git works for you and how to duplicate whatever’s going right for you. For git to be allowed just like svn, something would need to actually add it to the $protocols array, right? And clearly something is adding it to the $protocols array, on your install.
The $protocols array is a static variable of the wp_allowed_protocols() function. I know almost nothing about PHP, but as I understand it, that means the $protocols array is persistent and might be changed literally anywhere in the codebase.
static $protocols = array();
…but as you alluded to, the most likely thing to change the $protocols array is a kses_allowed_protocols filter.
I was tripped up at first by the word “filter”, which sounds like it can only remove allowed protocols, not add them. But I just searched and apparently the word “filter” is also used for adding protocols, e.g.
// Whitelist the steam:// and ts3server:// protocols for links
add_filter( 'kses_allowed_protocols', function( $protocols ) {
$protocols[] = 'steam';
$protocols[] = 'ts3server';
return $protocols;
} );
(Thanks to you pointing me to kses_allowed_protocols, I’m now finding a ton of information.)
(PHP syntax is confusing to me, but I gather that $protocols[] = ‘blah’ is adding on to the end of the array.)
There are a lot of places in the WordPress source code where the protocols array is touched, e.g. in wp-includes/kses.php by the name $allowed_protocols.
But there are very few places in the WordPress source code where the string “git” appears.
I just went through all twelve appearances of that three-character string in the WordPress source code, and none of them look like they could possibly end up on the $protocols array, even indirectly. (9/12 appearances are actually in comments, and the others are part of larger strings that could not be part of a URI, such as the string ‘.git’ in a list of file extensions.)
In view of that, uh, not to contradict you when you clearly know way more about this stuff than I do, but it seems more likely that you have a plugin that is adding git to the $protocols whitelist, rather than me having a plugin that is removing it.
In any case, while I still don’t really understand what’s going on — my working hypothesis is that you somehow have a plugin or custom theme functions.php that’s adding git to the whitelist without you knowing about it, which obviously sounds really strange — it sounds like my next step should be to try to make a plugin. I’ve never done that, but even without knowing what I’m doing, I can sort of adapt what other people have written.
// Whitelist the git protocols for links
add_filter( 'kses_allowed_protocols', function( $protocols ) {
$protocols[] = 'git+ssh';
$protocols[] = 'git+https';
return $protocols;
} );
I think I might still make a ticket — not a bug, but a change request. Since svn is on the default $protocols whitelist, it seems reasonable to have git there too.