From c8cc155dadc8cc9afa257106f739f4e8a4c3e669 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Mon, 21 Sep 2020 15:56:32 +0100
Subject: [PATCH] Issue #3055193 by catch, martin107, jungle, mikelutz,
 longwave, andypost, alexpott, mondrake, tim.plunkett, larowlan: [Symfony 5]
 The "Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser" class is
 deprecated since Symfony 4.3, use "Symfony\Component\Mime\MimeTypes" instead

---
 core/core.services.yml                        |  2 -
 core/lib/Drupal/Core/CoreServiceProvider.php  |  2 +
 .../Compiler/MimeTypePass.php                 | 77 +++++++++++++++++++
 .../MimeType/ExtensionMimeTypeGuesser.php     | 20 ++++-
 .../Core/File/MimeType/MimeTypeGuesser.php    | 51 ++++++++++--
 core/lib/Drupal/Core/File/file.api.php        |  7 +-
 .../MimeType/ExtensionMimeTypeGuesser.php     | 18 ++++-
 .../File/MimeType/MimeTypeGuesser.php         | 26 ++++++-
 core/modules/file/file.module                 | 10 ++-
 core/modules/file/src/Entity/File.php         | 10 ++-
 .../FieldFormatter/FileMediaFormatterBase.php | 12 ++-
 .../rest/resource/FileUploadResource.php      | 16 ++--
 .../src/Plugin/Field/FieldType/ImageItem.php  | 10 ++-
 .../TemporaryJsonapiFileFieldUploader.php     | 16 ++--
 .../responsive_image/responsive_image.module  |  8 +-
 .../system/src/Form/ThemeSettingsForm.php     | 16 ++--
 .../KernelTests/Core/File/MimeTypeTest.php    | 29 +++++--
 .../Compiler/MimeTypePassTest.php             | 63 +++++++++++++++
 .../Listeners/DeprecationListenerTrait.php    |  1 +
 19 files changed, 350 insertions(+), 44 deletions(-)
 create mode 100644 core/lib/Drupal/Core/DependencyInjection/Compiler/MimeTypePass.php
 create mode 100644 core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/MimeTypePassTest.php

diff --git a/core/core.services.yml b/core/core.services.yml
index 88e760c4892f..5d01d8766705 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -1656,8 +1656,6 @@ services:
   file.mime_type.guesser:
     class: Drupal\Core\File\MimeType\MimeTypeGuesser
     arguments: ['@stream_wrapper_manager']
-    tags:
-      - { name: service_collector, tag: mime_type_guesser, call: addGuesser }
     lazy: true
   file.mime_type.guesser.extension:
     class: Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser
diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index e07046ae0ab8..8eb6c04d695c 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -19,6 +19,7 @@
 use Drupal\Core\DependencyInjection\ServiceProviderInterface;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\DependencyInjection\Compiler\ModifyServiceDefinitionsPass;
+use Drupal\Core\DependencyInjection\Compiler\MimeTypePass;
 use Drupal\Core\DependencyInjection\Compiler\TaggedHandlersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterEventSubscribersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterAccessChecksPass;
@@ -73,6 +74,7 @@ public function register(ContainerBuilder $container) {
 
     // Collect tagged handler services as method calls on consumer services.
     $container->addCompilerPass(new TaggedHandlersPass());
+    $container->addCompilerPass(new MimeTypePass());
     $container->addCompilerPass(new RegisterStreamWrappersPass());
     $container->addCompilerPass(new GuzzleMiddlewarePass());
 
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/MimeTypePass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/MimeTypePass.php
new file mode 100644
index 000000000000..f20edc0956d6
--- /dev/null
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/MimeTypePass.php
@@ -0,0 +1,77 @@
+<?php
+
+namespace Drupal\Core\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Exception\LogicException;
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface as LegacyMimeTypeGuesserInterface;
+use Symfony\Component\Mime\MimeTypeGuesserInterface;
+
+/**
+ * Adds @mime_type_guesser tagged services to handle forwards compatibility.
+ *
+ * @internal
+ *
+ * @deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. No direct
+ * replacement is provided.
+ *
+ * @see https://www.drupal.org/node/3133341
+ */
+class MimeTypePass implements CompilerPassInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function process(ContainerBuilder $container) {
+    $consumer = $container->getDefinition('file.mime_type.guesser');
+
+    $tag = 'mime_type_guesser';
+    $interface = MimeTypeGuesserInterface::class;
+    $deprecated_interface = LegacyMimeTypeGuesserInterface::class;
+
+    // Find all tagged handlers.
+    $handlers = [];
+    foreach ($container->findTaggedServiceIds($tag) as $id => $attributes) {
+      // Validate the interface.
+      $handler = $container->getDefinition($id);
+      if (!is_subclass_of($handler->getClass(), $interface)) {
+        // Special handling for $deprecated_interface.
+        if (!is_subclass_of($handler->getClass(), $deprecated_interface)) {
+          throw new LogicException("Service '$id' does not implement $interface.");
+        }
+      }
+      $handlers[$id] = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
+      $interfaces[$id] = $handler->getClass();
+    }
+    if (empty($handlers)) {
+      throw new LogicException(sprintf("At least one service tagged with '%s' is required.", $tag));
+    }
+
+    // Sort all handlers by priority.
+    arsort($handlers, SORT_NUMERIC);
+
+    // Add a method call for each handler to the consumer service
+    // definition.
+    foreach ($handlers as $id => $priority) {
+      $arguments = [];
+      $arguments[0] = new Reference($id);
+      if (isset($priority_pos)) {
+        $arguments[$priority_pos] = $priority;
+      }
+      if (isset($id_pos)) {
+        $arguments[$id_pos] = $id;
+      }
+      // Sort the arguments by position.
+      ksort($arguments);
+      if (is_subclass_of($interfaces[$id], $interface)) {
+        $consumer->addMethodCall('addMimeTypeGuesser', $arguments);
+      }
+      else {
+        $consumer->addMethodCall('addGuesser', $arguments);
+      }
+    }
+  }
+
+}
diff --git a/core/lib/Drupal/Core/File/MimeType/ExtensionMimeTypeGuesser.php b/core/lib/Drupal/Core/File/MimeType/ExtensionMimeTypeGuesser.php
index 056f62792faa..b0798000aac0 100644
--- a/core/lib/Drupal/Core/File/MimeType/ExtensionMimeTypeGuesser.php
+++ b/core/lib/Drupal/Core/File/MimeType/ExtensionMimeTypeGuesser.php
@@ -3,12 +3,13 @@
 namespace Drupal\Core\File\MimeType;
 
 use Drupal\Core\Extension\ModuleHandlerInterface;
-use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface;
+use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface as LegacyMimeTypeGuesserInterface;
+use Symfony\Component\Mime\MimeTypeGuesserInterface;
 
 /**
  * Makes possible to guess the MIME type of a file using its extension.
  */
-class ExtensionMimeTypeGuesser implements MimeTypeGuesserInterface {
+class ExtensionMimeTypeGuesser implements MimeTypeGuesserInterface, LegacyMimeTypeGuesserInterface {
 
   /**
    * Default MIME extension mapping.
@@ -889,6 +890,14 @@ public function __construct(ModuleHandlerInterface $module_handler) {
    * {@inheritdoc}
    */
   public function guess($path) {
+    @trigger_error(__METHOD__ . '() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use ::guessMimeType() instead. See https://www.drupal.org/node/3133341', E_USER_DEPRECATED);
+    return $this->guessMimeType($path);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function guessMimeType($path): ?string {
     if ($this->mapping === NULL) {
       $mapping = $this->defaultMapping;
       // Allow modules to alter the default mapping.
@@ -927,4 +936,11 @@ public function setMapping(array $mapping = NULL) {
     $this->mapping = $mapping;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function isGuesserSupported(): bool {
+    return TRUE;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/File/MimeType/MimeTypeGuesser.php b/core/lib/Drupal/Core/File/MimeType/MimeTypeGuesser.php
index ff149b8f9510..d42f7ab90158 100644
--- a/core/lib/Drupal/Core/File/MimeType/MimeTypeGuesser.php
+++ b/core/lib/Drupal/Core/File/MimeType/MimeTypeGuesser.php
@@ -5,12 +5,13 @@
 use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser as SymfonyMimeTypeGuesser;
-use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface;
+use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface as LegacyMimeTypeGuesserInterface;
+use Symfony\Component\Mime\MimeTypeGuesserInterface as MimeTypeGuesserInterface;
 
 /**
  * Defines a MIME type guesser that also supports stream wrapper paths.
  */
-class MimeTypeGuesser implements MimeTypeGuesserInterface {
+class MimeTypeGuesser implements LegacyMimeTypeGuesserInterface, MimeTypeGuesserInterface {
 
   /**
    * An array of arrays of registered guessers keyed by priority.
@@ -51,7 +52,7 @@ public function __construct(StreamWrapperManagerInterface $stream_wrapper_manage
   /**
    * {@inheritdoc}
    */
-  public function guess($path) {
+  public function guessMimeType(string $path) : ?string {
     if ($wrapper = $this->streamWrapperManager->getViaUri($path)) {
       // Get the real path from the stream wrapper, if available. Files stored
       // in remote file systems will not have one.
@@ -67,13 +68,40 @@ public function guess($path) {
     }
 
     foreach ($this->sortedGuessers as $guesser) {
-      $mime_type = $guesser->guess($path);
+      $mime_type = $guesser->guessMimeType($path);
       if ($mime_type !== NULL) {
         return $mime_type;
       }
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function guess($path) {
+    @trigger_error(__METHOD__ . '() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use ::guessMimeType() instead. See https://www.drupal.org/node/3133341', E_USER_DEPRECATED);
+    return $this->guessMimeType($path);
+  }
+
+  /**
+   * Appends a MIME type guesser to the guessers chain.
+   *
+   * @param \Symfony\Component\Mime\MimeTypeGuesserInterface $guesser
+   *   The guesser to be appended.
+   * @param int $priority
+   *   The priority of the guesser being added.
+   *
+   * @return $this
+   */
+  public function addMimeTypeGuesser(MimeTypeGuesserInterface $guesser, $priority = 0) {
+    if ($guesser->isGuesserSupported()) {
+      $this->guessers[$priority][] = $guesser;
+      // Mark sorted guessers for rebuild.
+      $this->sortedGuessers = NULL;
+    }
+    return $this;
+  }
+
   /**
    * Appends a MIME type guesser to the guessers chain.
    *
@@ -83,14 +111,27 @@ public function guess($path) {
    *   The priority of the guesser being added.
    *
    * @return $this
+   *
+   * @deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use
+   * ::addMimeTypeGuesser() instead.
+   *
+   * @see https://www.drupal.org/node/3133341
    */
-  public function addGuesser(MimeTypeGuesserInterface $guesser, $priority = 0) {
+  public function addGuesser(LegacyMimeTypeGuesserInterface $guesser, $priority = 0) {
+    @trigger_error(__METHOD__ . ' is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use ::addMimeTypeGuesser() instead. See https://www.drupal.org/node/3133341', E_USER_DEPRECATED);
     $this->guessers[$priority][] = $guesser;
     // Mark sorted guessers for rebuild.
     $this->sortedGuessers = NULL;
     return $this;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function isGuesserSupported(): bool {
+    return TRUE;
+  }
+
   /**
    * Sorts guessers according to priority.
    *
diff --git a/core/lib/Drupal/Core/File/file.api.php b/core/lib/Drupal/Core/File/file.api.php
index 6c5236fec9f7..26501ff8a776 100644
--- a/core/lib/Drupal/Core/File/file.api.php
+++ b/core/lib/Drupal/Core/File/file.api.php
@@ -108,8 +108,9 @@ function hook_file_url_alter(&$uri) {
 /**
  * Alter MIME type mappings used to determine MIME type from a file extension.
  *
- * Invoked by \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::guess(). It
- * is used to allow modules to add to or modify the default mapping from
+ * Invoked by
+ * \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::guessMimeType(). It is
+ * used to allow modules to add to or modify the default mapping from
  * \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::$defaultMapping.
  *
  * @param $mapping
@@ -117,7 +118,7 @@ function hook_file_url_alter(&$uri) {
  *   The array has 'mimetypes' and 'extensions' elements, each of which is an
  *   array.
  *
- * @see \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::guess()
+ * @see \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::guessMimeType()
  * @see \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::$defaultMapping
  */
 function hook_file_mimetype_mapping_alter(&$mapping) {
diff --git a/core/lib/Drupal/Core/ProxyClass/File/MimeType/ExtensionMimeTypeGuesser.php b/core/lib/Drupal/Core/ProxyClass/File/MimeType/ExtensionMimeTypeGuesser.php
index ccaa8cc0c4ee..d3f3fef6ebbc 100644
--- a/core/lib/Drupal/Core/ProxyClass/File/MimeType/ExtensionMimeTypeGuesser.php
+++ b/core/lib/Drupal/Core/ProxyClass/File/MimeType/ExtensionMimeTypeGuesser.php
@@ -12,7 +12,7 @@
      *
      * @see \Drupal\Component\ProxyBuilder
      */
-    class ExtensionMimeTypeGuesser implements \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface
+    class ExtensionMimeTypeGuesser implements \Symfony\Component\Mime\MimeTypeGuesserInterface, \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface
     {
 
         use \Drupal\Core\DependencyInjection\DependencySerializationTrait;
@@ -75,6 +75,14 @@ public function guess($path)
             return $this->lazyLoadItself()->guess($path);
         }
 
+        /**
+         * {@inheritdoc}
+         */
+        public function guessMimeType($path): string
+        {
+            return $this->lazyLoadItself()->guessMimeType($path);
+        }
+
         /**
          * {@inheritdoc}
          */
@@ -83,6 +91,14 @@ public function setMapping(array $mapping = NULL)
             return $this->lazyLoadItself()->setMapping($mapping);
         }
 
+        /**
+         * {@inheritdoc}
+         */
+        public function isGuesserSupported(): bool
+        {
+            return $this->lazyLoadItself()->isGuesserSupported();
+        }
+
     }
 
 }
diff --git a/core/lib/Drupal/Core/ProxyClass/File/MimeType/MimeTypeGuesser.php b/core/lib/Drupal/Core/ProxyClass/File/MimeType/MimeTypeGuesser.php
index 02f21c5230aa..bbc8b16e32ea 100644
--- a/core/lib/Drupal/Core/ProxyClass/File/MimeType/MimeTypeGuesser.php
+++ b/core/lib/Drupal/Core/ProxyClass/File/MimeType/MimeTypeGuesser.php
@@ -12,7 +12,7 @@
      *
      * @see \Drupal\Component\ProxyBuilder
      */
-    class MimeTypeGuesser implements \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface
+    class MimeTypeGuesser implements \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface, \Symfony\Component\Mime\MimeTypeGuesserInterface
     {
 
         use \Drupal\Core\DependencyInjection\DependencySerializationTrait;
@@ -67,6 +67,14 @@ protected function lazyLoadItself()
             return $this->service;
         }
 
+        /**
+         * {@inheritdoc}
+         */
+        public function guessMimeType(string $path): string
+        {
+            return $this->lazyLoadItself()->guessMimeType($path);
+        }
+
         /**
          * {@inheritdoc}
          */
@@ -75,6 +83,14 @@ public function guess($path)
             return $this->lazyLoadItself()->guess($path);
         }
 
+        /**
+         * {@inheritdoc}
+         */
+        public function addMimeTypeGuesser($guesser, $priority = 0)
+        {
+            return $this->lazyLoadItself()->addMimeTypeGuesser($guesser, $priority);
+        }
+
         /**
          * {@inheritdoc}
          */
@@ -83,6 +99,14 @@ public function addGuesser(\Symfony\Component\HttpFoundation\File\MimeType\MimeT
             return $this->lazyLoadItself()->addGuesser($guesser, $priority);
         }
 
+        /**
+         * {@inheritdoc}
+         */
+        public function isGuesserSupported(): bool
+        {
+            return $this->lazyLoadItself()->isGuesserSupported();
+        }
+
         /**
          * {@inheritdoc}
          */
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index d63f1e856d92..18eecb71257f 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -23,6 +23,7 @@
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Template\Attribute;
+use Symfony\Component\Mime\MimeTypeGuesserInterface;
 
 /**
  * The regex pattern used when checking for insecure file types.
@@ -945,7 +946,14 @@ function _file_save_upload_single(\SplFileInfo $file_info, $form_field_name, $va
     'uri' => $file_info->getRealPath(),
     'filesize' => $file_info->getSize(),
   ];
-  $values['filemime'] = \Drupal::service('file.mime_type.guesser')->guess($values['filename']);
+  $guesser = \Drupal::service('file.mime_type.guesser');
+  if ($guesser instanceof MimeTypeGuesserInterface) {
+    $values['filemime'] = $guesser->guessMimeType($values['filename']);
+  }
+  else {
+    $values['filemime'] = $guesser->guess($values['filename']);
+    @trigger_error('\Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Implement \Symfony\Component\Mime\MimeTypeGuesserInterface instead. See https://www.drupal.org/node/3133341', E_USER_DEPRECATED);
+  }
   $file = File::create($values);
 
   $extensions = '';
diff --git a/core/modules/file/src/Entity/File.php b/core/modules/file/src/Entity/File.php
index 6332ca32aaef..e707b9ae4f84 100644
--- a/core/modules/file/src/Entity/File.php
+++ b/core/modules/file/src/Entity/File.php
@@ -10,6 +10,7 @@
 use Drupal\Core\File\Exception\FileException;
 use Drupal\file\FileInterface;
 use Drupal\user\EntityOwnerTrait;
+use Symfony\Component\Mime\MimeTypeGuesserInterface;
 
 /**
  * Defines the file entity class.
@@ -160,7 +161,14 @@ public static function preCreate(EntityStorageInterface $storage, array &$values
 
     // Automatically detect filemime if not set.
     if (!isset($values['filemime']) && isset($values['uri'])) {
-      $values['filemime'] = \Drupal::service('file.mime_type.guesser')->guess($values['uri']);
+      $guesser = \Drupal::service('file.mime_type.guesser');
+      if ($guesser instanceof MimeTypeGuesserInterface) {
+        $values['filemime'] = $guesser->guessMimeType($values['uri']);
+      }
+      else {
+        $values['filemime'] = $guesser->guess($values['uri']);
+        @trigger_error('\Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Implement \Symfony\Component\Mime\MimeTypeGuesserInterface instead. See https://www.drupal.org/node/3133341', E_USER_DEPRECATED);
+      }
     }
   }
 
diff --git a/core/modules/file/src/Plugin/Field/FieldFormatter/FileMediaFormatterBase.php b/core/modules/file/src/Plugin/Field/FieldFormatter/FileMediaFormatterBase.php
index 72192d6295ec..d69ab74005ab 100644
--- a/core/modules/file/src/Plugin/Field/FieldFormatter/FileMediaFormatterBase.php
+++ b/core/modules/file/src/Plugin/Field/FieldFormatter/FileMediaFormatterBase.php
@@ -8,6 +8,7 @@
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Template\Attribute;
+use Symfony\Component\Mime\MimeTypeGuesserInterface;
 
 /**
  * Base class for media file formatter.
@@ -75,13 +76,18 @@ public static function isApplicable(FieldDefinitionInterface $field_definition)
     if (!parent::isApplicable($field_definition)) {
       return FALSE;
     }
-    /** @var \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface $extension_mime_type_guesser */
+    /** @var \Symfony\Component\Mime\MimeTypeGuesserInterface $extension_mime_type_guesser */
     $extension_mime_type_guesser = \Drupal::service('file.mime_type.guesser.extension');
     $extension_list = array_filter(preg_split('/\s+/', $field_definition->getSetting('file_extensions')));
 
     foreach ($extension_list as $extension) {
-      $mime_type = $extension_mime_type_guesser->guess('fakedFile.' . $extension);
-
+      if ($extension_mime_type_guesser instanceof MimeTypeGuesserInterface) {
+        $mime_type = $extension_mime_type_guesser->guessMimeType('fakedFile.' . $extension);
+      }
+      else {
+        $mime_type = $extension_mime_type_guesser->guess('fakedFile.' . $extension);
+        @trigger_error('\Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Implement \Symfony\Component\Mime\MimeTypeGuesserInterface instead. See https://www.drupal.org/node/3133341', E_USER_DEPRECATED);
+      }
       if (static::mimeTypeApplies($mime_type)) {
         return TRUE;
       }
diff --git a/core/modules/file/src/Plugin/rest/resource/FileUploadResource.php b/core/modules/file/src/Plugin/rest/resource/FileUploadResource.php
index 9127da760440..1aaa5a753bad 100644
--- a/core/modules/file/src/Plugin/rest/resource/FileUploadResource.php
+++ b/core/modules/file/src/Plugin/rest/resource/FileUploadResource.php
@@ -23,11 +23,11 @@
 use Drupal\rest\RequestHandler;
 use Psr\Log\LoggerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
+use Symfony\Component\Mime\MimeTypeGuesserInterface;
 use Symfony\Component\Routing\Route;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\Exception\HttpException;
@@ -103,7 +103,7 @@ class FileUploadResource extends ResourceBase {
   /**
    * The MIME type guesser.
    *
-   * @var \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface
+   * @var \Symfony\Component\Mime\MimeTypeGuesserInterface
    */
   protected $mimeTypeGuesser;
 
@@ -147,7 +147,7 @@ class FileUploadResource extends ResourceBase {
    *   The entity field manager.
    * @param \Drupal\Core\Session\AccountInterface $current_user
    *   The currently authenticated user.
-   * @param \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface $mime_type_guesser
+   * @param \Symfony\Component\Mime\MimeTypeGuesserInterface $mime_type_guesser
    *   The MIME type guesser.
    * @param \Drupal\Core\Utility\Token $token
    *   The token replacement instance.
@@ -156,7 +156,7 @@ class FileUploadResource extends ResourceBase {
    * @param \Drupal\Core\Config\Config $system_file_config
    *   The system file configuration.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, $serializer_formats, LoggerInterface $logger, FileSystemInterface $file_system, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, AccountInterface $current_user, MimeTypeGuesserInterface $mime_type_guesser, Token $token, LockBackendInterface $lock, Config $system_file_config) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, $serializer_formats, LoggerInterface $logger, FileSystemInterface $file_system, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, AccountInterface $current_user, $mime_type_guesser, Token $token, LockBackendInterface $lock, Config $system_file_config) {
     parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);
     $this->fileSystem = $file_system;
     $this->entityTypeManager = $entity_type_manager;
@@ -254,7 +254,13 @@ public function post(Request $request, $entity_type_id, $bundle, $field_name) {
     $file = File::create([]);
     $file->setOwnerId($this->currentUser->id());
     $file->setFilename($prepared_filename);
-    $file->setMimeType($this->mimeTypeGuesser->guess($prepared_filename));
+    if ($this->mimeTypeGuesser instanceof MimeTypeGuesserInterface) {
+      $file->setMimeType($this->mimeTypeGuesser->guessMimeType($prepared_filename));
+    }
+    else {
+      $file->setMimeType($this->mimeTypeGuesser->guess($prepared_filename));
+      @trigger_error('\Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Implement \Symfony\Component\Mime\MimeTypeGuesserInterface instead. See https://www.drupal.org/node/3133341', E_USER_DEPRECATED);
+    }
     $file->setFileUri($file_uri);
     // Set the size. This is done in File::preSave() but we validate the file
     // before it is saved.
diff --git a/core/modules/image/src/Plugin/Field/FieldType/ImageItem.php b/core/modules/image/src/Plugin/Field/FieldType/ImageItem.php
index e462dc6f7258..8f80ef6f46de 100644
--- a/core/modules/image/src/Plugin/Field/FieldType/ImageItem.php
+++ b/core/modules/image/src/Plugin/Field/FieldType/ImageItem.php
@@ -13,6 +13,7 @@
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\file\Entity\File;
 use Drupal\file\Plugin\Field\FieldType\FileItem;
+use Symfony\Component\Mime\MimeTypeGuesserInterface;
 
 /**
  * Plugin implementation of the 'image' field type.
@@ -351,7 +352,14 @@ public static function generateSampleValue(FieldDefinitionInterface $field_defin
         $image = File::create();
         $image->setFileUri($path);
         $image->setOwnerId(\Drupal::currentUser()->id());
-        $image->setMimeType(\Drupal::service('file.mime_type.guesser')->guess($path));
+        $guesser = \Drupal::service('file.mime_type.guesser');
+        if ($guesser instanceof MimeTypeGuesserInterface) {
+          $image->setMimeType($guesser->guessMimeType($path));
+        }
+        else {
+          $image->setMimeType($guesser->guess($path));
+          @trigger_error('\Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Implement \Symfony\Component\Mime\MimeTypeGuesserInterface instead. See https://www.drupal.org/node/3133341', E_USER_DEPRECATED);
+        }
         $image->setFileName($file_system->basename($path));
         $destination_dir = static::doGetUploadLocation($settings);
         $file_system->prepareDirectory($destination_dir, FileSystemInterface::CREATE_DIRECTORY);
diff --git a/core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php b/core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php
index 5d63fb9bbe7f..8ebeaf870df8 100644
--- a/core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php
+++ b/core/modules/jsonapi/src/Controller/TemporaryJsonapiFileFieldUploader.php
@@ -21,10 +21,10 @@
 use Drupal\file\Entity\File;
 use Drupal\file\Plugin\Field\FieldType\FileFieldItemList;
 use Psr\Log\LoggerInterface;
-use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface;
 use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\Exception\HttpException;
+use Symfony\Component\Mime\MimeTypeGuesserInterface;
 use Symfony\Component\Validator\ConstraintViolation;
 
 /**
@@ -73,7 +73,7 @@ class TemporaryJsonapiFileFieldUploader {
   /**
    * The MIME type guesser.
    *
-   * @var \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface
+   * @var \Symfony\Component\Mime\MimeTypeGuesserInterface
    */
   protected $mimeTypeGuesser;
 
@@ -105,7 +105,7 @@ class TemporaryJsonapiFileFieldUploader {
    *   A logger instance.
    * @param \Drupal\Core\File\FileSystemInterface $file_system
    *   The file system service.
-   * @param \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface $mime_type_guesser
+   * @param \Symfony\Component\Mime\MimeTypeGuesserInterface $mime_type_guesser
    *   The MIME type guesser.
    * @param \Drupal\Core\Utility\Token $token
    *   The token replacement instance.
@@ -114,7 +114,7 @@ class TemporaryJsonapiFileFieldUploader {
    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
    *   The config factory.
    */
-  public function __construct(LoggerInterface $logger, FileSystemInterface $file_system, MimeTypeGuesserInterface $mime_type_guesser, Token $token, LockBackendInterface $lock, ConfigFactoryInterface $config_factory) {
+  public function __construct(LoggerInterface $logger, FileSystemInterface $file_system, $mime_type_guesser, Token $token, LockBackendInterface $lock, ConfigFactoryInterface $config_factory) {
     $this->logger = $logger;
     $this->fileSystem = $file_system;
     $this->mimeTypeGuesser = $mime_type_guesser;
@@ -173,7 +173,13 @@ public function handleFileUploadForField(FieldDefinitionInterface $field_definit
     $file = File::create([]);
     $file->setOwnerId($owner->id());
     $file->setFilename($prepared_filename);
-    $file->setMimeType($this->mimeTypeGuesser->guess($prepared_filename));
+    if ($this->mimeTypeGuesser instanceof MimeTypeGuesserInterface) {
+      $file->setMimeType($this->mimeTypeGuesser->guessMimeType($prepared_filename));
+    }
+    else {
+      @trigger_error('\Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Implement \Symfony\Component\Mime\MimeTypeGuesserInterface instead. See https://www.drupal.org/node/3133341', E_USER_DEPRECATED);
+      $file->setMimeType($this->mimeTypeGuesser->guess($prepared_filename));
+    }
     $file->setFileUri($file_uri);
     // Set the size. This is done in File::preSave() but we validate the file
     // before it is saved.
diff --git a/core/modules/responsive_image/responsive_image.module b/core/modules/responsive_image/responsive_image.module
index 36ea84d2b15f..566737104240 100644
--- a/core/modules/responsive_image/responsive_image.module
+++ b/core/modules/responsive_image/responsive_image.module
@@ -13,6 +13,7 @@
 use Drupal\responsive_image\Entity\ResponsiveImageStyle;
 use Drupal\responsive_image\ResponsiveImageStyleInterface;
 use Drupal\breakpoint\BreakpointInterface;
+use Symfony\Component\Mime\MimeTypeGuesserInterface;
 
 /**
  * Implements hook_help().
@@ -477,7 +478,12 @@ function responsive_image_get_mime_type($image_style_name, $extension) {
   else {
     $fake_path = 'responsive_image.' . ImageStyle::load($image_style_name)->getDerivativeExtension($extension);
   }
-  return Drupal::service('file.mime_type.guesser.extension')->guess($fake_path);
+  $guesser = \Drupal::service('file.mime_type.guesser.extension');
+  if (!$guesser instanceof MimeTypeGuesserInterface) {
+    @trigger_error('\Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Implement \Symfony\Component\Mime\MimeTypeGuesserInterface instead. See https://www.drupal.org/node/3133341', E_USER_DEPRECATED);
+    return $guesser->guess($fake_path);
+  }
+  return $guesser->guessMimeType($fake_path);
 }
 
 /**
diff --git a/core/modules/system/src/Form/ThemeSettingsForm.php b/core/modules/system/src/Form/ThemeSettingsForm.php
index 46885f25f7cd..e863c0f80594 100644
--- a/core/modules/system/src/Form/ThemeSettingsForm.php
+++ b/core/modules/system/src/Form/ThemeSettingsForm.php
@@ -10,12 +10,12 @@
 use Drupal\Core\StreamWrapper\PublicStream;
 use Drupal\Core\StreamWrapper\StreamWrapperManager;
 use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Form\ConfigFormBase;
 use Drupal\Core\Theme\ThemeManagerInterface;
+use Symfony\Component\Mime\MimeTypeGuesserInterface;
 
 /**
  * Displays theme configuration for entire site and individual themes.
@@ -41,7 +41,7 @@ class ThemeSettingsForm extends ConfigFormBase {
   /**
    * The MIME type guesser.
    *
-   * @var \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface
+   * @var \Symfony\Component\Mime\MimeTypeGuesserInterface
    */
   protected $mimeTypeGuesser;
 
@@ -75,14 +75,14 @@ class ThemeSettingsForm extends ConfigFormBase {
    *   The module handler instance to use.
    * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
    *   The theme handler.
-   * @param \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface $mime_type_guesser
+   * @param \Symfony\Component\Mime\MimeTypeGuesserInterface $mime_type_guesser
    *   The MIME type guesser instance to use.
    * @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
    *   The theme manager.
    * @param \Drupal\Core\File\FileSystemInterface $file_system
    *   The file system.
    */
-  public function __construct(ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, MimeTypeGuesserInterface $mime_type_guesser, ThemeManagerInterface $theme_manager, FileSystemInterface $file_system) {
+  public function __construct(ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, $mime_type_guesser, ThemeManagerInterface $theme_manager, FileSystemInterface $file_system) {
     parent::__construct($config_factory);
 
     $this->moduleHandler = $module_handler;
@@ -494,7 +494,13 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     }
 
     if (empty($values['default_favicon']) && !empty($values['favicon_path'])) {
-      $values['favicon_mimetype'] = $this->mimeTypeGuesser->guess($values['favicon_path']);
+      if ($this->mimeTypeGuesser instanceof MimeTypeGuesserInterface) {
+        $values['favicon_mimetype'] = $this->mimeTypeGuesser->guessMimeType($values['favicon_path']);
+      }
+      else {
+        $values['favicon_mimetype'] = $this->mimeTypeGuesser->guess($values['favicon_path']);
+        @trigger_error('\Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Implement \Symfony\Component\Mime\MimeTypeGuesserInterface instead. See https://www.drupal.org/node/3133341', E_USER_DEPRECATED);
+      }
     }
 
     theme_settings_convert_to_config($values, $config)->save();
diff --git a/core/tests/Drupal/KernelTests/Core/File/MimeTypeTest.php b/core/tests/Drupal/KernelTests/Core/File/MimeTypeTest.php
index 40f278b2b99f..1099dd0656df 100644
--- a/core/tests/Drupal/KernelTests/Core/File/MimeTypeTest.php
+++ b/core/tests/Drupal/KernelTests/Core/File/MimeTypeTest.php
@@ -2,8 +2,6 @@
 
 namespace Drupal\KernelTests\Core\File;
 
-use Drupal\Component\Render\FormattableMarkup;
-
 /**
  * Tests filename mimetype detection.
  *
@@ -46,13 +44,13 @@ public function testFileMimeTypeDetection() {
     foreach ($test_case as $input => $expected) {
       // Test stream [URI].
       foreach ($prefixes as $prefix) {
-        $output = $guesser->guess($prefix . $input);
-        $this->assertIdentical($output, $expected, new FormattableMarkup('Mimetype for %input is %output (expected: %expected).', ['%input' => $prefix . $input, '%output' => $output, '%expected' => $expected]));
+        $output = $guesser->guessMimeType($prefix . $input);
+        $this->assertSame($expected, $output);
       }
 
       // Test normal path equivalent
-      $output = $guesser->guess($input);
-      $this->assertIdentical($output, $expected, new FormattableMarkup('Mimetype (using default mappings) for %input is %output (expected: %expected).', ['%input' => $input, '%output' => $output, '%expected' => $expected]));
+      $output = $guesser->guessMimeType($input);
+      $this->assertSame($expected, $output);
     }
 
     // Now test the extension guesser by passing in a custom mapping.
@@ -86,9 +84,24 @@ public function testFileMimeTypeDetection() {
     $extension_guesser->setMapping($mapping);
 
     foreach ($test_case as $input => $expected) {
-      $output = $extension_guesser->guess($input);
-      $this->assertIdentical($output, $expected, new FormattableMarkup('Mimetype (using passed-in mappings) for %input is %output (expected: %expected).', ['%input' => $input, '%output' => $output, '%expected' => $expected]));
+      $output = $extension_guesser->guessMimeType($input);
+      $this->assertSame($expected, $output);
     }
   }
 
+  /**
+   * Test deprecations.
+   *
+   * @group legacy
+   * @expectedDeprecation The "Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser" class is deprecated since Symfony 4.3, use "Symfony\Component\Mime\MimeTypes" instead.
+   * @expectedDeprecation The "Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser" class is deprecated since Symfony 4.3, use "Symfony\Component\Mime\FileBinaryMimeTypeGuesser" instead.
+   * @expectedDeprecation The "Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser" class is deprecated since Symfony 4.3, use "Symfony\Component\Mime\FileinfoMimeTypeGuesser" instead.
+   * @expectedDeprecation Drupal\Core\File\MimeType\MimeTypeGuesser::guess() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use ::guessMimeType() instead. See https://www.drupal.org/node/3133341
+   */
+  public function testFileMimeTypeDetectionDeprecation() {
+    $guesser = $this->container->get('file.mime_type.guesser');
+    $output = $guesser->guess('public://test.jar');
+    $this->assertSame('application/java-archive', $output);
+  }
+
 }
diff --git a/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/MimeTypePassTest.php b/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/MimeTypePassTest.php
new file mode 100644
index 000000000000..6526135f89ec
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/MimeTypePassTest.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace Drupal\Tests\Core\DependencyInjection\Compiler;
+
+use Drupal\Core\DependencyInjection\Compiler\MimeTypePass;
+use Drupal\Tests\UnitTestCase;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface as LegacyMimeTypeGuesserInterface;
+use Symfony\Component\Mime\MimeTypeGuesserInterface;
+use Drupal\Core\File\MimeType\MimeTypeGuesser;
+
+/**
+ * @coversDefaultClass \Drupal\Core\DependencyInjection\Compiler\MimeTypePass
+ * @group DependencyInjection
+ * @group legacy
+ * @runInSeparateProcess
+ */
+class MimeTypePassTest extends UnitTestCase {
+
+  protected function buildContainer($environment = 'dev') {
+    $container = new ContainerBuilder();
+    $container->setParameter('kernel.environment', $environment);
+    return $container;
+  }
+
+  /**
+   * Tests backwards compatibility shim for MimeTypeGuesser interface changes.
+   *
+   * @expectedDeprecation The "Drupal\Tests\Core\DependencyInjection\Compiler\LegacyMimeTypeGuesser" class implements "Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface" that is deprecated since Symfony 4.3, use {@link MimeTypesInterface} instead.
+   */
+  public function testProcessLegacy() {
+    $container = $this->buildContainer();
+    $container
+      ->register('file.mime_type.guesser', MimeTypeGuesser::class);
+
+    $container
+      ->register('handler1', __NAMESPACE__ . '\NewMimeTypeGuesser')
+      ->addTag('mime_type_guesser');
+    $container
+      ->register('handler2', __NAMESPACE__ . '\LegacyMimeTypeGuesser')
+      ->addTag('mime_type_guesser');
+
+    $handler_pass = new MimeTypePass();
+    $handler_pass->process($container);
+    $method_calls = $container->getDefinition('file.mime_type.guesser')->getMethodCalls();
+    $this->assertCount(2, $method_calls);
+  }
+
+}
+
+class NewMimeTypeGuesser implements MimeTypeGuesserInterface {
+
+  public function guessMimeType(string $string): string {}
+
+  public function isGuesserSupported(): bool {}
+
+}
+
+class LegacyMimeTypeGuesser implements LegacyMimeTypeGuesserInterface {
+
+  public function guess($string) {}
+
+}
diff --git a/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php b/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php
index 1895054764e9..64ffefb87ea1 100644
--- a/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php
+++ b/core/tests/Drupal/Tests/Listeners/DeprecationListenerTrait.php
@@ -107,6 +107,7 @@ public static function getSkippedDeprecations() {
       'The "Drupal\Core\File\MimeType\MimeTypeGuesser" class implements "Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface" that is deprecated since Symfony 4.3, use {@link MimeTypesInterface} instead.',
       'The "Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser" class is deprecated since Symfony 4.3, use "Symfony\Component\Mime\FileBinaryMimeTypeGuesser" instead.',
       'The "Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser" class is deprecated since Symfony 4.3, use "Symfony\Component\Mime\FileinfoMimeTypeGuesser" instead.',
+      'The "Drupal\Tests\Core\DependencyInjection\Compiler\LegacyMimeTypeGuesser" class implements "Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface" that is deprecated since Symfony 4.3, use {@link MimeTypesInterface} instead.',
       'The "Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher::dispatch()" method will require a new "string|null $eventName" argument in the next major version of its interface "Symfony\Contracts\EventDispatcher\EventDispatcherInterface", not defining it is deprecated.',
       'The "Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher::dispatch()" method will require a new "string|null $eventName" argument in the next major version of its parent class "Symfony\Contracts\EventDispatcher\EventDispatcherInterface", not defining it is deprecated.',
       'Passing a command as string when creating a "Symfony\Component\Process\Process" instance is deprecated since Symfony 4.2, pass it as an array of its arguments instead, or use the "Process::fromShellCommandline()" constructor if you need features provided by the shell.',
-- 
GitLab