[wp-trac] [WordPress Trac] #42670: Symlinked plugin makes plugin_basename function return wrong basename
WordPress Trac
noreply at wordpress.org
Tue Aug 1 17:09:40 UTC 2023
#42670: Symlinked plugin makes plugin_basename function return wrong basename
----------------------------------------------------+---------------------
Reporter: sergiienko | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: 6.4
Component: Plugins | Version: 4.9
Severity: normal | Resolution:
Keywords: has-unit-tests has-patch needs-testing | Focuses:
----------------------------------------------------+---------------------
Comment (by brianhenryie):
After I posted the repo above to reproduce the issue and verify the patch,
@ironprogrammer and I discovered another related bug that should be fixed
at the same time: my patch was written for an environment where there is a
symlink inside a symlink (/wordpress/wp-content -> /wp-content, and /wp-
content/plugins/example-plugin -> /). Where there is only one symlink
(wordpress/wp-content/plugins -> .) the issue remains.
I'm posting notes from the Slack thread here:
----
So...
[`wp_register_plugin_realpath()`](https://github.com/WordPress/WordPress/blob/9e0f2faa28f1aa04a69e0b4eaa410a38adcd2e1e
/wp-includes/plugin.php#L819-L821) doesn't record the plugin realpath to
`$wp_plugin_paths` if its calculated `realpath()` isn't any different to
the `WP_PLUGIN_DIR` subdirectory path.
Then when `$wp_plugin_paths` is looped over in `plugin_basename()`, where
the "fix" is, the only entry is the only symlinked plugin, i.e. a-wp-
trac-42670 in the project root, which then matches for every plugin
queried in `plugin_basename()`.
The bug can be fixed by removing the condition on whether the plugins'
paths are recorded.
Ideally `$wp_plugin_paths` would only be populated when there is one or
more symlinked plugins, but we can't know this until looking at each one.
Something like this could be used to empty the array afterwards in times
when it's not needed:
{{{#!php
<?php
add_action( 'plugins_loaded', function() {
global $wp_plugin_paths;
foreach ( $wp_plugin_paths as $dir => $realdir ) {
if( $dir !== $realdir ) {
return;
}
}
$wp_plugin_paths = array();
}, 0);
}}}
----
Reflecting on that, the minimum addition to the patch should be:
In `wp-includes/plugin.php:819` change:
{{{#!php
<?php
if ( $plugin_path !== $plugin_realpath ) {
$wp_plugin_paths[ $plugin_path ] = $plugin_realpath;
}
}}}
to:
{{{#!php
<?php
$wp_plugin_paths[ $plugin_path ] = $plugin_realpath;
}}}
The `plugins_loaded` code above might be best omitted for clarity. The
performance impact here is how many times the sorted `global
$wp_plugin_paths` array, whose length will be the number of plugins
installed, is traversed by `plugin_basename()` (an admittedly popular
function).
--
Ticket URL: <https://core.trac.wordpress.org/ticket/42670#comment:29>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list