WordPress.org

Make WordPress Core

Ticket #27538: 27538.3.patch

File 27538.3.patch, 2.8 KB (added by David_Rothstein, 6 years ago)

Use a unique cache key for the Recent Posts and Recent Comments widgets, to prevent cache leaking bugs.

  • src/wp-includes/widgets.php

    class WP_Widget { 
    122122                return 'widget-' . $this->id_base . '-' . $this->number . '-' . $field_name;
    123123        }
    124124
     125        /**
     126         * Constructs a hash that is unique to the widget instance.
     127         *
     128         * This function can be used by widget classes to create a cache key
     129         * for caching the widget output, assuming that the output is uniquely
     130         * determined by the provided display arguments and widget instance
     131         * settings. For a usage example, see WP_Widget_Recent_Posts::widget().
     132         *
     133         * @since 3.9.0
     134         *
     135         * @param array $args Display arguments including before_title, after_title, before_widget, and after_widget.
     136         * @param array $instance The settings for the particular instance of the widget.
     137         * @return string A hash based on the provided display arguments and instance settings.
     138         */
     139        function hash($args, $instance) {
     140                // The hash must be unique to the provided display arguments
     141                // and instance settings, but the order doesn't matter.
     142                ksort( $args );
     143                ksort( $instance );
     144                return wp_hash( serialize( $args ) . serialize( $instance ) );
     145        }
     146
    125147        // Private Functions. Don't worry about these.
    126148
    127149        function _register() {
  • src/wp-includes/default-widgets.php

    class WP_Widget_Recent_Posts extends WP_Widget { 
    668668                if ( ! isset( $args['widget_id'] ) )
    669669                        $args['widget_id'] = $this->id;
    670670
    671                 if ( isset( $cache[ $args['widget_id'] ] ) ) {
    672                         echo $cache[ $args['widget_id'] ];
     671                $cache_key = $this->hash( $args, $instance );
     672                if ( isset( $cache[ $cache_key ] ) ) {
     673                        echo $cache[ $cache_key ];
    673674                        return;
    674675                }
    675676
    class WP_Widget_Recent_Posts extends WP_Widget { 
    723724
    724725                endif;
    725726
    726                 $cache[$args['widget_id']] = ob_get_flush();
     727                $cache[$cache_key] = ob_get_flush();
    727728                wp_cache_set('widget_recent_posts', $cache, 'widget');
    728729        }
    729730
    class WP_Widget_Recent_Comments extends WP_Widget 
    815816                if ( ! isset( $args['widget_id'] ) )
    816817                        $args['widget_id'] = $this->id;
    817818
    818                 if ( isset( $cache[ $args['widget_id'] ] ) ) {
    819                         echo $cache[ $args['widget_id'] ];
     819                $cache_key = $this->hash( $args, $instance );
     820                if ( isset( $cache[ $cache_key ] ) ) {
     821                        echo $cache[ $cache_key ];
    820822                        return;
    821823                }
    822824
    class WP_Widget_Recent_Comments extends WP_Widget 
    865867                $output .= $after_widget;
    866868
    867869                echo $output;
    868                 $cache[$args['widget_id']] = $output;
     870                $cache[$cache_key] = $output;
    869871                wp_cache_set('widget_recent_comments', $cache, 'widget');
    870872        }
    871873