From 7fbf1a20d7365da4c7eaea3aff857a5d72ee13fb Mon Sep 17 00:00:00 2001 From: Olivier Paroz Date: Wed, 26 Nov 2014 19:58:59 +0100 Subject: [PATCH] Updated the media type of some font types TTF and TTF have now the same media type Official since 2013 and supported by Firefox and Chrome https://www.iana.org/assignments/media-types/application/font-sfnt Introducing support for Type1 fonts --- lib/private/helper.php | 3 +- lib/private/mimetypes.list.php | 5 +- lib/repair/repairmimetypes.php | 257 +++++++++++++++------------ tests/lib/repair/repairmimetypes.php | 105 +++++++++++ 4 files changed, 252 insertions(+), 118 deletions(-) diff --git a/lib/private/helper.php b/lib/private/helper.php index 6268bd3d42..c87eb63b66 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -40,7 +40,8 @@ class OC_Helper { 'application/x-gimp' => 'image', 'application/x-photoshop' => 'image', - 'application/x-font-ttf' => 'font', + 'application/font-sfnt' => 'font', + 'application/x-font' => 'font', 'application/font-woff' => 'font', 'application/vnd.ms-fontobject' => 'font', diff --git a/lib/private/mimetypes.list.php b/lib/private/mimetypes.list.php index 4f11829859..265fffa7db 100644 --- a/lib/private/mimetypes.list.php +++ b/lib/private/mimetypes.list.php @@ -104,9 +104,10 @@ return array( 'oga' => array('audio/ogg', null), 'ogg' => array('audio/ogg', null), 'ogv' => array('video/ogg', null), - 'otf' => array('font/opentype', null), + 'otf' => array('application/font-sfnt', null), 'pages' => array('application/x-iwork-pages-sffpages', null), 'pdf' => array('application/pdf', null), + 'pfb' => array('application/x-font', null), 'php' => array('application/x-php', null), 'pl' => array('application/x-perl', null), 'png' => array('image/png', null), @@ -137,7 +138,7 @@ return array( 'tgz' => array('application/x-compressed', null), 'tiff' => array('image/tiff', null), 'tif' => array('image/tiff', null), - 'ttf' => array('application/x-font-ttf', null), + 'ttf' => array('application/font-sfnt', null), 'txt' => array('text/plain', null), 'vcard' => array('text/vcard', null), 'vcf' => array('text/vcard', null), diff --git a/lib/repair/repairmimetypes.php b/lib/repair/repairmimetypes.php index e3f4402cfd..06cd144bff 100644 --- a/lib/repair/repairmimetypes.php +++ b/lib/repair/repairmimetypes.php @@ -2,6 +2,7 @@ /** * Copyright (c) 2014 Vincent Petry * Copyright (c) 2014 Jörn Dreyer jfd@owncloud.com + * Copyright (c) 2014 Olivier Paroz owncloud@oparoz.com * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. @@ -16,6 +17,102 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { public function getName() { return 'Repair mime types'; } + + private static function existsStmt() { + return \OC_DB::prepare(' + SELECT count(`mimetype`) + FROM `*PREFIX*mimetypes` + WHERE `mimetype` = ? + '); + } + + private static function getIdStmt() { + return \OC_DB::prepare(' + SELECT `id` + FROM `*PREFIX*mimetypes` + WHERE `mimetype` = ? + '); + } + + private static function insertStmt() { + return \OC_DB::prepare(' + INSERT INTO `*PREFIX*mimetypes` ( `mimetype` ) + VALUES ( ? ) + '); + } + + private static function updateWrongStmt() { + return \OC_DB::prepare(' + UPDATE `*PREFIX*filecache` + SET `mimetype` = ( + SELECT `id` + FROM `*PREFIX*mimetypes` + WHERE `mimetype` = ? + ) WHERE `mimetype` = ? + '); + } + + private static function deleteStmt() { + return \OC_DB::prepare(' + DELETE FROM `*PREFIX*mimetypes` + WHERE `id` = ? + '); + } + + private static function updateByNameStmt() { + return \OC_DB::prepare(' + UPDATE `*PREFIX*filecache` + SET `mimetype` = ( + SELECT `id` + FROM `*PREFIX*mimetypes` + WHERE `mimetype` = ? + ) WHERE `name` LIKE ? + '); + } + + private function repairMimetypes($wrongMimetypes) { + foreach ($wrongMimetypes as $wrong => $correct) { + // do we need to remove a wrong mimetype? + $result = \OC_DB::executeAudited(self::getIdStmt(), array($wrong)); + $wrongId = $result->fetchOne(); + + if ($wrongId !== false) { + // do we need to insert the correct mimetype? + $result = \OC_DB::executeAudited(self::existsStmt(), array($correct)); + $exists = $result->fetchOne(); + + if ( ! is_null($correct) ) { + if ( ! $exists ) { + // insert mimetype + \OC_DB::executeAudited(self::insertStmt(), array($correct)); + } + + // change wrong mimetype to correct mimetype in filecache + \OC_DB::executeAudited(self::updateWrongStmt(), array($correct, $wrongId)); + } + + // delete wrong mimetype + \OC_DB::executeAudited(self::deleteStmt(), array($wrongId)); + + } + } + } + + private function updateMimetypes($updatedMimetypes) { + + foreach ($updatedMimetypes as $extension => $mimetype ) { + $result = \OC_DB::executeAudited(self::existsStmt(), array($mimetype)); + $exists = $result->fetchOne(); + + if ( ! $exists ) { + // insert mimetype + \OC_DB::executeAudited(self::insertStmt(), array($mimetype)); + } + + // change mimetype for files with x extension + \OC_DB::executeAudited(self::updateByNameStmt(), array($mimetype, '%.'.$extension)); + } + } private function fixOfficeMimeTypes() { // update wrong mimetypes @@ -24,64 +121,7 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { 'application/msexcel' => 'application/vnd.ms-excel', ); - $existsStmt = \OC_DB::prepare(' - SELECT count(`mimetype`) - FROM `*PREFIX*mimetypes` - WHERE `mimetype` = ? - '); - - $getIdStmt = \OC_DB::prepare(' - SELECT `id` - FROM `*PREFIX*mimetypes` - WHERE `mimetype` = ? - '); - - $insertStmt = \OC_DB::prepare(' - INSERT INTO `*PREFIX*mimetypes` ( `mimetype` ) - VALUES ( ? ) - '); - - $updateWrongStmt = \OC_DB::prepare(' - UPDATE `*PREFIX*filecache` - SET `mimetype` = ( - SELECT `id` - FROM `*PREFIX*mimetypes` - WHERE `mimetype` = ? - ) WHERE `mimetype` = ? - '); - - $deleteStmt = \OC_DB::prepare(' - DELETE FROM `*PREFIX*mimetypes` - WHERE `id` = ? - '); - - foreach ($wrongMimetypes as $wrong => $correct) { - - - // do we need to remove a wrong mimetype? - $result = \OC_DB::executeAudited($getIdStmt, array($wrong)); - $wrongId = $result->fetchOne(); - - if ($wrongId !== false) { - - // do we need to insert the correct mimetype? - $result = \OC_DB::executeAudited($existsStmt, array($correct)); - $exists = $result->fetchOne(); - - if ( ! $exists ) { - // insert mimetype - \OC_DB::executeAudited($insertStmt, array($correct)); - } - - // change wrong mimetype to correct mimetype in filecache - \OC_DB::executeAudited($updateWrongStmt, array($correct, $wrongId)); - - // delete wrong mimetype - \OC_DB::executeAudited($deleteStmt, array($wrongId)); - - } - - } + self::repairMimetypes($wrongMimetypes); $updatedMimetypes = array( 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', @@ -89,66 +129,46 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', ); - $updateByNameStmt = \OC_DB::prepare(' - UPDATE `*PREFIX*filecache` - SET `mimetype` = ( - SELECT `id` - FROM `*PREFIX*mimetypes` - WHERE `mimetype` = ? - ) WHERE `name` LIKE ? - '); // separate doc from docx etc - foreach ($updatedMimetypes as $extension => $mimetype ) { - $result = \OC_DB::executeAudited($existsStmt, array($mimetype)); - $exists = $result->fetchOne(); - - if ( ! $exists ) { - // insert mimetype - \OC_DB::executeAudited($insertStmt, array($mimetype)); - } - - // change mimetype for files with x extension - \OC_DB::executeAudited($updateByNameStmt, array($mimetype, '%.'.$extension)); - } + self::updateMimetypes($updatedMimetypes); + } + + private function fixApkMimeType() { + $updatedMimetypes = array( + 'apk' => 'application/vnd.android.package-archive', + ); - private function fixAPKMimeType() { - $existsStmt = \OC_DB::prepare(' - SELECT count(`mimetype`) - FROM `*PREFIX*mimetypes` - WHERE `mimetype` = ? - '); + self::updateMimetypes($updatedMimetypes); + } + + private function fixFontsMimeTypes() { + // update wrong mimetypes + $wrongMimetypes = array( + 'font' => null, + 'font/opentype' => 'application/font-sfnt', + 'application/x-font-ttf' => 'application/font-sfnt', + ); - $insertStmt = \OC_DB::prepare(' - INSERT INTO `*PREFIX*mimetypes` ( `mimetype` ) - VALUES ( ? ) - '); + self::repairMimetypes($wrongMimetypes); + + $updatedMimetypes = array( + 'ttf' => 'application/font-sfnt', + 'otf' => 'application/font-sfnt', + 'pfb' => 'application/x-font', + ); + self::updateMimetypes($updatedMimetypes); + } + + private function fixPostscriptMimeType() { + $updatedMimetypes = array( + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + ); - $updateByNameStmt = \OC_DB::prepare(' - UPDATE `*PREFIX*filecache` - SET `mimetype` = ( - SELECT `id` - FROM `*PREFIX*mimetypes` - WHERE `mimetype` = ? - ) WHERE `name` LIKE ? - '); - - - $mimeTypeExtension = 'apk'; - $mimeTypeName = 'application/vnd.android.package-archive'; - - $result = \OC_DB::executeAudited($existsStmt, array($mimeTypeName)); - $exists = $result->fetchOne(); - - if ( ! $exists ) { - // insert mimetype - \OC_DB::executeAudited($insertStmt, array($mimeTypeName)); - } - - // change mimetype for files with x extension - \OC_DB::executeAudited($updateByNameStmt, array($mimeTypeName, '%.'.$mimeTypeExtension)); + self::updateMimetypes($updatedMimetypes); } /** @@ -158,10 +178,17 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { if ($this->fixOfficeMimeTypes()) { $this->emit('\OC\Repair', 'info', array('Fixed office mime types')); } - - if ($this->fixAPKMimeType()) { + + if ($this->fixApkMimeType()) { $this->emit('\OC\Repair', 'info', array('Fixed APK mime type')); } + + if ($this->fixFontsMimeTypes()) { + $this->emit('\OC\Repair', 'info', array('Fixed fonts mime types')); + } + + if ($this->fixPostscriptMimeType()) { + $this->emit('\OC\Repair', 'info', array('Fixed Postscript mime types')); + } } -} - +} \ No newline at end of file diff --git a/tests/lib/repair/repairmimetypes.php b/tests/lib/repair/repairmimetypes.php index 6eaf68d8a4..403474957f 100644 --- a/tests/lib/repair/repairmimetypes.php +++ b/tests/lib/repair/repairmimetypes.php @@ -1,6 +1,7 @@ + * Copyright (c) 2014 Olivier Paroz owncloud@oparoz.com * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. @@ -110,6 +111,33 @@ class TestRepairMimeTypes extends \Test\TestCase { ) ); } + + /** + * Test renaming old fonts mime types + */ + public function testRenameFontsMimeTypes() { + $this->addEntries( + array( + array('test.ttf', 'application/x-font-ttf'), + array('test.otf', 'font/opentype'), + array('test.pfb', 'application/octet-stream'), + ) + ); + + $this->repair->run(); + + // force mimetype reload + DummyFileCache::clearCachedMimeTypes(); + $this->storage->getCache()->loadMimeTypes(); + + $this->checkEntries( + array( + array('test.ttf', 'application/font-sfnt'), + array('test.otf', 'application/font-sfnt'), + array('test.pfb', 'application/x-font'), + ) + ); + } /** * Test renaming the APK mime type @@ -137,6 +165,31 @@ class TestRepairMimeTypes extends \Test\TestCase { ) ); } + + /** + * Test renaming the postscript mime types + */ + public function testRenamePostscriptMimeType() { + $this->addEntries( + array( + array('test.eps', 'application/octet-stream'), + array('test.ps', 'application/octet-stream'), + ) + ); + + $this->repair->run(); + + // force mimetype reload + DummyFileCache::clearCachedMimeTypes(); + $this->storage->getCache()->loadMimeTypes(); + + $this->checkEntries( + array( + array('test.eps', 'application/postscript'), + array('test.ps', 'application/postscript'), + ) + ); + } /** * Test renaming and splitting old office mime types when @@ -188,6 +241,46 @@ class TestRepairMimeTypes extends \Test\TestCase { $this->assertNull($this->getMimeTypeIdFromDB('application/msexcel')); $this->assertNull($this->getMimeTypeIdFromDB('application/mspowerpoint')); } + + /** + * Test renaming old fonts mime types when + * new ones already exist + */ + public function testRenameFontsMimeTypesWhenExist() { + $this->addEntries( + array( + array('test.ttf', 'application/x-font-ttf'), + array('test.otf', 'font/opentype'), + // make it so that the new mimetypes already exist + array('bogus.ttf', 'application/font-sfnt'), + array('bogus.otf', 'application/font-sfnt'), + array('bogus2.ttf', 'application/wrong'), + array('bogus2.otf', 'application/wrong'), + ) + ); + + $this->repair->run(); + + // force mimetype reload + DummyFileCache::clearCachedMimeTypes(); + $this->storage->getCache()->loadMimeTypes(); + + $this->checkEntries( + array( + array('test.ttf', 'application/font-sfnt'), + array('test.otf', 'application/font-sfnt'), + array('bogus.ttf', 'application/font-sfnt'), + array('bogus.otf', 'application/font-sfnt'), + array('bogus2.ttf', 'application/font-sfnt'), + array('bogus2.otf', 'application/font-sfnt'), + ) + ); + + // wrong mimetypes are gone + $this->assertNull($this->getMimeTypeIdFromDB('application/x-font-ttf')); + $this->assertNull($this->getMimeTypeIdFromDB('font')); + $this->assertNull($this->getMimeTypeIdFromDB('font/opentype')); + } /** * Test that nothing happens and no error happens when all mimetypes are @@ -202,6 +295,12 @@ class TestRepairMimeTypes extends \Test\TestCase { array('test.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'), array('test.ppt', 'application/vnd.ms-powerpoint'), array('test.pptx', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'), + array('test.apk', 'application/vnd.android.package-archive'), + array('test.ttf', 'application/font-sfnt'), + array('test.otf', 'application/font-sfnt'), + array('test.pfb', 'application/x-font'), + array('test.eps', 'application/postscript'), + array('test.ps', 'application/postscript'), ) ); @@ -219,6 +318,12 @@ class TestRepairMimeTypes extends \Test\TestCase { array('test.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'), array('test.ppt', 'application/vnd.ms-powerpoint'), array('test.pptx', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'), + array('test.apk', 'application/vnd.android.package-archive'), + array('test.ttf', 'application/font-sfnt'), + array('test.otf', 'application/font-sfnt'), + array('test.pfb', 'application/x-font'), + array('test.eps', 'application/postscript'), + array('test.ps', 'application/postscript'), ) ); }