WordPress.org

Make WordPress Core

Ticket #32075: 32075.4.diff

File 32075.4.diff, 15.8 KB (added by swissspidy, 5 years ago)
  • src/wp-admin/admin.php

    diff --git src/wp-admin/admin.php src/wp-admin/admin.php
    index 6e9af5e..b35f073 100644
    else 
    138138        require(ABSPATH . 'wp-admin/menu.php');
    139139
    140140if ( current_user_can( 'manage_options' ) ) {
    141         /**
    142          * Filters the maximum memory limit available for administration screens.
    143          *
    144          * This only applies to administrators, who may require more memory for tasks like updates.
    145          * Memory limits when processing images (uploaded or edited by users of any role) are
    146          * handled separately.
    147          *
    148          * The WP_MAX_MEMORY_LIMIT constant specifically defines the maximum memory limit available
    149          * when in the administration back end. The default is 256M, or 256 megabytes of memory.
    150          *
    151          * @since 3.0.0
    152          *
    153          * @param string 'WP_MAX_MEMORY_LIMIT' The maximum WordPress memory limit. Default 256M.
    154          */
    155         @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
     141        wp_raise_memory_limit( 'admin' );
    156142}
    157143
    158144/**
  • src/wp-admin/includes/file.php

    diff --git src/wp-admin/includes/file.php src/wp-admin/includes/file.php
    index 3b754df..f65b55c 100644
    function unzip_file($file, $to) { 
    570570                return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
    571571
    572572        // Unzip can use a lot of memory, but not this much hopefully
    573         /** This filter is documented in wp-admin/admin.php */
    574         @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
     573        wp_raise_memory_limit( 'admin' );
    575574
    576575        $needed_dirs = array();
    577576        $to = trailingslashit($to);
  • src/wp-admin/includes/image-edit.php

    diff --git src/wp-admin/includes/image-edit.php src/wp-admin/includes/image-edit.php
    index 99e1c40..8b12a4e 100644
    function image_edit_apply_changes( $image, $changes ) { 
    586586function stream_preview_image( $post_id ) {
    587587        $post = get_post( $post_id );
    588588
    589         /** This filter is documented in wp-admin/admin.php */
    590         @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
     589        wp_raise_memory_limit( 'admin' );
    591590
    592591        $img = wp_get_image_editor( _load_image_to_edit_path( $post_id ) );
    593592
  • src/wp-includes/class-wp-image-editor-gd.php

    diff --git src/wp-includes/class-wp-image-editor-gd.php src/wp-includes/class-wp-image-editor-gd.php
    index 96e7bf1..d7823eb 100644
    class WP_Image_Editor_GD extends WP_Image_Editor { 
    9696                if ( ! is_file( $this->file ) && ! preg_match( '|^https?://|', $this->file ) )
    9797                        return new WP_Error( 'error_loading_image', __('File doesn’t exist?'), $this->file );
    9898
    99                 /**
    100                  * Filters the memory limit allocated for image manipulation.
    101                  *
    102                  * @since 3.5.0
    103                  *
    104                  * @param int|string $limit Maximum memory limit to allocate for images. Default WP_MAX_MEMORY_LIMIT.
    105                  *                          Accepts an integer (bytes), or a shorthand string notation, such as '256M'.
    106                  */
    107                 $image_memory_limit = apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT );
    108 
    10999                // Set artificially high because GD uses uncompressed images in memory.
    110                 @ini_set( 'memory_limit', $image_memory_limit );
     100                wp_raise_memory_limit( 'image' );
    111101
    112102                $this->image = @imagecreatefromstring( file_get_contents( $this->file ) );
    113103
  • src/wp-includes/class-wp-image-editor-imagick.php

    diff --git src/wp-includes/class-wp-image-editor-imagick.php src/wp-includes/class-wp-image-editor-imagick.php
    index 3d92d39..82b872d 100644
    class WP_Image_Editor_Imagick extends WP_Image_Editor { 
    137137                if ( ! is_file( $this->file ) && ! preg_match( '|^https?://|', $this->file ) )
    138138                        return new WP_Error( 'error_loading_image', __('File doesn’t exist?'), $this->file );
    139139
    140                 /** This filter is documented in wp-includes/class-wp-image-editor-gd.php */
    141                 $image_memory_limit = apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT );
    142 
    143140                /*
    144141                 * Even though Imagick uses less PHP memory than GD, set higher limit
    145142                 * for users that have low PHP.ini limits.
    146143                 */
    147                 @ini_set( 'memory_limit', $image_memory_limit );
     144                wp_raise_memory_limit( 'image' );
    148145
    149146                try {
    150147                        $this->image = new Imagick( $this->file );
  • src/wp-includes/default-constants.php

    diff --git src/wp-includes/default-constants.php src/wp-includes/default-constants.php
    index fe96e34..d2786fc 100644
     
    1717function wp_initial_constants() {
    1818        global $blog_id;
    1919
    20         // set memory limits
    21         if ( !defined('WP_MEMORY_LIMIT') ) {
    22                 if ( is_multisite() ) {
    23                         define('WP_MEMORY_LIMIT', '64M');
     20        $current_limit     = @ini_get( 'memory_limit' );
     21        $current_limit_int = wp_php_ini_bytes_to_int( $current_limit );
     22
     23        // Define memory limits.
     24        if ( ! defined( 'WP_MEMORY_LIMIT' ) ) {
     25                if ( false === wp_is_ini_value_changeable( 'memory_limit' ) ) {
     26                        define( 'WP_MEMORY_LIMIT', $current_limit );
     27                } elseif ( is_multisite() ) {
     28                        define( 'WP_MEMORY_LIMIT', '64M' );
    2429                } else {
    25                         define('WP_MEMORY_LIMIT', '40M');
     30                        define( 'WP_MEMORY_LIMIT', '40M' );
    2631                }
    2732        }
    2833
    2934        if ( ! defined( 'WP_MAX_MEMORY_LIMIT' ) ) {
    30                 define( 'WP_MAX_MEMORY_LIMIT', '256M' );
     35                if ( false === wp_is_ini_value_changeable( 'memory_limit' ) ) {
     36                        define( 'WP_MAX_MEMORY_LIMIT', $current_limit );
     37                } elseif ( -1 === $current_limit_int || $current_limit_int > 268435456 ) {
     38                        define( 'WP_MAX_MEMORY_LIMIT', $current_limit );
     39                } else {
     40                        define( 'WP_MAX_MEMORY_LIMIT', '256M' );
     41                }
    3142        }
    3243
     44        // Set memory limits.
     45        $wp_limit_int = wp_php_ini_bytes_to_int( WP_MEMORY_LIMIT );
     46        if ( -1 !== $current_limit_int && ( -1 === $wp_limit_int || $wp_limit_int > $current_limit_int ) ) {
     47                @ini_set( 'memory_limit', WP_MEMORY_LIMIT );
     48        }
     49
    3350        if ( ! isset($blog_id) )
    3451                $blog_id = 1;
    3552
    36         // set memory limits.
    37         if ( function_exists( 'memory_get_usage' ) ) {
    38                 $current_limit = @ini_get( 'memory_limit' );
    39                 $current_limit_int = intval( $current_limit );
    40                 if ( false !== strpos( $current_limit, 'G' ) )
    41                         $current_limit_int *= 1024;
    42                 $wp_limit_int = intval( WP_MEMORY_LIMIT );
    43                 if ( false !== strpos( WP_MEMORY_LIMIT, 'G' ) )
    44                         $wp_limit_int *= 1024;
    45 
    46                 if ( -1 != $current_limit && ( -1 == WP_MEMORY_LIMIT || $current_limit_int < $wp_limit_int ) )
    47                         @ini_set( 'memory_limit', WP_MEMORY_LIMIT );
    48         }
    49 
    5053        if ( !defined('WP_CONTENT_DIR') )
    5154                define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' ); // no trailing slash, full paths only - WP_CONTENT_URL is defined further down
    5255
  • src/wp-includes/deprecated.php

    diff --git src/wp-includes/deprecated.php src/wp-includes/deprecated.php
    index 0949f0b..8471a9b 100644
    function wp_load_image( $file ) { 
    31753175        if ( ! function_exists('imagecreatefromstring') )
    31763176                return __('The GD image library is not installed.');
    31773177
    3178         /** This filter is documented in wp-includes/class-wp-image-editor-gd.php */
    3179         $image_memory_limit = apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT );
    3180 
    31813178        // Set artificially high because GD uses uncompressed images in memory.
    3182         @ini_set( 'memory_limit', $image_memory_limit );
     3179        wp_raise_memory_limit( 'image' );
    31833180
    31843181        $image = imagecreatefromstring( file_get_contents( $file ) );
    31853182
  • src/wp-includes/functions.php

    diff --git src/wp-includes/functions.php src/wp-includes/functions.php
    index 690e271..72c8a17 100644
    function mysql_to_rfc3339( $date_string ) { 
    53505350        // Strip timezone information
    53515351        return preg_replace( '/(?:Z|[+-]\d{2}(?::\d{2})?)$/', '', $formatted );
    53525352}
     5353
     5354/**
     5355 * Attempts to raise the PHP memory limit for memory intensive processes.
     5356 *
     5357 * Only allows raising the existing limit and prevents lowering it.
     5358 *
     5359 * @since 4.6.0
     5360 *
     5361 * @param string $context Context in which the function is called.
     5362 *                        Either 'admin' or 'image'. Defaults to 'admin'.
     5363 * @return bool|int|string The limit that was attempted to set or false on failure.
     5364 */
     5365function wp_raise_memory_limit( $context = 'admin' ) {
     5366        // Exit early if the limit cannot be changed.
     5367        if ( false === wp_is_ini_value_changeable( 'memory_limit' ) ) {
     5368                return false;
     5369        }
     5370
     5371        $current_limit     = @ini_get( 'memory_limit' );
     5372        $current_limit_int = wp_php_ini_bytes_to_int( $current_limit );
     5373
     5374        if ( -1 === $current_limit_int ) {
     5375                return false;
     5376        }
     5377
     5378        $wp_max_limit     = WP_MAX_MEMORY_LIMIT;
     5379        $wp_max_limit_int = wp_php_ini_bytes_to_int( $wp_max_limit );
     5380        $filtered_limit   = $wp_max_limit;
     5381
     5382        switch ( $context ) {
     5383                case 'admin':
     5384                        /**
     5385                         * Filters the memory limit available for administration screens.
     5386                         *
     5387                         * This only applies to administrators, who may require more memory for tasks like updates.
     5388                         * Memory limits when processing images (uploaded or edited by users of any role) are
     5389                         * handled separately.
     5390                         *
     5391                         * The WP_MAX_MEMORY_LIMIT constant specifically defines the maximum memory limit available
     5392                         * when in the administration back end. The default is 256M (256 megabytes
     5393                         * of memory) or the original `memory_limit` php.ini value if this is higher.
     5394                         *
     5395                         * @since 3.0.0
     5396                         * @since 4.6.0 The default takes the original `memory_limit` into account.
     5397                         *
     5398                         * @param int|string $filtered_limit The maximum WordPress memory limit.
     5399                         *                                   Accepts an integer (bytes), or a shorthand string
     5400                         *                                   notation, such as '256M'.
     5401                         */
     5402                        $filtered_limit = apply_filters( 'admin_memory_limit', $filtered_limit );
     5403                        break;
     5404
     5405                case 'image':
     5406                        /**
     5407                         * Filters the memory limit allocated for image manipulation.
     5408                         *
     5409                         * @since 3.5.0
     5410                         * @since 4.6.0 The default takes the original `memory_limit` into account.
     5411                         *
     5412                         * @param int|string $filtered_limit Maximum memory limit to allocate for images.
     5413                         *                                   Default 256M or the original php.ini memory_limit,
     5414                         *                                   whichever is higher.
     5415                         *                                   Accepts an integer (bytes), or a shorthand string
     5416                         *                                   notation, such as '256M'.
     5417                         */
     5418                        $filtered_limit = apply_filters( 'image_memory_limit', $filtered_limit );
     5419                        break;
     5420
     5421                default:
     5422                        /**
     5423                         * Filters the memory limit allocated for arbitrary contexts.
     5424                         *
     5425                         * The dynamic portion of the hook name, `$context`, refers to an arbitrary
     5426                         * context passed on calling the function. This allows for plugins to define
     5427                         * their own contexts for raising the memory limit.
     5428                         *
     5429                         * @since 4.6.0
     5430                         *
     5431                         * @param int|string $filtered_limit Maximum memory limit to allocate for images.
     5432                         *                                   Default 256M or the original php.ini memory_limit,
     5433                         *                                   whichever is higher.
     5434                         *                                   Accepts an integer (bytes), or a shorthand string
     5435                         *                                   notation, such as '256M'.
     5436                         */
     5437                        $filtered_limit = apply_filters( "{$context}_memory_limit", $filtered_limit );
     5438                        break;
     5439        }
     5440
     5441        $filtered_limit_int = wp_php_ini_bytes_to_int( $filtered_limit );
     5442
     5443        if ( -1 === $filtered_limit_int || ( $filtered_limit_int > $wp_max_limit_int && $filtered_limit_int > $current_limit_int ) ) {
     5444                @ini_set( 'memory_limit', $filtered_limit );
     5445
     5446                return $filtered_limit;
     5447        } elseif ( -1 === $wp_max_limit_int || $wp_max_limit_int > $current_limit_int ) {
     5448                @ini_set( 'memory_limit', $wp_max_limit );
     5449
     5450                return $wp_max_limit;
     5451        } else {
     5452                return false;
     5453        }
     5454}
  • src/wp-includes/load.php

    diff --git src/wp-includes/load.php src/wp-includes/load.php
    index 80654f1..ae2d796 100644
    function is_ssl() { 
    974974        }
    975975        return false;
    976976}
     977
     978/**
     979 * Converts a PHP ini shorthand byte value to an integer byte value.
     980 *
     981 * @since 4.6.0
     982 *
     983 * @link http://php.net/manual/en/function.ini-get.php
     984 * @link http://php.net/manual/en/faq.using.php#faq.using.shorthandbytes
     985 *
     986 * @param string $value An PHP ini byte value, either shorthand or ordinary.
     987 * @return int Value in bytes.
     988 */
     989function wp_php_ini_bytes_to_int( $value ) {
     990        $value = trim( $value );
     991        $last  = strtolower( substr( $value, -1 ) );
     992
     993        switch ( $last ) {
     994                // Note: the `break` statement is left out on purpose!
     995                case 'g':
     996                        $value *= 1024;
     997                case 'm':
     998                        $value *= 1024;
     999                case 'k':
     1000                        $value *= 1024;
     1001                default:
     1002                        // Left empty on purpose.
     1003                        break;
     1004        }
     1005
     1006        // Deal with large (float) values which run into the maximum integer size.
     1007        return (int) min( PHP_INT_MAX, $value );
     1008}
     1009
     1010/**
     1011 * Determines whether a PHP ini value is changeable at runtime.
     1012 *
     1013 * @since 4.6.0
     1014 *
     1015 * @link http://php.net/manual/en/function.ini-get-all.php
     1016 *
     1017 * @param string $setting The name of the ini setting to check.
     1018 * @return bool True if the value is changeable at runtime. False otherwise.
     1019 */
     1020function wp_is_ini_value_changeable( $setting ) {
     1021        static $ini_all;
     1022
     1023        if ( ! isset( $ini_all ) ) {
     1024                $ini_all = ini_get_all();
     1025        }
     1026
     1027        return isset( $ini_all[ $setting ]['access'] ) &&
     1028               ( INI_ALL === $ini_all[ $setting ]['access'] || INI_USER === $ini_all[ $setting ]['access'] );
     1029}
  • tests/phpunit/tests/functions.php

    diff --git tests/phpunit/tests/functions.php tests/phpunit/tests/functions.php
    index e28e65f..24d1889 100644
    class Tests_Functions extends WP_UnitTestCase { 
    887887
    888888                $this->assertNull( wp_ext2type( 'unknown_format' ) );
    889889        }
     890
     891        /**
     892         * Test raising the memory limit.
     893         *
     894         * Unfortunately as the default for 'WP_MAX_MEMORY_LIMIT' in the
     895         * test suite is -1, we can not test the memory limit negotiations.
     896         *
     897         * @ticket 32075
     898         */
     899        function test_wp_raise_memory_limit() {
     900                ini_set( 'memory_limit', '40M' );
     901                $this->assertSame( -1, wp_raise_memory_limit() );
     902                $this->assertEquals( '-1', ini_get( 'memory_limit' ) );
     903        }
    890904}
  • new file tests/phpunit/tests/load.php

    diff --git tests/phpunit/tests/load.php tests/phpunit/tests/load.php
    new file mode 100644
    index 0000000..1eedcb4
    - +  
     1<?php
     2
     3/**
     4 * @group load.php
     5 */
     6class Tests_Load extends WP_UnitTestCase {
     7
     8        /**
     9         * Test converting PHP ini byte values to integer byte values.
     10         *
     11         * @dataProvider data_wp_php_ini_bytes_to_int
     12         */
     13        function test_wp_php_ini_bytes_to_int( $value, $expected ) {
     14                $this->assertSame( $expected, wp_php_ini_bytes_to_int( $value ) );
     15        }
     16
     17        function data_wp_php_ini_bytes_to_int() {
     18                $array = array(
     19                        // Integer input
     20                        array( -1, -1 ), // = no memory limit
     21                        array( 8388608, 8388608 ), // 8M
     22
     23                        // String input (memory limit shorthand values)
     24                        array( '32k', 32768 ),
     25                        array( '64K', 65536 ),
     26                        array( '128m', 134217728 ),
     27                        array( '256M', 268435456 ),
     28                        array( '1g', 1073741824 ),
     29                        array( '1024', 1024 ), // No letter will be interpreted as integer value.
     30
     31                        // Edge cases
     32                        array( 'g', 0 ),
     33                        array( 'null', 0 ),
     34                        array( 'off', 0 ),
     35                );
     36
     37                // Test while running into maximum integer size limit on 32bit systems.
     38                if ( 2147483647 === PHP_INT_MAX ) {
     39                        $array[] = array( '2G', 2147483647 );
     40                        $array[] = array( '4G', 2147483647 );
     41                } else {
     42                        $array[] = array( '2G', 2147483648 );
     43                        $array[] = array( '4G', 4294967296 );
     44                }
     45
     46                return $array;
     47        }
     48
     49        /**
     50         * Test the determining of the changability of a PHP ini value.
     51         *
     52         * @dataProvider data_wp_is_ini_value_changable
     53         */
     54        function test_wp_is_ini_value_changable( $setting, $expected ) {
     55                $this->assertSame( $expected, wp_is_ini_value_changeable( $setting ) );
     56        }
     57
     58        function data_wp_is_ini_value_changable() {
     59                $array = array(
     60                        array( 'memory_limit', true ), // PHP_INI_ALL
     61                        array( 'log_errors', true ), // PHP_INI_ALL
     62                        array( 'upload_max_filesize', false ), // PHP_INI_PERDIR
     63                        array( 'upload_tmp_dir', false ), // PHP_INI_SYSTEM
     64                );
     65
     66                if ( extension_loaded( 'Tidy' ) && version_compare( PHP_VERSION, '7.0.0', '>' ) ) {
     67                        $array[] = array( 'tidy.clean_output', true ); // PHP_INI_USER
     68                }
     69
     70                return $array;
     71        }
     72}