Make WordPress Core

Ticket #32075: 32075-improved-patch-v3.patch

File 32075-improved-patch-v3.patch, 12.2 KB (added by jrf, 9 years ago)
  • src/wp-admin/admin.php

    From 3756d9699691f5bb5b18660a63422ea90df342ea Mon Sep 17 00:00:00 2001
    From: jrfnl <github_nospam@adviesenzo.nl>
    Date: Thu, 10 Dec 2015 12:02:49 +0100
    Subject: [PATCH] Prevent WP setting the memory limit to a value lower than it
     currently is.
    
    Also fixes a bug in how the memory limits were tested in the first place.
    ---
     src/wp-admin/admin.php                            | 16 +-----
     src/wp-admin/includes/file.php                    |  3 +-
     src/wp-admin/includes/image-edit.php              |  3 +-
     src/wp-includes/class-wp-image-editor-gd.php      | 10 +---
     src/wp-includes/class-wp-image-editor-imagick.php |  3 +-
     src/wp-includes/default-constants.php             | 31 +++++------
     src/wp-includes/deprecated.php                    |  3 +-
     src/wp-includes/functions.php                     | 68 +++++++++++++++++++++++
     src/wp-includes/load.php                          | 26 +++++++++
     tests/phpunit/tests/functions.php                 | 16 ++++++
     10 files changed, 132 insertions(+), 47 deletions(-)
    
    diff --git a/src/wp-admin/admin.php b/src/wp-admin/admin.php
    index b1fa18f..11f54b5 100644
    a b else 
    138138        require(ABSPATH . 'wp-admin/menu.php');
    139139
    140140if ( current_user_can( 'manage_options' ) ) {
    141         /**
    142          * Filter 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 a/src/wp-admin/includes/file.php b/src/wp-admin/includes/file.php
    index b8052eb..8d7d697 100644
    a b function unzip_file($file, $to) { 
    546546                return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
    547547
    548548        // Unzip can use a lot of memory, but not this much hopefully
    549         /** This filter is documented in wp-admin/admin.php */
    550         @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
     549        wp_raise_memory_limit( 'admin' );
    551550
    552551        $needed_dirs = array();
    553552        $to = trailingslashit($to);
  • src/wp-admin/includes/image-edit.php

    diff --git a/src/wp-admin/includes/image-edit.php b/src/wp-admin/includes/image-edit.php
    index 4015f30..d4b902a 100644
    a b function image_edit_apply_changes( $image, $changes ) { 
    557557function stream_preview_image( $post_id ) {
    558558        $post = get_post( $post_id );
    559559
    560         /** This filter is documented in wp-admin/admin.php */
    561         @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
     560        wp_raise_memory_limit( 'admin' );
    562561
    563562        $img = wp_get_image_editor( _load_image_to_edit_path( $post_id ) );
    564563
  • src/wp-includes/class-wp-image-editor-gd.php

    diff --git a/src/wp-includes/class-wp-image-editor-gd.php b/src/wp-includes/class-wp-image-editor-gd.php
    index 2093c6b..9cb756d 100644
    a b 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&#8217;t exist?'), $this->file );
    9898
    99                 /**
    100                  * Filter 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                  */
    10799                // Set artificially high because GD uses uncompressed images in memory
    108                 @ini_set( 'memory_limit', apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT ) );
     100                wp_raise_memory_limit( 'image' );
    109101
    110102                $this->image = @imagecreatefromstring( file_get_contents( $this->file ) );
    111103
  • src/wp-includes/class-wp-image-editor-imagick.php

    diff --git a/src/wp-includes/class-wp-image-editor-imagick.php b/src/wp-includes/class-wp-image-editor-imagick.php
    index a14fa40..1888316 100644
    a b class WP_Image_Editor_Imagick extends WP_Image_Editor { 
    129129                if ( ! is_file( $this->file ) && ! preg_match( '|^https?://|', $this->file ) )
    130130                        return new WP_Error( 'error_loading_image', __('File doesn&#8217;t exist?'), $this->file );
    131131
    132                 /** This filter is documented in wp-includes/class-wp-image-editor-imagick.php */
    133132                // Even though Imagick uses less PHP memory than GD, set higher limit for users that have low PHP.ini limits
    134                 @ini_set( 'memory_limit', apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT ) );
     133                wp_raise_memory_limit( 'image' );
    135134
    136135                try {
    137136                        $this->image = new Imagick( $this->file );
  • src/wp-includes/default-constants.php

    diff --git a/src/wp-includes/default-constants.php b/src/wp-includes/default-constants.php
    index d7a0e4e..8ceb45a 100644
    a b  
    1717function wp_initial_constants() {
    1818        global $blog_id;
    1919
    20         // set memory limits
     20        // Define memory limits.
    2121        if ( !defined('WP_MEMORY_LIMIT') ) {
    2222                if ( is_multisite() ) {
    2323                        define('WP_MEMORY_LIMIT', '64M');
    function wp_initial_constants() { 
    2626                }
    2727        }
    2828
     29        $current_limit     = @ini_get( 'memory_limit' );
     30        $current_limit_int = wp_php_ini_bytes_to_int( $current_limit );
     31
    2932        if ( ! defined( 'WP_MAX_MEMORY_LIMIT' ) ) {
    30                 define( 'WP_MAX_MEMORY_LIMIT', '256M' );
     33                if ( -1 === $current_limit_int || $current_limit_int > 268435456 ) {
     34                        define( 'WP_MAX_MEMORY_LIMIT', $current_limit );
     35                } else {
     36                        define( 'WP_MAX_MEMORY_LIMIT', '256M' );
     37                }
     38        }
     39
     40        // Set memory limits.
     41        $wp_limit_int = wp_php_ini_bytes_to_int( WP_MEMORY_LIMIT );
     42        if ( -1 !== $current_limit_int && ( -1 === $wp_limit_int || $wp_limit_int > $current_limit_int ) ) {
     43                @ini_set( 'memory_limit', WP_MEMORY_LIMIT );
    3144        }
    3245
    3346        if ( ! isset($blog_id) )
    3447                $blog_id = 1;
    3548
    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 
    5049        if ( !defined('WP_CONTENT_DIR') )
    5150                define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' ); // no trailing slash, full paths only - WP_CONTENT_URL is defined further down
    5251
  • src/wp-includes/deprecated.php

    diff --git a/src/wp-includes/deprecated.php b/src/wp-includes/deprecated.php
    index 571de24..d357f03 100644
    a b function wp_load_image( $file ) { 
    31343134                return __('The GD image library is not installed.');
    31353135
    31363136        // Set artificially high because GD uses uncompressed images in memory
    3137         @ini_set( 'memory_limit', apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT ) );
     3137        wp_raise_memory_limit( 'image' );
     3138
    31383139        $image = imagecreatefromstring( file_get_contents( $file ) );
    31393140
    31403141        if ( !is_resource( $image ) )
  • src/wp-includes/functions.php

    diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php
    index e3fb353..51fe439 100644
    a b function mysql_to_rfc3339( $date_string ) { 
    51665166        // Strip timezone information
    51675167        return preg_replace( '/(?:Z|[+-]\d{2}(?::\d{2})?)$/', '', $formatted );
    51685168}
     5169
     5170/**
     5171 * WP raise memory limit.
     5172 *
     5173 * Raises the PHP memory limit for memory intensive processes.
     5174 * Only allows filter to raise and not lower the exciting limit.
     5175 *
     5176 * @param string $context Context in which the function is called.
     5177 *                        Either 'admin' or 'image'. Defaults to 'admin'.
     5178 */
     5179function wp_raise_memory_limit( $context = 'admin' ) {
     5180        $current_limit     = @ini_get( 'memory_limit' );
     5181        $current_limit_int = wp_php_ini_bytes_to_int( $current_limit );
     5182
     5183        if ( -1 === $current_limit_int ) {
     5184                return;
     5185        }
     5186
     5187        $wp_max_limit     = WP_MAX_MEMORY_LIMIT;
     5188        $wp_max_limit_int = wp_php_ini_bytes_to_int( $wp_max_limit );
     5189        $filtered_limit   = $wp_max_limit;
     5190
     5191        switch ( $context ) {
     5192                case 'admin':
     5193                        /**
     5194                         * Filter the maximum memory limit available for administration screens.
     5195                         *
     5196                         * This only applies to administrators, who may require more memory for tasks like updates.
     5197                         * Memory limits when processing images (uploaded or edited by users of any role) are
     5198                         * handled separately.
     5199                         *
     5200                         * The WP_MAX_MEMORY_LIMIT constant specifically defines the maximum memory limit available
     5201                         * when in the administration back-end. The default is 256M (256 megabytes
     5202                         * of memory) or the original `memory_limit` php.ini value if this is higher.
     5203                         *
     5204                         * @since 3.0.0
     5205                         *
     5206                         * @param int|string $filtered_limit The maximum WordPress memory limit.
     5207                         *                                   Accepts an integer (bytes), or a shorthand string
     5208                         *                                   notation, such as '256M'.
     5209                         */
     5210                        $filtered_limit = apply_filters( $filter, $filtered_limit );
     5211                        break;
     5212
     5213                case 'image':
     5214                        /**
     5215                         * Filter the memory limit allocated for image manipulation.
     5216                         *
     5217                         * @since 3.5.0
     5218                         *
     5219                         * @param int|string $filtered_limit Maximum memory limit to allocate for images.
     5220                         *                                   Default 256M or the original php.ini memory_limit,
     5221                         *                                   whichever is higher.
     5222                         *                                   Accepts an integer (bytes), or a shorthand string
     5223                         *                                   notation, such as '256M'.
     5224                         */
     5225                        $filtered_limit = apply_filters( $filter, $filtered_limit );
     5226                        break;
     5227        }
     5228
     5229        $filtered_limit_int = wp_php_ini_bytes_to_int( $filtered_limit );
     5230
     5231        if ( -1 === $filtered_limit_int || ( $filtered_limit_int > $wp_max_limit_int && $filtered_limit_int > $current_limit_int ) ) {
     5232                @ini_set( 'memory_limit', $filtered_limit );
     5233        } elseif ( -1 === $wp_max_limit_int || $wp_max_limit_int > $current_limit_int ) {
     5234                @ini_set( 'memory_limit', $wp_max_limit );
     5235        }
     5236}
  • src/wp-includes/load.php

    diff --git a/src/wp-includes/load.php b/src/wp-includes/load.php
    index 9d247ba..017558b 100644
    a b function wp_installing( $is_installing = null ) { 
    892892
    893893        return (bool) $installing;
    894894}
     895
     896/**
     897 * Convert a PHP ini shorthand byte value to an integer byte value.
     898 *
     899 * @see http://php.net/manual/en/function.ini-get.php
     900 * @see http://php.net/manual/en/faq.using.php#faq.using.shorthandbytes
     901 *
     902 * @param string $value An PHP ini byte value, either shorthand or ordinary.
     903 * @return int Value in bytes.
     904 */
     905function wp_php_ini_bytes_to_int( $value ) {
     906        $value = trim( $value );
     907        $last  = strtolower( $value[ strlen( $value ) - 1 ] );
     908       
     909        switch( $last ) {
     910                // Note: the `break` statement is left out on purpose!
     911                case 'g':
     912                        $value *= 1024;
     913                case 'm':
     914                        $value *= 1024;
     915                case 'k':
     916                        $value *= 1024;
     917        }
     918
     919        return (int) $value;
     920}
  • tests/phpunit/tests/functions.php

    diff --git a/tests/phpunit/tests/functions.php b/tests/phpunit/tests/functions.php
    index 631b303..2c4ab82 100644
    a b class Tests_Functions extends WP_UnitTestCase { 
    717717                the_date( 'Y', 'before ', ' after', false );
    718718                $this->assertEquals( '', ob_get_clean() );
    719719        }
     720
     721        /**
     722         * Test raising the memory limit.
     723         *
     724         * Unfortunately as the default for 'WP_MAX_MEMORY_LIMIT' in the test suite is -1, we can not
     725         * test the memory limit negotiations.
     726         *
     727         * @ticket 32075
     728         */
     729        function test_wp_raise_memory_limit() {
     730                $original = ini_get( 'memory_limit' );
     731
     732                ini_set( 'memory_limit', '40M' );
     733                wp_raise_memory_limit();
     734                $this->assertEquals( '-1', ini_get( 'memory_limit' ) );
     735        }
    720736}