Make WordPress Core

Opened 6 years ago

Last modified 2 weeks ago

#50228 new defect (bug)

Plugins can inadvertently trigger `wp_die()` infinite loop during site creation

Reported by: iandunn Owned by:
Priority: normal Milestone: Awaiting Review
Component: Networks and Sites Version:
Severity: normal Keywords: has-patch has-unit-tests
Cc: Focuses:

Description (last modified by iandunn)

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()
  2. That calls switch_to_blog()
  3. A plugin could hook into the switch_blog() action, and call get_locale().
  4. That calls get_option(), which will trigger a MySQL error, because the tables don't exist.
  5. wpdb->print_error( ) calls _default_wp_die_handler()
  6. That calls get_language_attributes(), which calls get_option()
  7. 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.

  2. _default_wp_die_handler() could avoid calling get_language_attributes() when is_installing() is true.

  3. Something else?

Change History (3)

#1 @iandunn
6 years ago

  • Component GeneralUpgrade/Install
  • Focuses multisite added

#2 @iandunn
6 years ago

  • Component Upgrade/InstallNetworks and Sites
  • Description modified (diff)
  • Focuses multisite removed

This ticket was mentioned in PR #12663 on WordPress/wordpress-develop by @realloc.


2 weeks ago
#3

  • Keywords has-patch has-unit-tests added

https://core.trac.wordpress.org/ticket/50228

get_language_attributes() queries the database. During install (for example, midway through Multisite site creation, before the new site's tables exist), that query can re-trigger the database error that led to wp_die() in the first place, looping wp_die() until PHP's function nesting limit is reached. While installing, the handler must fall back to the already-computed dir attribute instead.

Note: See TracTickets for help on using tickets.