Index: trunk/wp-includes/functions.php
===================================================================
--- trunk/wp-includes/functions.php	(revision 11779)
+++ trunk/wp-includes/functions.php	(working copy)
@@ -2025,7 +2025,7 @@
  * @param string $time Optional. Time formatted in 'yyyy/mm'.
  * @return array See above for description.
  */
-function wp_upload_dir( $time = null ) {
+function wp_upload_dir( $time = null, $subdir = '' ) {
 	$siteurl = get_option( 'siteurl' );
 	$upload_path = get_option( 'upload_path' );
 	$upload_path = trim($upload_path);
@@ -2052,14 +2052,18 @@
 	$bdir = $dir;
 	$burl = $url;
 
-	$subdir = '';
+	if ( empty($subdir) || strpos($subdir, '..') !== false ) {
+		$subdir = '';
+	} else {
+		$subdir = '/' . trim( $subdir, '/' );
+	}
 	if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
 		// Generate the yearly and monthly dirs
 		if ( !$time )
 			$time = current_time( 'mysql' );
 		$y = substr( $time, 0, 4 );
 		$m = substr( $time, 5, 2 );
-		$subdir = "/$y/$m";
+		$subdir .= "/$y/$m";
 	}
 
 	$dir .= $subdir;
@@ -3284,13 +3288,13 @@
 			$display = $zone['t_continent'];
 		} else {
 			// It's inside a continent group
-			
+
 			// Continent optgroup
 			if ( !isset( $zonen[$key - 1] ) || $zonen[$key - 1]['continent'] !== $zone['continent'] ) {
 				$label = ( 'Etc' === $zone['continent'] ) ? __( 'Manual offsets' ) : $zone['t_continent'];
 				$structure[] = '<optgroup label="'. esc_attr( $label ) .'">';
 			}
-			
+
 			// Add the city to the value
 			$value[] = $zone['city'];
 			if ( 'Etc' === $zone['continent'] ) {
@@ -3318,7 +3322,7 @@
 			$selected = 'selected="selected" ';
 		}
 		$structure[] = '<option ' . $selected . 'value="' . esc_attr( $value ) . '">' . esc_html( $display ) . "</option>";
-		
+
 		// Close continent optgroup
 		if ( !empty( $zone['city'] ) && ( !isset($zonen[$key + 1]) || (isset( $zonen[$key + 1] ) && $zonen[$key + 1]['continent'] !== $zone['continent']) ) ) {
 			$structure[] = '</optgroup>';
@@ -3340,7 +3344,7 @@
 
 /**
  * Permanently deletes posts, pages, attachments, and comments which have been in the trash for EMPTY_TRASH_DAYS.
- * 
+ *
  * @since 2.9.0
  *
  * @return void
