From 2ad684fea44a11afb4f8009a163afa4440ebecdf Mon Sep 17 00:00:00 2001 From: skjnldsv Date: Fri, 18 Sep 2026 13:02:36 +0200 Subject: [PATCH] feat(mimetype): recognise AVIF files There is no avif entry in the mapping, so detectPath() falls through to its default and an uploaded photo is labelled application/octet-stream: holiday.avif application/octet-stream holiday.heic image/heic With the mapping it is what it is: holiday.avif image/avif That is enough to keep the viewer from opening one, since a handler is chosen by mime, and enough to leave it without a name in the file list. Both are fixed here, together with a repair step so the files already stored under the wrong type are relabelled on upgrade rather than only the ones uploaded afterwards. The integrity check fixture is regenerated and re-signed, following the procedure written in the test that reads it. Assisted-by: ClaudeCode:claude-opus-5 Signed-off-by: skjnldsv --- lib/private/Repair/RepairMimeTypes.php | 16 ++++++++++++++++ resources/config/mimetypemapping.dist.json | 1 + resources/config/mimetypenames.dist.json | 1 + .../mimetypeListModified/core/js/mimetypelist.js | 1 + .../mimetypeListModified/core/signature.json | 4 ++-- tests/lib/Repair/RepairMimeTypesTest.php | 16 ++++++++++++++++ 6 files changed, 37 insertions(+), 2 deletions(-) diff --git a/lib/private/Repair/RepairMimeTypes.php b/lib/private/Repair/RepairMimeTypes.php index 785b6a0f6077f..73602366f91b0 100644 --- a/lib/private/Repair/RepairMimeTypes.php +++ b/lib/private/Repair/RepairMimeTypes.php @@ -374,6 +374,18 @@ private function introduceTomlAndOvpnType(): IResult|int|null { return $this->updateMimetypes($updatedMimetypes); } + /** + * @throws Exception + * @since 36.0.0 + */ + private function introduceAvifType(): IResult|int|null { + $updatedMimetypes = [ + 'avif' => 'image/avif', + ]; + + return $this->updateMimetypes($updatedMimetypes); + } + /** * Check if there are any migrations available * @@ -497,6 +509,10 @@ public function run(IOutput $output): void { $output->info('Fixed toml and ovpn mime type'); } + if (version_compare($mimeTypeVersion, '36.0.0.0', '<') && $this->introduceAvifType()) { + $output->info('Fixed avif mime type'); + } + if (!$this->dryRun) { $this->appConfig->setValueString('files', 'mimetype_version', $serverVersion); } diff --git a/resources/config/mimetypemapping.dist.json b/resources/config/mimetypemapping.dist.json index a98c06f9140a9..6f52b0743bc0f 100644 --- a/resources/config/mimetypemapping.dist.json +++ b/resources/config/mimetypemapping.dist.json @@ -17,6 +17,7 @@ "arw": ["image/x-dcraw"], "asciidoc": ["text/asciidoc", "text/plain"], "avi": ["video/x-msvideo"], + "avif": ["image/avif"], "bash": ["text/x-shellscript"], "bat": ["application/x-msdos-program"], "bin": ["application/x-bin"], diff --git a/resources/config/mimetypenames.dist.json b/resources/config/mimetypenames.dist.json index 2697e86482060..1b1184cc378d7 100644 --- a/resources/config/mimetypenames.dist.json +++ b/resources/config/mimetypenames.dist.json @@ -128,6 +128,7 @@ "audio/wav": "RIFF/WAVe standard Audio", "audio/webm": "WebM audio", "audio/x-scpls": "MP3 ShoutCast playlist", + "image/avif": "AVIF image", "image/bmp": "Windows BMP image", "image/bpg": "Better Portable Graphics image", "image/emf": "EMF image", diff --git a/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js b/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js index 2b7c92c35472d..acc8b8979d625 100644 --- a/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js +++ b/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js @@ -249,6 +249,7 @@ OC.MimeTypeList={ 'audio/wav': t('core', "RIFF\/WAVe standard Audio"), 'audio/webm': t('core', "WebM audio"), 'audio/x-scpls': t('core', "MP3 ShoutCast playlist"), +'image/avif': t('core', "AVIF image"), 'image/bmp': t('core', "Windows BMP image"), 'image/bpg': t('core', "Better Portable Graphics image"), 'image/emf': t('core', "EMF image"), diff --git a/tests/data/integritycheck/mimetypeListModified/core/signature.json b/tests/data/integritycheck/mimetypeListModified/core/signature.json index b2a3ce02dfcdf..7ea6873719d22 100644 --- a/tests/data/integritycheck/mimetypeListModified/core/signature.json +++ b/tests/data/integritycheck/mimetypeListModified/core/signature.json @@ -1,7 +1,7 @@ { "hashes": { - "core\/js\/mimetypelist.js": "25635feead9858d82354005d59b36ae965323bc651b012910c0178bef8e90c9809abb2a6aa2425268d0f08a545567d2f2a10f00818435dc04ded44b7d9e61fad" + "core\/js\/mimetypelist.js": "c08ff8fbaa204fb1fff9a1d9f58f78dc02d8f0b5dac7a0266e6cb8a0ea5a38facc1fb765cf5c63fb2c69230f7a972e6fb534efebec664392fb48a1b1b2cf952b" }, - "signature": "lrvTud+92i2m7XmQXbpT2LFSuFUk351DPjCRJ8hvPngKLB1yoSLQqUNOFTRN97fUKlkR2k2O8x\/HWAOG9pmB9H2m5bYrJ8\/mUbhbYSoVV5yC1rWtWH7A1uCvdj\/wDjuTR9NRKQXbIQa+v0DuwxyeRO6GiY9YRl+K5UYmP2jZscolECHCWKnHfLBoesrkt6VsJIqJTRk\/6l8\/MzMxmzcq8mWH5AdEvwieyEIXqmJevRi\/lVQG8h4l3yZukjtDHdFnbKdyOjezRQFK\/joJlxV3pNUVIsBl6ClGghS75c\/kO9AD+70BX6u6aRr9TPbkh84EmCyzceFaU+FzCd\/NC+fwPjDrJQlVh6EfwOEzkpNQP5KA5r8FVQZw51U9o1kJ3mdK04w0X2Eap0ZOz3RP2W2Vo2KJH7OitXA9TCNh9VoVY5jBJRYNeFi3NQewC6qZ2IXhXIEi8nyLjrsh71WfimvBl37s8LkDHODzKIQTCO14a7mDiiPZHry2BRHwF8G7znaEf6CCbygUZi4PK3VZT5Sv5OBzLfgkpTxRXIN6NxKljBRF8B2bz027J4L7A3s6ttpmBOXtj98MQekp27eWC4mb+ihUaxvpe6M3dsK7hCfUDl4VvPlVYo+vnCP8WNa1I2IcB38HN5Wb6E5JDhaXgCz6i3CcNXwghcrs1j7wXiDw8Rc=", + "signature": "MyLGk+nY8BLIBkr1PvLq4ePKe693xkq8xPzuyDQ4Sg7OlLkoDdlr4FqYTx7nJCyaaIO7BiaYrHHvX1BB1CSFG+Ta0bdq2A0yh+OlgQcpgFgxxv1QOS+PKrJCdNcM+UQDiyr2R6iKuhi2TfkwU7iyNHJLbTyvlJze5+mUNeLpaFIUirsiOw0O78adcJaIk6GI8eLgxI079PrZNAel7DAxzESsKPRy6td\/fenhuxSaCIx2Hmy0isjdm7a78yZ7P4+1DZmb0UGTrMOrNkSclAmvkqpKcKYwmeLQ711swmRr5SbXjjJZZrVmsWZSFFKZzmFfsNvQ83FaLCZ\/rQRbzBnBiGNQrofDkDcNb6SNiElUSQhP4rc1iu6fFgwoWt+CUmbgK3vtaxmw6VZ835\/8lciQ1xCStEQYQeImxPDeaASzTSrUMybutKToYdBLHWVXbisOtOf09xJeh0vA3cnsaCwaWqcwAKEoZN7sNHwBDlw0E361y9dNkPwuU9X8Swt3V4XWGpQ1UTMpz60n1Uf77r8u1mR0gUMYd++cv7g8tLvzUNgNyLGL7CNwj2W5MYHP+WSY8\/ywHG0aL\/1YM2xGG88gi3UOug6tY6eymFURutU8qC6i3bA4nYKqvTqqSY58tkuQo0G54tC9J\/E\/f3rGlIaVDWvdGTFxFC5ZvZEOGiEAKjo=", "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" } \ No newline at end of file diff --git a/tests/lib/Repair/RepairMimeTypesTest.php b/tests/lib/Repair/RepairMimeTypesTest.php index b403f5879d362..0b1801131abc9 100644 --- a/tests/lib/Repair/RepairMimeTypesTest.php +++ b/tests/lib/Repair/RepairMimeTypesTest.php @@ -139,6 +139,22 @@ public function testRenameImageTypes(): void { $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); } + /** + * Test renaming AVIF images, which had no mapping and so were stored + * as whatever the content sniffer made of them, or as nothing at all + */ + public function testRenameAvifType(): void { + $currentMimeTypes = [ + ['test.avif', 'application/octet-stream'], + ]; + + $fixedMimeTypes = [ + ['test.avif', 'image/avif'], + ]; + + $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); + } + /** * Test renaming the richdocuments additional office mime types */