WordPress.org

Make WordPress Core

Ticket #36901: 36901.7.diff

File 36901.7.diff, 11.4 KB (added by rachelbaker, 3 years ago)

Same as 36901.6.diff with correction to parameters for the check_comment action.

  • src/wp-includes/comment.php

     
    586586 * Validates whether this comment is allowed to be made.
    587587 *
    588588 * @since 2.0.0
     589 * @since 4.7.0 The `$avoid_die` parameter was added.
    589590 *
    590591 * @global wpdb $wpdb WordPress database abstraction object.
    591592 *
    592  * @param array $commentdata Contains information on the comment
    593  * @return int|string Signifies the approval status (0|1|'spam')
     593 * @param array   $commentdata Contains information on the comment.
     594 * @param boolean $avoid_die   Should errors be returned as WP_Error objects
     595 *                             instead of executing wp_die()? Default false.
     596 * @return int|string|WP_Error Allowed comments return the approval status (0|1|'spam').
     597 *                             If $avoid_die is true, unallowed comments return a WP_Error.
    594598 */
    595 function wp_allow_comment( $commentdata ) {
     599function wp_allow_comment( $commentdata, $avoid_die = false ) {
    596600        global $wpdb;
    597601
    598602        // Simple duplicate check
     
    637641                 * @param array $commentdata Comment data.
    638642                 */
    639643                do_action( 'comment_duplicate_trigger', $commentdata );
    640                 if ( wp_doing_ajax() ) {
    641                         die( __('Duplicate comment detected; it looks as though you’ve already said that!') );
     644                if ( true === $avoid_die ) {
     645                        return new WP_Error( 'comment_duplicate', __( 'Duplicate comment detected; it looks as though you’ve already said that!' ), 409 );
     646                } else {
     647                        if ( wp_doing_ajax() ) {
     648                                die( __('Duplicate comment detected; it looks as though you’ve already said that!') );
     649                        }
     650
     651                        wp_die( __( 'Duplicate comment detected; it looks as though you’ve already said that!' ), 409 );
    642652                }
    643                 wp_die( __( 'Duplicate comment detected; it looks as though you’ve already said that!' ), 409 );
    644653        }
    645654
    646655        /**
     
    649658         * Allows checking for comment flooding.
    650659         *
    651660         * @since 2.3.0
     661         * @since 4.7.0 The `$avoid_die` parameter was added.
    652662         *
    653663         * @param string $comment_author_IP    Comment author's IP address.
    654664         * @param string $comment_author_email Comment author's email.
    655665         * @param string $comment_date_gmt     GMT date the comment was posted.
     666         * @param boolean $avoid_die           Prevent executing wp_die() or die()
     667         *                                     if a comment flood is occuring.
    656668         */
    657669        do_action(
    658670                'check_comment_flood',
    659671                $commentdata['comment_author_IP'],
    660672                $commentdata['comment_author_email'],
    661                 $commentdata['comment_date_gmt']
     673                $commentdata['comment_date_gmt'],
     674                $avoid_die
    662675        );
    663676
     677        /**
     678         * Filters whether a comment is part of a comment flood or not.
     679         *
     680         * @since 4.7.0
     681         *
     682         * @param boolean $is_flood                            Is a comment flooding occurring?
     683         *                                                     Default is false.
     684         * @param string  $commentdata['comment_author_IP']    Comment author's IP address.
     685         * @param string  $commentdata['comment_author_email'] Comment author's email.
     686         * @param string  $commentdata['comment_date_gmt']     GMT date the comment was posted.
     687         * @param boolean $avoid_die                           Prevent executing wp_die() or die()
     688         *                                                     if a comment flood is occuring.
     689         */
     690        $is_flood = apply_filters(
     691                'wp_is_comment_flood',
     692                false,
     693                $commentdata['comment_author_IP'],
     694                $commentdata['comment_author_email'],
     695                $commentdata['comment_date_gmt'],
     696                $avoid_die
     697        );
     698
     699        if ( $is_flood ) {
     700                return new WP_Error( 'comment_flood', __( 'You are posting comments too quickly. Slow down.' ), 429 );
     701        }
     702
    664703        if ( ! empty( $commentdata['user_id'] ) ) {
    665704                $user = get_userdata( $commentdata['user_id'] );
    666705                $post_author = $wpdb->get_var( $wpdb->prepare(
     
    713752}
    714753
    715754/**
     755 * Hooks WP's native database-based comment-flood check.
     756 *
     757 * @since 2.3.0
     758 * @since 4.7.0 Converted to be an add_filter() wrapper.
     759 */
     760function check_comment_flood_db() {
     761        add_filter( 'wp_is_comment_flood', 'wp_check_comment_flood', 10, 5 );
     762}
     763
     764/**
    716765 * Check whether comment flooding is occurring.
    717766 *
    718767 * Won't run, if current user can manage options, so to not block
    719768 * administrators.
    720769 *
    721  * @since 2.3.0
     770 * @since 4.7.0
    722771 *
    723772 * @global wpdb $wpdb WordPress database abstraction object.
    724773 *
    725  * @param string $ip Comment IP.
    726  * @param string $email Comment author email address.
    727  * @param string $date MySQL time string.
     774 * @param boolean $is_flood  Is a comment flooding occurring?
     775 * @param string  $ip        Comment IP.
     776 * @param string  $email     Comment author email address.
     777 * @param string  $date      MySQL time string.
     778 * @param boolean $avoid_die Prevent executing wp_die() or die() if a
     779 *                           comment flood is occuring. Default is false.
     780 * @return boolean|WP_Error True or a WP_Error if a comment flood is occuring,
     781 *                          otherwise false.
    728782 */
    729 function check_comment_flood_db( $ip, $email, $date ) {
     783function wp_check_comment_flood( $is_flood, $ip, $email, $date, $avoid_die = false ) {
     784
    730785        global $wpdb;
     786
     787        if ( true === $is_flood ) {
     788                return $is_flood;
     789        }
     790
    731791        // don't throttle admins or moderators
    732792        if ( current_user_can( 'manage_options' ) || current_user_can( 'moderate_comments' ) ) {
    733                 return;
     793                return false;
    734794        }
    735795        $hour_ago = gmdate( 'Y-m-d H:i:s', time() - HOUR_IN_SECONDS );
    736796
     
    772832                         * @param int $time_newcomment  Timestamp of when the new comment was posted.
    773833                         */
    774834                        do_action( 'comment_flood_trigger', $time_lastcomment, $time_newcomment );
     835                        if ( true === $avoid_die ) {
     836                                return true;
     837                        } else {
     838                                if ( wp_doing_ajax() ) {
     839                                        die( __('You are posting comments too quickly. Slow down.') );
     840                                }
    775841
    776                         if ( wp_doing_ajax() )
    777                                 die( __('You are posting comments too quickly. Slow down.') );
    778 
    779                         wp_die( __( 'You are posting comments too quickly. Slow down.' ), 429 );
     842                                wp_die( __( 'You are posting comments too quickly. Slow down.' ), 429 );
     843                        }
    780844                }
    781845        }
     846
     847        return false;
    782848}
    783849
    784850/**
     
    17221788 *
    17231789 * @since 1.5.0
    17241790 * @since 4.3.0 'comment_agent' and 'comment_author_IP' can be set via `$commentdata`.
     1791 * @since 4.7.0 The `$avoid_die` parameter was added.
    17251792 *
    17261793 * @see wp_insert_comment()
    17271794 * @global wpdb $wpdb WordPress database abstraction object.
     
    17451812 *     @type string $comment_author_IP    Comment author IP address in IPv4 format. Default is the value of
    17461813 *                                        'REMOTE_ADDR' in the `$_SERVER` superglobal sent in the original request.
    17471814 * }
    1748  * @return int|false The ID of the comment on success, false on failure.
     1815 * @param boolean $avoid_die Should errors be returned as WP_Error objects instead of
     1816 *                           executing wp_die()? Default false.
     1817 * @return int|false|WP_Error The ID of the comment on success, false or WP_Error on failure.
    17491818 */
    1750 function wp_new_comment( $commentdata ) {
     1819function wp_new_comment( $commentdata, $avoid_die = false ) {
    17511820        global $wpdb;
    17521821
    17531822        if ( isset( $commentdata['user_ID'] ) ) {
     
    17961865
    17971866        $commentdata = wp_filter_comment($commentdata);
    17981867
    1799         $commentdata['comment_approved'] = wp_allow_comment($commentdata);
     1868        $commentdata['comment_approved'] = wp_allow_comment( $commentdata, $avoid_die );
     1869        if ( is_wp_error( $commentdata['comment_approved'] ) ) {
     1870                return $commentdata['comment_approved'];
     1871        }
    18001872
    18011873        $comment_ID = wp_insert_comment($commentdata);
    18021874        if ( ! $comment_ID ) {
     
    18101882
    18111883                $commentdata = wp_filter_comment( $commentdata );
    18121884
    1813                 $commentdata['comment_approved'] = wp_allow_comment( $commentdata );
     1885                $commentdata['comment_approved'] = wp_allow_comment( $commentdata, $avoid_die );
     1886                if ( is_wp_error( $commentdata['comment_approved'] ) ) {
     1887                        return $commentdata['comment_approved'];
     1888                }
    18141889
    18151890                $comment_ID = wp_insert_comment( $commentdata );
    18161891                if ( ! $comment_ID ) {
     
    29323007                'user_ID'
    29333008        );
    29343009
    2935         $comment_id = wp_new_comment( wp_slash( $commentdata ) );
     3010        $comment_id = wp_new_comment( wp_slash( $commentdata ), true );
     3011        if ( is_wp_error( $comment_id ) ) {
     3012                return $comment_id;
     3013        }
     3014
    29363015        if ( ! $comment_id ) {
    29373016                return new WP_Error( 'comment_save_error', __( '<strong>ERROR</strong>: The comment could not be saved. Please try again later.' ), 500 );
    29383017        }
    29393018
    29403019        return get_comment( $comment_id );
    2941 
    29423020}
  • src/wp-includes/default-filters.php

     
    197197add_filter( 'teeny_mce_before_init',    '_mce_set_direction'                  );
    198198add_filter( 'pre_kses',                 'wp_pre_kses_less_than'               );
    199199add_filter( 'sanitize_title',           'sanitize_title_with_dashes',   10, 3 );
    200 add_action( 'check_comment_flood',      'check_comment_flood_db',       10, 3 );
     200add_action( 'check_comment_flood',      'check_comment_flood_db',       10, 4 );
    201201add_filter( 'comment_flood_filter',     'wp_throttle_comment_flood',    10, 3 );
    202202add_filter( 'pre_comment_content',      'wp_rel_nofollow',              15    );
    203203add_filter( 'comment_email',            'antispambot'                         );
  • tests/phpunit/tests/comment-submission.php

     
    714714                return $commentdata;
    715715        }
    716716
     717        /**
     718         * @ticket 36901
     719         */
     720        public function test_submitting_duplicate_comments() {
     721                $post = self::factory()->post->create_and_get( array(
     722                        'post_status' => 'publish',
     723                ) );
     724                $data = array(
     725                        'comment_post_ID' => $post->ID,
     726                        'comment'         => 'Did I say that?',
     727                        'author'          => 'Repeat myself',
     728                        'email'           => 'mail@example.com',
     729                );
     730                $first_comment = wp_handle_comment_submission( $data );
     731                $second_comment = wp_handle_comment_submission( $data );
     732                $this->assertWPError( $second_comment );
     733                $this->assertSame( 'comment_duplicate', $second_comment->get_error_code() );
     734        }
     735
     736        /**
     737         * @ticket 36901
     738         */
     739        public function test_comments_flood() {
     740                $post = self::factory()->post->create_and_get( array(
     741                        'post_status' => 'publish',
     742                ) );
     743                $data = array(
     744                        'comment_post_ID' => $post->ID,
     745                        'comment'         => 'Did I say that?',
     746                        'author'          => 'Repeat myself',
     747                        'email'           => 'mail@example.com',
     748                );
     749                $first_comment = wp_handle_comment_submission( $data );
     750
     751                $data['comment'] = 'Wow! I am quick!';
     752                $second_comment = wp_handle_comment_submission( $data );
     753
     754                $this->assertWPError( $second_comment );
     755                $this->assertSame( 'comment_flood', $second_comment->get_error_code() );
     756        }
     757
     758        /**
     759         * @ticket 36901
     760         */
     761        public function test_comments_flood_user_is_admin() {
     762                $user = self::factory()->user->create_and_get( array(
     763                        'role' => 'administrator',
     764                ) );
     765                wp_set_current_user( $user->ID );
     766
     767                $post = self::factory()->post->create_and_get( array(
     768                        'post_status' => 'publish',
     769                ) );
     770                $data = array(
     771                        'comment_post_ID' => $post->ID,
     772                        'comment'         => 'Did I say that?',
     773                        'author'          => 'Repeat myself',
     774                        'email'           => 'mail@example.com',
     775                );
     776                $first_comment = wp_handle_comment_submission( $data );
     777
     778                $data['comment'] = 'Wow! I am quick!';
     779                $second_comment = wp_handle_comment_submission( $data );
     780
     781                $this->assertNotWPError( $second_comment );
     782                $this->assertEquals( $post->ID, $second_comment->comment_post_ID );
     783        }
    717784}