diff --git src/wp-admin/includes/image.php src/wp-admin/includes/image.php
index d8d5d5b34b..83d7f28edd 100644
--- src/wp-admin/includes/image.php
+++ src/wp-admin/includes/image.php
@@ -647,18 +647,27 @@ function wp_generate_attachment_metadata( $attachment_id, $file ) {
  * @since 2.5.0
  *
  * @param string $str
- * @return int|float
+ * @return int|float Returns originally passed string on failure.
  */
 function wp_exif_frac2dec( $str ) {
-	if ( false === strpos( $str, '/' ) ) {
+	// Fractions must contain a single `/`.
+	if ( substr_count( $str, '/' ) !== 1 ) {
 		return $str;
 	}
 
 	list( $numerator, $denominator ) = explode( '/', $str );
-	if ( ! empty( $denominator ) ) {
-		return $numerator / $denominator;
+
+	// Both the numerator and the denominator must be numbers.
+	if ( ! is_numeric( $numerator ) || ! is_numeric( $denominator ) ) {
+		return $str;
+	}
+
+	// The denominator must not be zero.
+	if ( empty( $denominator ) ) {
+		return $str;
 	}
-	return $str;
+
+	return $numerator / $denominator;
 }
 
 /**
diff --git tests/phpunit/tests/image/functions.php tests/phpunit/tests/image/functions.php
index 488731a0e8..1dad1af9a1 100644
--- tests/phpunit/tests/image/functions.php
+++ tests/phpunit/tests/image/functions.php
@@ -700,4 +700,106 @@ class Tests_Image_Functions extends WP_UnitTestCase {
 			unlink( $temp_dir . $size['file'] );
 		}
 	}
+
+	/**
+	 * Test for wp_exif_frac2dec verified that it properly handles edge cases
+	 * and always returns an int or float, or original value for failures.
+	 *
+	 * @param string $fraction The fraction to convert.
+	 * @param string $expect   The expected result.
+	 *
+	 * @ticket 54385
+	 * @dataProvider data_wp_exif_frac2dec
+	 *
+	 * @covers ::wp_exif_frac2dec
+	 */
+	public function test_wp_exif_frac2dec( $fraction, $expect ) {
+		$this->assertSame( $expect, wp_exif_frac2dec( $fraction ) );
+	}
+
+
+	/**
+	 * Data provider for testing `wp_exif_frac2dec()`.
+	 *
+	 * @return array {
+	 *     Arguments for testing `wp_exif_frac2dec()`.
+	 */
+	public function data_wp_exif_frac2dec() {
+		global $wpdb;
+
+		return array(
+			'division by zero is prevented'       => array(
+				'fraction' => '0/0',
+				'expect'   => '0/0',
+			),
+			'typical fnumber'                     => array(
+				'fraction' => '4.8',
+				'expect'   => '4.8',
+			),
+			'typical focal length'                => array(
+				'fraction' => '37 mm',
+				'expect'   => '37 mm',
+			),
+			'typical exposure time'               => array(
+				'fraction' => '1/350',
+				'expect'   => 0.002857142857142857,
+			),
+			'division by text prevented'          => array(
+				'fraction' => '0/abc',
+				'expect'   => '0/abc',
+			),
+			'non fraction returns original value' => array(
+				'fraction' => '0.0',
+				'expect'   => '0.0',
+			),
+			'non fraction returns original value' => array(
+				'fraction' => '010',
+				'expect'   => '010',
+			),
+			'non fraction returns original value' => array(
+				'fraction' => 10.123,
+				'expect'   => 10.123,
+			),
+			'valid fraction'                      => array(
+				'fraction' => '50/100',
+				'expect'   => 0.5,
+			),
+			'valid fraction 2'                    => array(
+				'fraction' => '25/100',
+				'expect'   => .25,
+			),
+			'valid fraction 3'                    => array(
+				'fraction' => '4/2',
+				'expect'   => 2,
+			),
+			'non fraction returns original value' => array(
+				'fraction' => '0',
+				'expect'   => '0',
+			),
+			'division by zero is prevented'       => array(
+				'fraction' => '100/0',
+				'expect'   => '100/0',
+			),
+			'text is prevented'                   => array(
+				'fraction' => 'path/to/file',
+				'expect'   => 'path/to/file',
+			),
+			'text is prevented'                   => array(
+				'fraction' => '123notafraction',
+				'expect'   => '123notafraction',
+			),
+			'invalid input prevented'             => array(
+				'fraction' => '/',
+				'expect'   => '/',
+			),
+			'invalid input prevented 2'           => array(
+				'fraction' => '1/2/3',
+				'expect'   => '1/2/3',
+			),
+			'invalid input prevented 3'           => array(
+				'fraction' => '///',
+				'expect'   => '///',
+			),
+		);
+	}
 }
