From fa31ac08fdecba96a218fc08d067a0a9a9cff052 Mon Sep 17 00:00:00 2001
From: Nathaniel Catchpole <catch@35733.no-reply.drupal.org>
Date: Mon, 8 Dec 2014 10:03:17 +0000
Subject: [PATCH] Issue #2387443 by alexpott, dawehner: BinaryFileResponse can
 fail because the core MIME guessing is not added to the MimeType singleton

---
 core/lib/Drupal/Core/DrupalKernel.php         |  4 ++
 .../Core/File/MimeType/MimeTypeGuesser.php    | 16 +++++++
 .../Tests/Core/File/MimeTypeGuesserTest.php   | 43 +++++++++++++++++++
 3 files changed, 63 insertions(+)
 create mode 100644 core/tests/Drupal/Tests/Core/File/MimeTypeGuesserTest.php

diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index 2c58ccc7035f..6495229a8b51 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -18,6 +18,7 @@
 use Drupal\Core\DependencyInjection\ServiceProviderInterface;
 use Drupal\Core\DependencyInjection\YamlFileLoader;
 use Drupal\Core\Extension\ExtensionDiscovery;
+use Drupal\Core\File\MimeType\MimeTypeGuesser;
 use Drupal\Core\Language\Language;
 use Drupal\Core\PageCache\RequestPolicyInterface;
 use Drupal\Core\PhpStorage\PhpStorageFactory;
@@ -458,6 +459,9 @@ public function preHandle(Request $request) {
       $allowed_protocols = array('http', 'https');
     }
     UrlHelper::setAllowedProtocols($allowed_protocols);
+
+    // Override of Symfony's mime type guesser singleton.
+    MimeTypeGuesser::registerWithSymfonyGuesser($this->container);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/File/MimeType/MimeTypeGuesser.php b/core/lib/Drupal/Core/File/MimeType/MimeTypeGuesser.php
index d7b276836eb0..20544638a090 100644
--- a/core/lib/Drupal/Core/File/MimeType/MimeTypeGuesser.php
+++ b/core/lib/Drupal/Core/File/MimeType/MimeTypeGuesser.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\Core\File\MimeType;
 
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser as SymfonyMimeTypeGuesser;
 use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface;
 
 /**
@@ -88,4 +90,18 @@ protected function sortGuessers() {
     return $sorted;
   }
 
+  /**
+   * A helper function to register with Symfony's singleton mime type guesser.
+   *
+   * Symfony's default mimetype guessers have dependencies on PHP's fileinfo
+   * extension or being able to run the system command file. Drupal's guesser
+   * does not have these dependencies.
+   *
+   * @see \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser
+   */
+  public static function registerWithSymfonyGuesser(ContainerInterface $container) {
+    $singleton = SymfonyMimeTypeGuesser::getInstance();
+    $singleton->register($container->get('file.mime_type.guesser'));
+  }
+
 }
diff --git a/core/tests/Drupal/Tests/Core/File/MimeTypeGuesserTest.php b/core/tests/Drupal/Tests/Core/File/MimeTypeGuesserTest.php
new file mode 100644
index 000000000000..a1bf9c2327cb
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/File/MimeTypeGuesserTest.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\File\MimeTypeGuesserTest.
+ */
+
+namespace Drupal\Tests\Core\File;
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\File\MimeType\MimeTypeGuesser;
+use Drupal\Tests\UnitTestCase;
+use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser as SymfonyMimeTypeGuesser;
+
+/**
+ * @coversDefaultClass \Drupal\Core\File\MimeType\MimeTypeGuesser
+ * @group DrupalKernel
+ */
+class MimeTypeGuesserTest extends UnitTestCase {
+
+  /**
+   * @covers ::registerWithSymfonyGuesser
+   *
+   * @see Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser
+   */
+  public function testSymfonyGuesserRegistration() {
+    // Make the guessers property accessible on Symfony's MimeTypeGuesser.
+    $symfony_guesser = SymfonyMimeTypeGuesser::getInstance();
+    // Test that the Drupal mime type guess is not being used before the
+    // override method is called. It is possible that the test environment does
+    // not support the default guessers.
+    $guessers = $this->readAttribute($symfony_guesser, 'guessers');
+    if (count($guessers)) {
+      $this->assertNotInstanceOf('Drupal\Core\File\MimeType\MimeTypeGuesser', $guessers[0]);
+    }
+    $container = new ContainerBuilder();
+    $container->set('file.mime_type.guesser', new MimeTypeGuesser());
+    MimeTypeGuesser::registerWithSymfonyGuesser($container);
+    $guessers = $this->readAttribute($symfony_guesser, 'guessers');
+    $this->assertInstanceOf('Drupal\Core\File\MimeType\MimeTypeGuesser', $guessers[0]);
+  }
+
+}
-- 
GitLab