WordPress.org

Make WordPress Core

Ticket #36901: 36901.2.patch

File 36901.2.patch, 11.6 KB (added by websupporter, 3 years ago)
  • src/wp-includes/comment.php

     
    3838 */
    3939function check_comment($author, $email, $url, $comment, $user_ip, $user_agent, $comment_type) {
    4040        global $wpdb;
    41 
    4241        // If manual moderation is enabled, skip all checks and return false.
    4342        if ( 1 == get_option('comment_moderation') )
    4443                return false;
     
    582581 * Validates whether this comment is allowed to be made.
    583582 *
    584583 * @since 2.0.0
     584 * @since trunk Define $return_error if function returns an error or uses wp_die()
    585585 *
    586586 * @global wpdb $wpdb WordPress database abstraction object.
    587587 *
    588  * @param array $commentdata Contains information on the comment
     588 * @param array   $commentdata Contains information on the comment
     589 * @param boolean $return_error Wheter to return an error or to use wp_die(). Default: false
    589590 * @return int|string Signifies the approval status (0|1|'spam')
    590591 */
    591 function wp_allow_comment( $commentdata ) {
     592function wp_allow_comment( $commentdata, $return_error = false ) {
    592593        global $wpdb;
    593594
    594595        // Simple duplicate check
     
    633634                 * @param array $commentdata Comment data.
    634635                 */
    635636                do_action( 'comment_duplicate_trigger', $commentdata );
    636                 if ( defined( 'DOING_AJAX' ) ) {
    637                         die( __('Duplicate comment detected; it looks as though you’ve already said that!') );
     637                if( $return_error ) {
     638                        return new WP_Error( 'duplicate_comment', __( 'Duplicate comment detected; it looks as though you’ve already said that!' ), 409 );
     639                } else {
     640                        if ( defined( 'DOING_AJAX' ) ) {
     641                                die( __('Duplicate comment detected; it looks as though you’ve already said that!') );
     642                        }
     643                        wp_die( __( 'Duplicate comment detected; it looks as though you’ve already said that!' ), 409 );
    638644                }
    639                 wp_die( __( 'Duplicate comment detected; it looks as though you’ve already said that!' ), 409 );
    640645        }
    641646
    642647        /**
     
    646651         *
    647652         * @since 2.3.0
    648653         *
    649          * @param string $comment_author_IP    Comment author's IP address.
    650          * @param string $comment_author_email Comment author's email.
    651          * @param string $comment_date_gmt     GMT date the comment was posted.
     654         * @param string  $comment_author_IP    Comment author's IP address.
     655         * @param string  $comment_author_email Comment author's email.
     656         * @param string  $comment_date_gmt     GMT date the comment was posted.
     657         * @param boolean $return_error         If the expected behavior is to die if a comment is detected to be part of a flood
    652658         */
    653659        do_action(
    654660                'check_comment_flood',
    655661                $commentdata['comment_author_IP'],
    656662                $commentdata['comment_author_email'],
    657                 $commentdata['comment_date_gmt']
     663                $commentdata['comment_date_gmt'],
     664                $return_error
    658665        );
    659666
     667
     668        /**
     669         * Filters if a comment is part of a comment flood.
     670         *
     671         * @since trunk
     672         *
     673         * @param boolean $is_flood             If a comment is flagged as being part of a flood.
     674         * @param string  $comment_author_IP    Comment author's IP address.
     675         * @param string  $comment_author_email Comment author's email.
     676         * @param string  $comment_date_gmt     GMT date the comment was posted.
     677         * @param boolean $return_error         Indicating if wp_die() is supposed to be executed in case of a flood
     678         */
     679        $is_flood = apply_filters( 'is_comment_flood', false, $commentdata['comment_author_IP'], $commentdata['comment_author_email'], $commentdata['comment_date_gmt'], $return_error );
     680        if ( $is_flood && $return_error ) {
     681                return new WP_Error( 'comment_flood', __( 'You are posting comments too quickly. Slow down.' ), 429 );
     682        }
     683
    660684        if ( ! empty( $commentdata['user_id'] ) ) {
    661685                $user = get_userdata( $commentdata['user_id'] );
    662686                $post_author = $wpdb->get_var( $wpdb->prepare(
     
    708732        return $approved;
    709733}
    710734
     735
    711736/**
     737 * Filters whether comment flooding is occurring.
     738 *
     739 * @since trunk
     740 *
     741 * @param boolean  $is_flood If the current comment is part of a flood
     742 * @param string   $ip Comment IP.
     743 * @param string   $email Comment author email address.
     744 * @param string   $date MySQL time string.
     745 * @param boolean  $return_error Wether to return a WP_Error on flood or use wp_die()
     746 *
     747 * @return boolean $is_flood If the current comment is part of a flood
     748 */
     749function check_comment_flood_db_filter( $is_flood, $ip, $email, $date, $return_error = false ) {
     750        if ( $is_flood ) {
     751                return $is_flood;
     752        }
     753        $is_flood = check_comment_flood_db( $ip, $email, $date, $return_error );
     754        if ( true !== $is_flood ) {
     755                return false;
     756        }
     757        return true;
     758}
     759
     760/**
    712761 * Check whether comment flooding is occurring.
    713762 *
    714763 * Won't run, if current user can manage options, so to not block
     
    715764 * administrators.
    716765 *
    717766 * @since 2.3.0
     767 * @since trunk $return_error indicating if a WP_Error object should be returned instead of using wp_die()
    718768 *
    719769 * @global wpdb $wpdb WordPress database abstraction object.
    720770 *
    721  * @param string $ip Comment IP.
    722  * @param string $email Comment author email address.
    723  * @param string $date MySQL time string.
     771 * @param string  $ip Comment IP.
     772 * @param string  $email Comment author email address.
     773 * @param string  $date MySQL time string.
     774 * @param boolean $return_error Wether to return a WP_Error on flood or use wp_die()
     775 *
     776 * @return mixed  if $return_error is true it returns a boolean indicating the flood. Otherwise nothing will be returned.
    724777 */
    725 function check_comment_flood_db( $ip, $email, $date ) {
     778function check_comment_flood_db( $ip, $email, $date, $return_error = false ) {
     779
    726780        global $wpdb;
    727781        // don't throttle admins or moderators
    728782        if ( current_user_can( 'manage_options' ) || current_user_can( 'moderate_comments' ) ) {
     
    768822                         * @param int $time_newcomment  Timestamp of when the new comment was posted.
    769823                         */
    770824                        do_action( 'comment_flood_trigger', $time_lastcomment, $time_newcomment );
    771 
    772                         if ( defined('DOING_AJAX') )
    773                                 die( __('You are posting comments too quickly. Slow down.') );
    774 
    775                         wp_die( __( 'You are posting comments too quickly. Slow down.' ), 429 );
     825                        if( $return_error ) {
     826                                return $flood_die;
     827                        } else {
     828                                if ( defined('DOING_AJAX') )
     829                                        die( __('You are posting comments too quickly. Slow down.') );
     830                                wp_die( __( 'You are posting comments too quickly. Slow down.' ), 429 );
     831                        }
    776832                }
    777833        }
     834
     835        if( $return_error ) {
     836                return false;
     837        }
    778838}
    779839
    780840/**
     
    17111771 *
    17121772 * @since 1.5.0
    17131773 * @since 4.3.0 'comment_agent' and 'comment_author_IP' can be set via `$commentdata`.
     1774 * @since trunk $return_error boolean to be able to return errors instead of using wp_die()
    17141775 *
    17151776 * @see wp_insert_comment()
    17161777 * @global wpdb $wpdb WordPress database abstraction object.
     
    17341795 *     @type string $comment_author_IP    Comment author IP address in IPv4 format. Default is the value of
    17351796 *                                        'REMOTE_ADDR' in the `$_SERVER` superglobal sent in the original request.
    17361797 * }
     1798 * @param boolean   $return_error         Return a WP_Error instead of using wp_die(). Default: false
    17371799 * @return int|false The ID of the comment on success, false on failure.
    17381800 */
    1739 function wp_new_comment( $commentdata ) {
     1801function wp_new_comment( $commentdata, $return_error = false ) {
    17401802        global $wpdb;
    17411803
    17421804        if ( isset( $commentdata['user_ID'] ) ) {
     
    17851847
    17861848        $commentdata = wp_filter_comment($commentdata);
    17871849
    1788         $commentdata['comment_approved'] = wp_allow_comment($commentdata);
     1850        $commentdata['comment_approved'] = wp_allow_comment( $commentdata, $return_error );
     1851        if ( is_wp_error( $commentdata['comment_approved'] ) ) {
     1852                return $commentdata['comment_approved'];
     1853        }
    17891854
    17901855        $comment_ID = wp_insert_comment($commentdata);
    17911856        if ( ! $comment_ID ) {
     
    17991864
    18001865                $commentdata = wp_filter_comment( $commentdata );
    18011866
    1802                 $commentdata['comment_approved'] = wp_allow_comment( $commentdata );
     1867                $commentdata['comment_approved'] = wp_allow_comment( $commentdata, $return_error );
     1868                if ( is_wp_error( $commentdata['comment_approved'] ) ) {
     1869                        return $commentdata['comment_approved'];
     1870                }
    18031871
    18041872                $comment_ID = wp_insert_comment( $commentdata );
    18051873                if ( ! $comment_ID ) {
     
    29162984                'user_ID'
    29172985        );
    29182986
    2919         $comment_id = wp_new_comment( wp_slash( $commentdata ) );
     2987        $comment_id = wp_new_comment( wp_slash( $commentdata ), true );
     2988
     2989        if ( is_wp_error( $comment_id ) ) {
     2990                return $comment_id;
     2991        }
     2992
    29202993        if ( ! $comment_id ) {
    29212994                return new WP_Error( 'comment_save_error', __( '<strong>ERROR</strong>: The comment could not be saved. Please try again later.' ), 500 );
    29222995        }
  • src/wp-includes/default-filters.php

     
    190190add_filter( 'teeny_mce_before_init',    '_mce_set_direction'                  );
    191191add_filter( 'pre_kses',                 'wp_pre_kses_less_than'               );
    192192add_filter( 'sanitize_title',           'sanitize_title_with_dashes',   10, 3 );
    193 add_action( 'check_comment_flood',      'check_comment_flood_db',       10, 3 );
     193add_filter( 'is_comment_flood',         'check_comment_flood_db_filter',10, 5 );
    194194add_filter( 'comment_flood_filter',     'wp_throttle_comment_flood',    10, 3 );
    195195add_filter( 'pre_comment_content',      'wp_rel_nofollow',              15    );
    196196add_filter( 'comment_email',            'antispambot'                         );
  • tests/phpunit/tests/comment-submission.php

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