Index: src/wp-comments-post.php
===================================================================
--- src/wp-comments-post.php	(revision 33203)
+++ src/wp-comments-post.php	(working copy)
@@ -126,10 +126,6 @@
 	}
 }
 
-if ( '' == $comment_content ) {
-	wp_die( __( '<strong>ERROR</strong>: please type a comment.' ), 200 );
-}
-
 $comment_parent = isset($_POST['comment_parent']) ? absint($_POST['comment_parent']) : 0;
 
 $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID');
Index: src/wp-includes/comment.php
===================================================================
--- src/wp-includes/comment.php	(revision 33203)
+++ src/wp-includes/comment.php	(working copy)
@@ -1350,39 +1350,6 @@
 function wp_allow_comment( $commentdata ) {
 	global $wpdb;
 
-	// Simple duplicate check
-	// expected_slashed ($comment_post_ID, $comment_author, $comment_author_email, $comment_content)
-	$dupe = $wpdb->prepare(
-		"SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_parent = %s AND comment_approved != 'trash' AND ( comment_author = %s ",
-		wp_unslash( $commentdata['comment_post_ID'] ),
-		wp_unslash( $commentdata['comment_parent'] ),
-		wp_unslash( $commentdata['comment_author'] )
-	);
-	if ( $commentdata['comment_author_email'] ) {
-		$dupe .= $wpdb->prepare(
-			"OR comment_author_email = %s ",
-			wp_unslash( $commentdata['comment_author_email'] )
-		);
-	}
-	$dupe .= $wpdb->prepare(
-		") AND comment_content = %s LIMIT 1",
-		wp_unslash( $commentdata['comment_content'] )
-	);
-	if ( $wpdb->get_var( $dupe ) ) {
-		/**
-		 * Fires immediately after a duplicate comment is detected.
-		 *
-		 * @since 3.0.0
-		 *
-		 * @param array $commentdata Comment data.
-		 */
-		do_action( 'comment_duplicate_trigger', $commentdata );
-		if ( defined( 'DOING_AJAX' ) ) {
-			die( __('Duplicate comment detected; it looks as though you&#8217;ve already said that!') );
-		}
-		wp_die( __( 'Duplicate comment detected; it looks as though you&#8217;ve already said that!' ), 409 );
-	}
-
 	/**
 	 * Fires immediately before a comment is marked approved.
 	 *
@@ -1398,7 +1365,8 @@
 		'check_comment_flood',
 		$commentdata['comment_author_IP'],
 		$commentdata['comment_author_email'],
-		$commentdata['comment_date_gmt']
+		$commentdata['comment_date_gmt'],
+		$commentdata
 	);
 
 	if ( ! empty( $commentdata['user_id'] ) ) {
@@ -1453,6 +1421,56 @@
 }
 
 /**
+ * Check whether the comment has been posted already
+ *
+ *
+ * @since 4.3.0
+ * @uses $wpdb
+ * @uses do_action() Calls 'comment_duplicate_trigger' action with the comment data
+ *
+ * @param string $ip Comment IP.
+ * @param string $email Comment author email address.
+ * @param string $date MySQL time string.
+ * @param array  $commentdata The pre-processed comment data
+ */
+function check_comment_flood_duplicate( $ip, $email, $date, $commentdata ) {
+	global $wpdb;
+
+	// Simple duplicate check
+	// expected_slashed ($comment_post_ID, $comment_author, $comment_author_email, $comment_content)
+	$dupe = $wpdb->prepare(
+		"SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_parent = %s AND comment_approved != 'trash' AND ( comment_author = %s ",
+		wp_unslash( $commentdata['comment_post_ID'] ),
+		wp_unslash( $commentdata['comment_parent'] ),
+		wp_unslash( $commentdata['comment_author'] )
+	);
+	if ( $commentdata['comment_author_email'] ) {
+		$dupe .= $wpdb->prepare(
+			"OR comment_author_email = %s ",
+			wp_unslash( $commentdata['comment_author_email'] )
+		);
+	}
+	$dupe .= $wpdb->prepare(
+		") AND comment_content = %s LIMIT 1",
+		wp_unslash( $commentdata['comment_content'] )
+	);
+	if ( $wpdb->get_var( $dupe ) ) {
+		/**
+		 * Fires immediately after a duplicate comment is detected.
+		 *
+		 * @since 3.0.0
+		 *
+		 * @param array $commentdata Comment data.
+		 */
+		do_action( 'comment_duplicate_trigger', $commentdata );
+		if ( defined( 'DOING_AJAX' ) ) {
+			die( __('Duplicate comment detected; it looks as though you&#8217;ve already said that!') );
+		}
+		wp_die( __( 'Duplicate comment detected; it looks as though you&#8217;ve already said that!' ), 409 );
+	}
+}
+
+/**
  * Check whether comment flooding is occurring.
  *
  * Won't run, if current user can manage options, so to not block
@@ -1503,6 +1521,25 @@
 	}
 }
 
+/** 
+ * Blocks empty comments by wp_die()'ing on empty comments 
+ * 
+ * This function is hooked as such: 
+ * <code>add_filter( 'preprocess_comment', 'disallow_empty_comments', 5 );</code> 
+ * 
+ * @since 4.3.0 
+ * 
+ * @param array $commentdata the comment data 
+ * @return array the comment data 
+ */ 
+function disallow_empty_comments( $commentdata ) { 
+	if ( '' == $commentdata[ 'comment_content' ] ) {
+		wp_die( __( '<strong>ERROR</strong>: please type a comment.' ), 200 );
+	}
+
+	return $commentdata; 
+} 
+
 /**
  * Separates an array of comments into an array keyed by comment_type.
  *
@@ -2193,6 +2230,9 @@
 	$user_id  = ! isset( $data['user_id'] ) ? 0 : $data['user_id'];
 
 	$compacted = compact( 'comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_author_IP', 'comment_date', 'comment_date_gmt', 'comment_content', 'comment_karma', 'comment_approved', 'comment_agent', 'comment_type', 'comment_parent', 'user_id' );
+
+	$compacted = apply_filters( 'wp_insert_comment_data', $compacted );
+
 	if ( ! $wpdb->insert( $wpdb->comments, $compacted ) ) {
 		return false;
 	}
@@ -2375,6 +2415,8 @@
 
 	$commentdata['comment_approved'] = wp_allow_comment($commentdata);
 
+	$commentdata = apply_filters( 'process_comment', $commentdata );
+
 	$comment_ID = wp_insert_comment($commentdata);
 	if ( ! $comment_ID ) {
 		$fields = array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content' );
Index: src/wp-includes/default-filters.php
===================================================================
--- src/wp-includes/default-filters.php	(revision 33203)
+++ src/wp-includes/default-filters.php	(working copy)
@@ -185,6 +185,7 @@
 add_filter( 'teeny_mce_before_init',    '_mce_set_direction'                  );
 add_filter( 'pre_kses',                 'wp_pre_kses_less_than'               );
 add_filter( 'sanitize_title',           'sanitize_title_with_dashes',   10, 3 );
+add_action( 'check_comment_flood',      'check_comment_flood_duplicate', 10, 4);
 add_action( 'check_comment_flood',      'check_comment_flood_db',       10, 3 );
 add_filter( 'comment_flood_filter',     'wp_throttle_comment_flood',    10, 3 );
 add_filter( 'pre_comment_content',      'wp_rel_nofollow',              15    );
@@ -197,6 +198,7 @@
 add_filter( 'editable_slug',            'urldecode'                           );
 add_filter( 'editable_slug',            'esc_textarea'                        );
 add_filter( 'nav_menu_meta_box_object', '_wp_nav_menu_meta_box_object'        );
+add_filter( 'preprocess_comment',       'disallow_empty_comments',          5 );
 add_filter( 'pingback_ping_source_uri', 'pingback_ping_source_uri'            );
 add_filter( 'xmlrpc_pingback_error',    'xmlrpc_pingback_error'               );
 add_filter( 'title_save_pre',           'trim'                                );
Index: tests/phpunit/tests/comment/duplicateContent.php
===================================================================
--- tests/phpunit/tests/comment/duplicateContent.php	(revision 0)
+++ tests/phpunit/tests/comment/duplicateContent.php	(working copy)
@@ -0,0 +1,40 @@
+<?php
+/**
+ * @group comment
+ */
+class Tests_Comment_DuplicateContent extends WP_UnitTestCase {
+
+	function test_comment_allow_duplicate_content_after_filter_removed() {
+		$user = $this->factory->user->create();
+		$post_id = $this->factory->post->create();
+
+		$content = 'test_content';
+
+		$data = array(
+			'comment_post_ID'      => $post_id,
+			'comment_author'       => $user,
+			'comment_author_IP'    => '192.168.1.1',
+			'comment_author_url'   => '',
+			'comment_author_email' => '',
+			'comment_type'         => '',
+			'comment_date_gmt' => '2015-01-01 10:00:00',
+			'comment_content'      => $content,
+		);
+
+		$id_first = wp_new_comment( $data );
+		$comment_first = get_comment( $id_first );
+
+		remove_action( 'check_comment_flood', 'check_comment_flood_duplicate', 10 );
+
+		$data[ 'comment_date_gmt' ] = '2015-02-02 10:00:00';
+
+		$id_next = wp_new_comment( $data );
+		$comment_next = get_comment( $id_next );
+
+		add_action( 'check_comment_flood', 'check_comment_flood_duplicate', 10, 4 );
+
+		$this->assertEquals( $data[ 'comment_author' ], $comment_first->comment_author );
+		$this->assertEquals( $data[ 'comment_author' ], $comment_next->comment_author );
+	}
+
+}
\ No newline at end of file
Index: tests/phpunit/tests/comment/emptyContent.php
===================================================================
--- tests/phpunit/tests/comment/emptyContent.php	(revision 0)
+++ tests/phpunit/tests/comment/emptyContent.php	(working copy)
@@ -0,0 +1,34 @@
+<?php
+/**
+ * @group comment
+ */
+class Tests_Comment_EmptyContent extends WP_UnitTestCase {
+
+	function test_comment_allow_empty_content_after_filter_removed() {
+		$post_id = $this->factory->post->create();
+
+		$data = array(
+			'comment_post_ID'      => $post_id,
+			'comment_author'       => 'test_author',
+			'comment_author_IP'    => '192.168.1.1',
+			'comment_author_url'   => '',
+			'comment_author_email' => '',
+			'comment_type'         => '',
+			'comment_content'      => '',
+		);
+
+		remove_filter( 'preprocess_comment', 'disallow_empty_comments', 5 );
+
+		$id = wp_new_comment( $data );
+		
+		add_filter( 'preprocess_comment', 'disallow_empty_comments', 5 );
+
+		$comment = get_comment( $id );
+
+		$this->assertEquals( $data[ 'comment_content' ], $comment->comment_content );
+		$this->assertEquals( $data[ 'comment_post_ID' ], $comment->comment_post_ID );
+		$this->assertEquals( $data[ 'comment_author' ], $comment->comment_author );
+		$this->assertEquals( $data[ 'comment_author_IP' ], $comment->comment_author_IP );
+	}
+
+}
