Index: src/wp-admin/includes/image-edit.php
===================================================================
--- src/wp-admin/includes/image-edit.php	(revision 40076)
+++ src/wp-admin/includes/image-edit.php	(working copy)
@@ -776,17 +776,7 @@
 			$new_path = $path;
 		}
 	} else {
-		while ( true ) {
-			$filename = preg_replace( '/-e([0-9]+)$/', '', $filename );
-			$filename .= "-e{$suffix}";
-			$new_filename = "{$filename}.{$ext}";
-			$new_path = "{$dirname}/$new_filename";
-			if ( file_exists($new_path) ) {
-				$suffix++;
-			} else {
-				break;
-			}
-		}
+		$new_path = wp_generate_random_file_name( $path, $dirname, $ext, 'e', $suffix );
 	}
 
 	// Save the full-size file, also needed to create sub-sizes.
Index: src/wp-admin/includes/image.php
===================================================================
--- src/wp-admin/includes/image.php	(revision 40076)
+++ src/wp-admin/includes/image.php	(working copy)
@@ -251,7 +251,16 @@
 			$editor = wp_get_image_editor( $file );
 
 			if ( ! is_wp_error( $editor ) ) { // No support for this type of file
-				$uploaded = $editor->save( $file, 'image/jpeg' );
+				/*
+				 * PDFs may have the same file filename as JPGs.
+				 * Use a random string for the PDF preview image to prevent the original JPG from being overwritten.
+				 */
+				$dirname = pathinfo( $file, PATHINFO_DIRNAME );
+				$suffix = time() . rand( 100, 999 );
+
+				$preview_filename = wp_generate_random_file_name( $file, $dirname, 'jpg', 'pdf', $suffix );
+				$uploaded = $editor->save( $preview_filename, 'image/jpeg' );
+
 				unset( $editor );
 
 				// Resize based on the full size image, rather than the source.
Index: src/wp-includes/functions.php
===================================================================
--- src/wp-includes/functions.php	(revision 40076)
+++ src/wp-includes/functions.php	(working copy)
@@ -2098,6 +2098,45 @@
 }
 
 /**
+ * Generates a random string for a filename.
+ *
+ * @param string $path    File path.
+ * @param string $dirname File directory name.
+ * @param string $prefix  Prefix for the file name.
+ * @param string $suffix  Suffix for the file name.
+ *
+ * @return string Generated unique file name.
+ */
+function wp_generate_random_file_name( $path, $dirname, $ext, $prefix = '', $suffix = '' ) {
+	$file_name = '';
+	$suffix = time() . rand( 100, 999 );
+	$name_parts = array();
+
+	if ( ! empty( $suffix ) ) {
+		$name_parts[] = $suffix;
+	}
+
+	if ( ! empty( $prefix ) ) {
+		$name_parts[] = $prefix;
+	}
+
+	while ( true ) {
+		$new_filename = implode( '-', $name_parts );
+		$file_name = "{$new_filename}.{$ext}";
+		$new_path = "{$dirname}/$file_name";
+
+		if ( file_exists( $new_path ) ) {
+			$suffix++;
+		} else {
+			$file_name = $new_path;
+			break;
+		}
+	}
+
+	return $file_name;
+}
+
+/**
  * Create a file in the upload folder with given content.
  *
  * If there is an error, then the key 'error' will exist with the error message.
Index: tests/phpunit/tests/image/functions.php
===================================================================
--- tests/phpunit/tests/image/functions.php	(revision 40076)
+++ tests/phpunit/tests/image/functions.php	(working copy)
@@ -400,7 +400,14 @@
 		);
 
 		$metadata = wp_generate_attachment_metadata( $attachment_id, $test_file );
-		$this->assertSame( $expected, $metadata );
+		$this->assertArrayHasKey( 'sizes', $metadata, 'attachment should have size data' );
+		$this->assertEquals( count( $expected['sizes'] ), count( $metadata['sizes'] ) );
+
+		$this->assertContains( '-pdf', $metadata['sizes']['medium']['file'] );
+		$this->assertEquals( $expected['sizes']['medium']['height'], $metadata['sizes']['medium']['height'] );
+
+		$this->assertContains( '-pdf', $metadata['sizes']['large']['file'] );
+		$this->assertEquals( $expected['sizes']['large']['width'], $metadata['sizes']['large']['width'] );
 
 		unlink( $test_file );
 	}
@@ -435,7 +442,8 @@
 
 		$metadata = wp_generate_attachment_metadata( $attachment_id, $test_file );
 		$this->assertTrue( isset( $metadata['sizes']['test-size'] ), 'The `test-size` was not added to the metadata.' );
-		$this->assertSame( $metadata['sizes']['test-size'], $expected );
+		$this->assertContains( '-pdf', $metadata['sizes']['test-size']['file'] );
+		$this->assertEquals( $expected['height'], $metadata['sizes']['test-size']['height'] );
 
 		remove_image_size( 'test-size' );
 		remove_filter( 'fallback_intermediate_image_sizes', array( $this, 'filter_fallback_intermediate_image_sizes' ), 10 );
