[wp-trac] [WordPress Trac] #55711: set_time_limit( 300 ); in Class WP_Upgrader causes crashes in PHP8 when hosting disables it

WordPress Trac noreply at wordpress.org
Thu May 12 21:56:46 UTC 2022


#55711: set_time_limit( 300 ); in Class WP_Upgrader causes crashes in PHP8 when
hosting disables it
-----------------------------+------------------------------
 Reporter:  theode           |       Owner:  (none)
     Type:  defect (bug)     |      Status:  new
 Priority:  normal           |   Milestone:  Awaiting Review
Component:  Upgrade/Install  |     Version:  5.9.3
 Severity:  critical         |  Resolution:
 Keywords:  php8             |     Focuses:  administration
-----------------------------+------------------------------

Comment (by jrf):

 Replying to [comment:5 costdev]:
 > > @hellofromTonya function_exists( 'set_time_limit' ) would guard
 against invoking the native PHP function when it's been disabled and is
 not in memory.
 >
 > To clarify this:
 > - `function_exists()` will return `false` for a native function that is
 not in memory or in the PHP binary. However, it will return `true` for a
 native function disabled via the `disable_functions` directive. (I know!)
 > - There are three ways I'm aware of to return `true` for a native
 function disabled via `disabled_functions`:
 >     1. `false === strpos()` as WooCommerce and SMTP use.
 >     2. `! str_contains()` - a modern version of the above.
 >     3. `is_callable()` - Which feels more accurate in context. Check if
 it exists with `function_exists()`, check if it's callable with
 `is_callable()`.

 Well actually....

 Only a check with `strpos()`/`str_contains()` will give consistent results
 cross-version, which makes every other way of checking this invalid.

 There was a change in how PHP reports on disabled functions in PHP 8.0
 which is relevant here:

 > Disabled functions are now treated exactly like non-existent functions.
 > Calling a disabled function will report it as unknown, and redefining a
 disabled function is now possible.

 Ref: https://github.com/php/php-
 src/blob/5e34638c1cc42520c86008cec2f7b20f3d678701/UPGRADING#L186-L188

 This can be confirmed by running the following script on multiple PHP
 versions:
 {{{#!php
 <?php
 echo 'function_exists: ', var_export(function_exists('set_time_limit'),
 true), PHP_EOL;
 echo 'is_callable: ', var_export(is_callable('set_time_limit'), true),
 PHP_EOL;
 echo 'strpos/str_contains: ', var_export(strpos( ini_get(
 'disable_functions' ), 'set_time_limit' ), true), PHP_EOL;
 }}}


 Do make sure to set `disable_functions = 'set_time_limit'` in the
 `php.ini` file prior to running the script as it can not be changed at
 run-time (which is also the reason why I'm not posting an 3v4l link).

 The output will look like this:

 {{{
 "PHP 5.6"
 ------------------
 function_exists: false
 is_callable: true
 strpos/str_contains: 0

 "PHP 7.0"
 ------------------
 function_exists: false
 is_callable: true
 strpos/str_contains: 0

 "PHP 7.2"
 ------------------
 function_exists: false
 is_callable: true
 strpos/str_contains: 0

 "PHP 7.4"
 ------------------
 function_exists: true
 is_callable: true
 strpos/str_contains: 0

 "PHP 8.0"
 ------------------
 function_exists: false
 is_callable: false
 strpos/str_contains: 0

 "PHP 8.1"
 ------------------
 function_exists: false
 is_callable: false
 strpos/str_contains: 0
 }}}

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/55711#comment:6>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list