[wp-trac] [WordPress Trac] #50228: Plugins can inadvertently trigger `wp_die()` infinite loop during site creation
WordPress Trac
noreply at wordpress.org
Fri May 22 21:11:05 UTC 2020
#50228: Plugins can inadvertently trigger `wp_die()` infinite loop during site
creation
--------------------------------+------------------------------
Reporter: iandunn | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Networks and Sites | Version:
Severity: normal | Resolution:
Keywords: | Focuses:
--------------------------------+------------------------------
Changes (by iandunn):
* focuses: multisite =>
* component: Upgrade/Install => Networks and Sites
Old description:
> ==== Problem
>
> This is one example of an execution path that leads to an infinite loop,
> but there are probably several others. It can happen to any callback that
> tries to query a new site's tables after the `wp_insert_site` action, and
> before the `make_db_current_silent()` call inside `wp_initialize_site()`.
>
> 1. Creating a site in the UI or programatically calls eventually
> `wp_initialize_site()`
> 1. That calls `switch_to_blog()`
> 1. A plugin could hook into the `switch_blog()` action, and call
> `get_locale()`.
> 1. That calls `get_option()`, which will trigger a MySQL error, because
> the tables don't exist.
> 1. `wpdb->print_error( )` calls `_default_wp_die_handler()`
> 1. That calls `get_language_attributes()`, which calls `get_option()`
> 1. The process repeats until PHP gives up.
>
> > ( ! ) Fatal error: Uncaught Error: Maximum function nesting level of
> '256' reached, aborting! in wp-includes/class-wp-hook.php on line 196
>
> It's not obvious to plugin developers that this kind of thing can happen,
> so I think Core should handle it gracefully.
>
> Related: #49263
>
> ==== Potential solutions
>
> 1. `wp_die()` coule call a new `_installing_wp_die_handler()` when
> `is_installing()` is `true`. This could be a minimal version of
> `_default_wp_die_handler()`, where no database queries are
> made.[[br]][[br]]
> 1. `_default_wp_die_handler()` could avoid calling
> `get_language_attributes()` when `is_installing()` is
> `true`.[[br]][[br]]
> 1. Something else?
New description:
==== Problem
This is one example of an execution path that leads to an infinite loop,
but there are probably several others. It can happen to any callback that
tries to query a new site's tables after the `wp_insert_site` action, and
before the `make_db_current_silent()` call inside `wp_initialize_site()`.
1. Creating a new site in a Multisite network will eventually call
`wp_initialize_site()`
1. That calls `switch_to_blog()`
1. A plugin could hook into the `switch_blog()` action, and call
`get_locale()`.
1. That calls `get_option()`, which will trigger a MySQL error, because
the tables don't exist.
1. `wpdb->print_error( )` calls `_default_wp_die_handler()`
1. That calls `get_language_attributes()`, which calls `get_option()`
1. The process repeats until PHP gives up.
> ( ! ) Fatal error: Uncaught Error: Maximum function nesting level of
'256' reached, aborting! in wp-includes/class-wp-hook.php on line 196
It's not obvious to plugin developers that this kind of thing can happen,
so I think Core should handle it gracefully.
Related: #49263
==== Potential solutions
1. `wp_die()` coule call a new `_installing_wp_die_handler()` when
`is_installing()` is `true`. This could be a minimal version of
`_default_wp_die_handler()`, where no database queries are
made.[[br]][[br]]
1. `_default_wp_die_handler()` could avoid calling
`get_language_attributes()` when `is_installing()` is `true`.[[br]][[br]]
1. Something else?
--
--
Ticket URL: <https://core.trac.wordpress.org/ticket/50228#comment:2>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list