aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Scherzinger <info@andy-scherzinger.de>2025-02-13 16:42:50 +0100
committerGitHub <noreply@github.com>2025-02-13 16:42:50 +0100
commit6964531134bcaea659bb4455d094fdfddefb70c7 (patch)
tree16fa20ac7d172dc06dba2d2f9e44e1c1bd8d027a
parent2af31ab059808a818daaeb5a7172aacf2860df89 (diff)
parent86408a5be7ab1209e322cbd225bb094588caaa95 (diff)
downloadnextcloud-server-6964531134bcaea659bb4455d094fdfddefb70c7.tar.gz
nextcloud-server-6964531134bcaea659bb4455d094fdfddefb70c7.zip
Merge pull request #50704 from nextcloud/backport/50660/stable30
[stable30] fix: make sure we process mime extensions as string
-rw-r--r--build/psalm-baseline.xml6
-rw-r--r--core/Command/Maintenance/Mimetype/GenerateMimetypeFileBuilder.php4
-rw-r--r--core/Command/Maintenance/Mimetype/UpdateDB.php4
-rw-r--r--lib/private/Files/Type/Detection.php15
-rw-r--r--lib/public/Files/IMimeTypeDetector.php6
-rw-r--r--lib/public/Files/IMimeTypeLoader.php10
-rw-r--r--tests/lib/Files/Type/DetectionTest.php35
7 files changed, 70 insertions, 10 deletions
diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml
index 184587e572d..296c7852a9c 100644
--- a/build/psalm-baseline.xml
+++ b/build/psalm-baseline.xml
@@ -1320,12 +1320,6 @@
<code><![CDATA[$this->timeFactory->getTime()]]></code>
</InvalidScalarArgument>
</file>
- <file src="core/Command/Maintenance/Mimetype/UpdateDB.php">
- <UndefinedInterfaceMethod>
- <code><![CDATA[getAllMappings]]></code>
- <code><![CDATA[updateFilecache]]></code>
- </UndefinedInterfaceMethod>
- </file>
<file src="core/Command/Preview/Repair.php">
<UndefinedInterfaceMethod>
<code><![CDATA[section]]></code>
diff --git a/core/Command/Maintenance/Mimetype/GenerateMimetypeFileBuilder.php b/core/Command/Maintenance/Mimetype/GenerateMimetypeFileBuilder.php
index 1a6c3933461..7e54af61748 100644
--- a/core/Command/Maintenance/Mimetype/GenerateMimetypeFileBuilder.php
+++ b/core/Command/Maintenance/Mimetype/GenerateMimetypeFileBuilder.php
@@ -18,6 +18,10 @@ class GenerateMimetypeFileBuilder {
public function generateFile(array $aliases): string {
// Remove comments
$aliases = array_filter($aliases, static function ($key) {
+ // Single digit extensions will be treated as integers
+ // Let's make sure they are strings
+ // https://github.com/nextcloud/server/issues/42902
+ $key = (string)$key;
return !($key === '' || $key[0] === '_');
}, ARRAY_FILTER_USE_KEY);
diff --git a/core/Command/Maintenance/Mimetype/UpdateDB.php b/core/Command/Maintenance/Mimetype/UpdateDB.php
index fd448cf862a..97677b9d5f4 100644
--- a/core/Command/Maintenance/Mimetype/UpdateDB.php
+++ b/core/Command/Maintenance/Mimetype/UpdateDB.php
@@ -45,6 +45,10 @@ class UpdateDB extends Command {
$totalNewMimetypes = 0;
foreach ($mappings as $ext => $mimetypes) {
+ // Single digit extensions will be treated as integers
+ // Let's make sure they are strings
+ // https://github.com/nextcloud/server/issues/42902
+ $ext = (string)$ext;
if ($ext[0] === '_') {
// comment
continue;
diff --git a/lib/private/Files/Type/Detection.php b/lib/private/Files/Type/Detection.php
index b1e4c098e54..3676a9b736c 100644
--- a/lib/private/Files/Type/Detection.php
+++ b/lib/private/Files/Type/Detection.php
@@ -23,6 +23,7 @@ class Detection implements IMimeTypeDetector {
private const CUSTOM_MIMETYPEMAPPING = 'mimetypemapping.json';
private const CUSTOM_MIMETYPEALIASES = 'mimetypealiases.json';
+ /** @var array<string, list{string, string|null}> */
protected array $mimetypes = [];
protected array $secureMimeTypes = [];
@@ -52,6 +53,8 @@ class Detection implements IMimeTypeDetector {
public function registerType(string $extension,
string $mimetype,
?string $secureMimeType = null): void {
+ // Make sure the extension is a string
+ // https://github.com/nextcloud/server/issues/42902
$this->mimetypes[$extension] = [$mimetype, $secureMimeType];
$this->secureMimeTypes[$mimetype] = $secureMimeType ?: $mimetype;
}
@@ -66,13 +69,17 @@ class Detection implements IMimeTypeDetector {
* @param array $types
*/
public function registerTypeArray(array $types): void {
- $this->mimetypes = array_merge($this->mimetypes, $types);
+ // Register the types,
+ foreach ($types as $extension => $mimeType) {
+ $this->registerType((string)$extension, $mimeType[0], $mimeType[1] ?? null);
+ }
// Update the alternative mimetypes to avoid having to look them up each time.
foreach ($this->mimetypes as $extension => $mimeType) {
- if (str_starts_with($extension, '_comment')) {
+ if (str_starts_with((string)$extension, '_comment')) {
continue;
}
+
$this->secureMimeTypes[$mimeType[0]] = $mimeType[1] ?? $mimeType[0];
if (isset($mimeType[1])) {
$this->secureMimeTypes[$mimeType[1]] = $mimeType[1];
@@ -133,7 +140,7 @@ class Detection implements IMimeTypeDetector {
}
/**
- * @return array
+ * @return array<string, list{string, string|null}>
*/
public function getAllMappings(): array {
$this->loadMappings();
@@ -163,7 +170,7 @@ class Detection implements IMimeTypeDetector {
$extension = strrchr($fileName, '.');
if ($extension !== false) {
$extension = strtolower($extension);
- $extension = substr($extension, 1); //remove leading .
+ $extension = substr($extension, 1); // remove leading .
return $this->mimetypes[$extension][0] ?? 'application/octet-stream';
}
}
diff --git a/lib/public/Files/IMimeTypeDetector.php b/lib/public/Files/IMimeTypeDetector.php
index 1c683cdd4b9..6f3e498c203 100644
--- a/lib/public/Files/IMimeTypeDetector.php
+++ b/lib/public/Files/IMimeTypeDetector.php
@@ -73,4 +73,10 @@ interface IMimeTypeDetector {
* @since 28.0.0
*/
public function getAllAliases(): array;
+
+ /**
+ * @return array<string, list{string, string|null}>
+ * @since 32.0.0
+ */
+ public function getAllMappings(): array;
}
diff --git a/lib/public/Files/IMimeTypeLoader.php b/lib/public/Files/IMimeTypeLoader.php
index 44261527d53..77c59fb2c0a 100644
--- a/lib/public/Files/IMimeTypeLoader.php
+++ b/lib/public/Files/IMimeTypeLoader.php
@@ -47,4 +47,14 @@ interface IMimeTypeLoader {
* @since 8.2.0
*/
public function reset(): void;
+
+ /**
+ * Update filecache mimetype based on file extension
+ *
+ * @param string $ext
+ * @param int $mimeTypeId
+ * @return int
+ * @since 32.0.0
+ */
+ public function updateFilecache(string $ext, int $mimeTypeId): int;
}
diff --git a/tests/lib/Files/Type/DetectionTest.php b/tests/lib/Files/Type/DetectionTest.php
index e647fa064d4..6a50467a57f 100644
--- a/tests/lib/Files/Type/DetectionTest.php
+++ b/tests/lib/Files/Type/DetectionTest.php
@@ -100,6 +100,41 @@ class DetectionTest extends \Test\TestCase {
$this->assertEquals($expected, $result);
}
+ public function dataMimeTypeCustom(): array {
+ return [
+ ['123', 'foobar/123'],
+ ['a123', 'foobar/123'],
+ ['bar', 'foobar/bar'],
+ ];
+ }
+
+ /**
+ * @dataProvider dataMimeTypeCustom
+ *
+ * @param string $ext
+ * @param string $mime
+ */
+ public function testDetectMimeTypeCustom(string $ext, string $mime): void {
+ $confDir = sys_get_temp_dir();
+ file_put_contents($confDir . '/mimetypemapping.dist.json', json_encode([]));
+
+ /** @var IURLGenerator $urlGenerator */
+ $urlGenerator = $this->getMockBuilder(IURLGenerator::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ /** @var LoggerInterface $logger */
+ $logger = $this->createMock(LoggerInterface::class);
+
+ // Create new mapping file
+ file_put_contents($confDir . '/mimetypemapping.dist.json', json_encode([$ext => [$mime]]));
+
+ $detection = new Detection($urlGenerator, $logger, $confDir, $confDir);
+ $mappings = $detection->getAllMappings();
+ $this->assertArrayHasKey($ext, $mappings);
+ $this->assertEquals($mime, $detection->detectPath('foo.' . $ext));
+ }
+
public function dataGetSecureMimeType(): array {
return [
['image/svg+xml', 'text/plain'],