Index: wp-includes/post.php
===================================================================
--- wp-includes/post.php	(revision 25617)
+++ wp-includes/post.php	(working copy)
@@ -2680,9 +2680,10 @@
  *
  * @param array $postarr Elements that make up post to insert.
  * @param bool $wp_error Optional. Allow return of WP_Error on failure.
+ * @param bool $sanitize Optional. Run "current user" sanitization routines on $postarr.
  * @return int|WP_Error The value 0 or WP_Error on failure. The post ID on success.
  */
-function wp_insert_post($postarr, $wp_error = false) {
+function wp_insert_post( $postarr, $wp_error = false, $sanitize = true ) {
 	global $wpdb, $user_ID;
 
 	$defaults = array('post_status' => 'draft', 'post_type' => 'post', 'post_author' => $user_ID,
@@ -2695,7 +2696,11 @@
 
 	unset( $postarr[ 'filter' ] );
 
-	$postarr = sanitize_post($postarr, 'db');
+	if ( ! $sanitize )
+		kses_remove_filters();
+	$postarr = sanitize_post( $postarr, 'db' );
+	if ( ! $sanitize )
+		kses_init();
 
 	// export array as variables
 	extract($postarr, EXTR_SKIP);
@@ -2753,7 +2758,7 @@
 		$post_author = $user_ID;
 
 	// Don't allow contributors to set the post slug for pending review posts
-	if ( 'pending' == $post_status && !current_user_can( 'publish_posts' ) )
+	if ( 'pending' == $post_status && $sanitize && !current_user_can( 'publish_posts' ) )
 		$post_name = '';
 
 	// Create a valid post name. Drafts and pending posts are allowed to have an empty
@@ -2848,7 +2853,9 @@
 
 	$post_name = wp_unique_post_slug($post_name, $post_ID, $post_status, $post_type, $post_parent);
 
-	// expected_slashed (everything!)
+	// expected_slashed, everything, unless $sanitize = false
+	if ( ! $sanitize )
+		$sanitize = wp_slash( $sanitize ); // That way the wp_insert_post_data filter receives consistent data.
 	$data = compact( array( 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_content_filtered', 'post_title', 'post_excerpt', 'post_status', 'post_type', 'comment_status', 'ping_status', 'post_password', 'post_name', 'to_ping', 'pinged', 'post_modified', 'post_modified_gmt', 'post_parent', 'menu_order', 'guid' ) );
 	$data = apply_filters('wp_insert_post_data', $data, $postarr);
 	$data = wp_unslash( $data );
@@ -2901,7 +2908,7 @@
 			$taxonomy_obj = get_taxonomy($taxonomy);
 			if ( is_array($tags) ) // array = hierarchical, string = non-hierarchical.
 				$tags = array_filter($tags);
-			if ( current_user_can($taxonomy_obj->cap->assign_terms) )
+			if ( ! $sanitize || current_user_can( $taxonomy_obj->cap->assign_terms ) )
 				wp_set_post_terms( $post_ID, $tags, $taxonomy );
 		}
 	}
