Index: wp-comments-post.php
===================================================================
--- wp-comments-post.php	(revision 17639)
+++ wp-comments-post.php	(working copy)
@@ -80,9 +80,6 @@
 		wp_die( __('Error: please enter a valid email address.') );
 }
 
-if ( '' == $comment_content )
-	wp_die( __('Error: please type a comment.') );
-
 $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: wp-includes/comment.php
===================================================================
--- wp-includes/comment.php	(revision 17639)
+++ wp-includes/comment.php	(working copy)
@@ -604,22 +604,8 @@
 	global $wpdb;
 	extract($commentdata, EXTR_SKIP);
 
-	// Simple duplicate check
-	// expected_slashed ($comment_post_ID, $comment_author, $comment_author_email, $comment_content)
-	$dupe = "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = '$comment_post_ID' AND comment_approved != 'trash' AND ( comment_author = '$comment_author' ";
-	if ( $comment_author_email )
-		$dupe .= "OR comment_author_email = '$comment_author_email' ";
-	$dupe .= ") AND comment_content = '$comment_content' LIMIT 1";
-	if ( $wpdb->get_var($dupe) ) {
-		do_action( 'comment_duplicate_trigger', $commentdata );
-		if ( defined('DOING_AJAX') )
-			die( __('Duplicate comment detected; it looks as though you&#8217;ve already said that!') );
+	do_action( 'check_comment_flood', $comment_author_IP, $comment_author_email, $comment_date_gmt, $commentdata);
 
-		wp_die( __('Duplicate comment detected; it looks as though you&#8217;ve already said that!') );
-	}
-
-	do_action( 'check_comment_flood', $comment_author_IP, $comment_author_email, $comment_date_gmt );
-
 	if ( isset($user_id) && $user_id) {
 		$userdata = get_userdata($user_id);
 		$user = new WP_User($user_id);
@@ -681,6 +667,38 @@
 }
 
 /**
+ * Check whether the comment has been posted already
+ *
+ *
+ * @since 3.2.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;
+	extract($commentdata, EXTR_SKIP);
+
+	// expected_slashed ($comment_post_ID, $comment_author, $comment_author_email, $comment_content)
+	$dupe = "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = '$comment_post_ID' AND comment_approved != 'trash' AND ( comment_author = '$comment_author' ";
+	if ( $comment_author_email )
+		$dupe .= "OR comment_author_email = '$comment_author_email' ";
+	$dupe .= ") AND comment_content = '$comment_content' LIMIT 1";
+
+	if ( $wpdb->get_var($dupe) ) {
+		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!') );
+	}
+}
+
+/**
  * Separates an array of comments into an array keyed by comment_type.
  *
  * @since 2.7.0
@@ -1223,6 +1241,9 @@
 		$comment_type = '';
 
 	$data = 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');
+
+	$data = apply_filters('wp_insert_comment_data', $data); // expect UNslashed
+	
 	$wpdb->insert($wpdb->comments, $data);
 
 	$id = (int) $wpdb->insert_id;
@@ -1289,6 +1310,24 @@
 }
 
 /**
+ * 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 3.2.0
+ *
+ * @param array $commentdata the comment data
+ * @return array the comment data
+ */
+function disallow_empty_comments($commentdata) {
+	if ( '' == $commentdata['comment_content'] )
+		wp_die( __('Error: please type a comment.') );
+
+	return $commentdata;
+}
+
+/**
  * Adds a new comment to the database.
  *
  * Filters new comment to ensure that the fields are sanitized and valid before
@@ -1333,6 +1372,8 @@
 
 	$commentdata['comment_approved'] = wp_allow_comment($commentdata);
 
+	$commentdata = apply_filters('process_comment', $commentdata);
+
 	$comment_ID = wp_insert_comment($commentdata);
 
 	do_action('comment_post', $comment_ID, $commentdata['comment_approved']);
Index: wp-includes/default-filters.php
===================================================================
--- wp-includes/default-filters.php	(revision 17639)
+++ wp-includes/default-filters.php	(working copy)
@@ -179,6 +179,7 @@
 add_filter( 'tiny_mce_before_init', '_mce_set_direction'                  );
 add_filter( 'pre_kses',             'wp_pre_kses_less_than'               );
 add_filter( 'sanitize_title',       'sanitize_title_with_dashes'          );
+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    );
@@ -190,9 +191,10 @@
 add_filter( 'pings_open',           '_close_comments_for_old_post', 10, 2 );
 add_filter( 'editable_slug',        'urldecode'                           );
 add_filter( 'nav_menu_meta_box_object', '_wp_nav_menu_meta_box_object'    );
+add_filter( 'preprocess_comment',   'disallow_empty_comments',      5     );
 
 // Atom SSL support
-add_filter( 'atom_service_url','atom_service_url_filter' );
+add_filter( 'atom_service_url', 'atom_service_url_filter' );
 
 // Actions
 add_action( 'wp_head',             'wp_enqueue_scripts',            1     );
