Opened 4 years ago
Last modified 4 years ago
#51947 new defect (bug)
When Customizer `setup_theme` action fails during wp-settings.php, WordPress crashes due to missing global $wp_locale
Reported by: | Guss77 | Owned by: | |
---|---|---|---|
Milestone: | Future Release | Priority: | normal |
Severity: | major | Version: | 4.6 |
Component: | Customize | Keywords: | needs-patch |
Focuses: | Cc: |
Description
The wp-settings.php
sets up the global $wp_locale
(line 499 in WordPress 5.5.3) but before doing that it calls do_action( 'setup_theme' );
(line 478).
The problem is that WP_Customize_Manager::setup_theme()
has several failure actions that call the class's wp_die()
"wrapper" which - depending on the value of the messenger_channel
might try to call wp_enqueue_scripts()
, which will eventually call wp_localize_jquery_ui_datepicker()
that expects $wp_locale
to be already set. The result is a crash.
Here is one such stack trace:
PHP Fatal error: Uncaught Error: Call to a member function is_rtl() on null in /var/www/html/wp-includes/script-loader.php:1684 Stack trace: #0 /var/www/html/wp-includes/class-wp-hook.php(287): wp_localize_jquery_ui_datepicker('') #1 /var/www/html/wp-includes/class-wp-hook.php(311): WP_Hook->apply_filters(NULL, Array) #2 /var/www/html/wp-includes/plugin.php(478): WP_Hook->do_action(Array) #3 /var/www/html/wp-includes/script-loader.php(2001): do_action('wp_enqueue_scri...') #4 /var/www/html/wp-includes/class-wp-customize-manager.php(454): wp_enqueue_scripts() #5 /var/www/html/wp-includes/class-wp-customize-manager.php(551): WP_Customize_Manager->wp_die(0, 'Non-existent ch...') #6 /var/www/html/wp-includes/class-wp-hook.php(287): WP_Customize_Manager->setup_theme('') #7 /var/www/html/wp-includes/class-wp-hook.php(311): WP_Hook->apply_filters(NULL, Array) #8 /var/www/html/wp-includes/plugin.php(478): WP_Hook->do_action(Array) #9 /var/www/html/wp-settings.php(478): do_action('setup_theme') #10 /var/www/html/wp-config.php(97): req... in /var/www/html/wp-includes/script-loader.php on line 1684, referer: https://somesite.com/
Moving the do_action( 'setup_theme' );
line down a few lines until after the local has been setup, and just before loading the active theme's function.php
file (which is arguably where it was supposed to be in the first place) solves the problem.
Change History (7)
#2
@
4 years ago
For me it happens when the customizer is trying to output the "Non-existent changeset UUID" error message, and this happened on my multi-site with the MU Domain Mapping plugin when accessing the customizer in a site where the primary domain name is not a sub-domain of the multisite "DOMAIN_CURRENT_SITE
".
#3
follow-up:
↓ 4
@
4 years ago
In my testing so far, I'm unable to replicate that fatal error. The script exits as expected.
wp_localize_jquery_ui_datepicker()
won't attempt to use the $wp_locale
global unless the jquery-ui-datepicker
script is enqueued — see https://github.com/WordPress/wordpress-develop/blob/901909bf2cc79333d424628cef2064770b4b839b/src/wp-includes/script-loader.php#L1666-L1671.
Is a plugin enqueuing the datepicker? If so, when in the bootstrap cycle is it being enqueued, and how?
#4
in reply to:
↑ 3
@
4 years ago
Replying to dlh:
Is a plugin enqueuing the datepicker? If so, when in the bootstrap cycle is it being enqueued, and how?
very likely - I have several plugins installed that call wp_enqueue_script('jquery-ui-datepicker')
or wp_register_script()
with jquery-ui-datepicker
as a dependency.
- WordPress File Upload: calls
wp_enqueue_script('jquery-ui-datepicker')
fromadmin_print_scripts
hook. - Contact Form 7: calls
wp_enqueue_script('jquery-ui-datepicker')
from thewp_enqueue_scripts
hook. - Woo Order Export Lite: calls
wp_enqueue_script('jquery-ui-datepicker')
fromadmin_enqueue_scripts
hook.
I think maybe the Contact Form 7 plugin is the issue, but I can list the plugins calling wp_register_script()
if that is not it.
#5
@
4 years ago
- Keywords needs-patch added; reporter-feedback removed
- Milestone changed from Awaiting Review to 5.7
- Version set to 4.6
No need for the list of plugins, @Guss77. I can replicate simply by enqueuing the datepicker on wp_enqueue_scripts
, since WP_Customize_Manager
invokes it before exiting: https://github.com/WordPress/wordpress-develop/blob/668581d0f3be00c0babe6929f97ecce654507843/src/wp-includes/class-wp-customize-manager.php#L454
Moving the timing of setup_theme
is going to be a non-starter for backwards-compatibility concerns, I suspect, but the I18N or theme component maintainers might have ideas for doing so. Adding safety checks to wp_localize_jquery_ui_datepicker()
might be a less-risky approach. Let's see whether we can work something out in 5.7.
Thanks for the report, @Guss77!
Can you provide steps to replicate this behavior?