Index: wp-includes/functions.php
===================================================================
--- wp-includes/functions.php	(revision 21284)
+++ wp-includes/functions.php	(working copy)
@@ -1576,26 +1576,26 @@
  * @param null $deprecated Never used. Set to null.
  * @param mixed $bits File content
  * @param string $time Optional. Time formatted in 'yyyy/mm'.
+ * @param array $additional_args Optional. Additional arguments. 
  * @return array
  */
-function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
+function wp_upload_bits( $name, $deprecated, $bits, $time = null, $additional_args = false ) {
 	if ( !empty( $deprecated ) )
 		_deprecated_argument( __FUNCTION__, '2.0' );
 
+	$default_additional_args = array( 'validate_extension' => true, 'mimes' => false ); 
+	$additional_args = wp_parse_args( $additional_args, $default_additional_args );
+
 	if ( empty( $name ) )
 		return array( 'error' => __( 'Empty filename' ) );
 
-	$wp_filetype = wp_check_filetype( $name );
-	if ( !$wp_filetype['ext'] )
-		return array( 'error' => __( 'Invalid file type' ) );
-
 	$upload = wp_upload_dir( $time );
 
 	if ( $upload['error'] !== false )
 		return $upload;
 
 	$upload_bits_error = apply_filters( 'wp_upload_bits', array( 'name' => $name, 'bits' => $bits, 'time' => $time ) );
-	if ( !is_array( $upload_bits_error ) ) {
+	if ( ! is_array( $upload_bits_error ) || isset( $upload_bits_error['error'] ) ) {
 		$upload[ 'error' ] = $upload_bits_error;
 		return $upload;
 	}
@@ -1617,16 +1617,42 @@
 	clearstatcache();
 
 	// Set correct file permissions
-	$stat = @ stat( dirname( $new_file ) );
+	$stat  = stat( dirname( $new_file ) );
 	$perms = $stat['mode'] & 0007777;
 	$perms = $perms & 0000666;
 	@ chmod( $new_file, $perms );
 	clearstatcache();
 
+	// Attempt to validate the extension as being correct
+	if ( $additional_args['validate_extension'] ) {
+		$wp_filetype = wp_check_filetype_and_ext( $new_file, $name, $additional_args['mimes'] );
+
+		extract( $wp_filetype );
+
+		// This will be set if the original filename was invalid
+		if ( $proper_filename ) {
+			$filename = wp_unique_filename( $upload['path'], $proper_filename );
+			$new_file_path = $upload['path'] . "/$filename";
+			rename( $new_file, $new_file_path );
+			$new_file = $new_file_path;
+		}
+
+		if ( ( !$type || !$ext ) && !current_user_can( 'unfiltered_upload' ) ) {
+			unlink( $new_file );
+			return array( 'error' => __( 'Sorry, this file type is not permitted for security reasons.' ) );
+		}
+	}
+	else {
+		$type = false;
+	}
+
 	// Compute the URL
 	$url = $upload['url'] . "/$filename";
 
-	return array( 'file' => $new_file, 'url' => $url, 'error' => false );
+	if ( is_multisite() )
+		delete_transient( 'dirsize_cache' );
+
+	return array( 'file' => $new_file, 'url' => $url, 'type' => $type, 'error' => false );
 }
 
 /**
Index: wp-includes/class-wp-xmlrpc-server.php
===================================================================
--- wp-includes/class-wp-xmlrpc-server.php	(revision 21284)
+++ wp-includes/class-wp-xmlrpc-server.php	(working copy)
@@ -4557,10 +4557,15 @@
 		}
 
 		$upload = wp_upload_bits($name, null, $bits);
+
 		if ( ! empty($upload['error']) ) {
 			$errorString = sprintf(__('Could not write file %1$s (%2$s)'), $name, $upload['error']);
 			return new IXR_Error(500, $errorString);
 		}
+
+		if( $upload['type'] )
+			$type = $upload['type'];
+
 		// Construct the attachment array
 		// attach to post_id 0
 		$post_id = 0;
Index: wp-admin/includes/ms.php
===================================================================
--- wp-admin/includes/ms.php	(revision 21284)
+++ wp-admin/includes/ms.php	(working copy)
@@ -19,7 +19,7 @@
 	if ( get_site_option( 'upload_space_check_disabled' ) )
 		return $file;
 
-	if ( $file['error'] != '0' ) // there's already an error
+	if ( isset( $file['error'] ) && $file['error'] != '0' ) // there's already an error
 		return $file;
 
 	if ( defined( 'WP_IMPORTING' ) )
@@ -28,20 +28,31 @@
 	$space_allowed = 1048576 * get_space_allowed();
 	$space_used = get_dirsize( BLOGUPLOADDIR );
 	$space_left = $space_allowed - $space_used;
-	$file_size = filesize( $file['tmp_name'] );
-	if ( $space_left < $file_size )
+
+	if( 'wp_upload_bits' == current_filter() ) {
+		if( function_exists( 'mb_strlen' ) )
+			$file_size = mb_strlen( $file['bits'], 'ascii');
+		else
+			$file_size = strlen( $file['bits'] );
+	}
+	else {
+		$file_size = filesize( $file['tmp_name'] );
+	}
+
+	if( $space_left < $file_size )
 		$file['error'] = sprintf( __( 'Not enough space to upload. %1$s KB needed.' ), number_format( ($file_size - $space_left) /1024 ) );
-	if ( $file_size > ( 1024 * get_site_option( 'fileupload_maxk', 1500 ) ) )
+	if( $file_size > ( 1024 * get_site_option( 'fileupload_maxk', 1500 ) ) )
 		$file['error'] = sprintf(__('This file is too big. Files must be less than %1$s KB in size.'), get_site_option( 'fileupload_maxk', 1500 ) );
-	if ( upload_is_user_over_quota( false ) ) {
+	if( upload_is_user_over_quota( false ) ) {
 		$file['error'] = __( 'You have used your space quota. Please delete files before uploading.' );
 	}
-	if ( $file['error'] != '0' && !isset($_POST['html-upload']) )
+	if( 'wp_handle_upload_prefilter' == current_filter() && $file['error'] != '0' && ! isset( $_POST['html-upload'] ) )
 		wp_die( $file['error'] . ' <a href="javascript:history.go(-1)">' . __( 'Back' ) . '</a>' );
 
 	return $file;
 }
 add_filter( 'wp_handle_upload_prefilter', 'check_upload_size' );
+add_filter( 'wp_upload_bits', 'check_upload_size' );
 
 /**
  * Delete a blog
