Index: wp-admin/includes/file.php
===================================================================
--- wp-admin/includes/file.php	(revision 20104)
+++ wp-admin/includes/file.php	(working copy)
@@ -1044,10 +1044,7 @@
 </table>
 
 <?php
-foreach ( (array) $extra_fields as $field ) {
-	if ( isset( $_POST[ $field ] ) )
-		echo '<input type="hidden" name="' . esc_attr( $field ) . '" value="' . esc_attr( stripslashes( $_POST[ $field ] ) ) . '" />';
-}
+output_filesystem_extra_fields( $extra_fields );
 submit_button( __( 'Proceed' ), 'button', 'upgrade' );
 ?>
 </div>
@@ -1055,3 +1052,32 @@
 <?php
 	return false;
 }
+
+/**
+ * Callback function for outputting any extra fields passed through request_filesystem_credentials().
+ *
+ * This function will parse strings, arrays or multi-dimensional arrays passed within the $extra_fields 
+ * parameter so that no data is lost.
+ *
+ * @since 3.4.0
+ *
+ * @uses build_query
+ * @param array $fields Extra fields passed through request_filesystem_credentials().
+ */
+function output_filesystem_extra_fields( $fields ) {
+
+	// Sanitize and store all passed data into one array
+	$qs = array();
+	foreach ( (array) $fields as $field ) {
+		if ( isset( $_POST[ $field ] ) )
+			$qs[esc_attr( $field )] = is_array( $_POST[$field] ) ? $_POST[esc_attr( stripslashes_deep( $field ) )] : $_POST[esc_attr( stripslashes( $field ) )];
+	}
+	
+	// Build a query string out of the data and then parse the string into input fields
+	$query_string = build_query( $qs );
+	foreach ( explode( '&', $query_string ) as $kv_pair ) {
+		list( $name, $value ) = explode( '=', $kv_pair, 2 );
+		echo '<input type="hidden" name="' . urldecode( $name ) . '" value="' . urldecode( $value ) . '">' . "\r\n";
+	}
+
+}
\ No newline at end of file
