From 789d49359510f10c68be61eaa56d77b3ab428328 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 23 Oct 2013 18:34:06 +0200 Subject: [PATCH 01/20] [ticket/11912] Integrate mimetype guesser with plupload PHPBB3-11912 --- phpBB/config/mimetype_guessers.yml | 22 ++++++++++++++++++++++ phpBB/config/services.yml | 2 ++ phpBB/phpbb/plupload/plupload.php | 11 +++++++++-- 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 phpBB/config/mimetype_guessers.yml diff --git a/phpBB/config/mimetype_guessers.yml b/phpBB/config/mimetype_guessers.yml new file mode 100644 index 0000000000..1b5cdee97d --- /dev/null +++ b/phpBB/config/mimetype_guessers.yml @@ -0,0 +1,22 @@ +services: + mimetype.FileinfoMimeTypeGuesser: + class: Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser + tags: + - { name: mimetype.guessers } + + mimetype.FileBinaryMimeTypeGuesser: + class: Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser + tags: + - { name: mimetype.guessers } + + mimetype.guesser_collection: + class: phpbb\di\service_collection + arguments: + - @service_container + tags: + - { name: service_collection, tag: mimetype.guessers } + + mimetype.guesser: + class: phpbb\mimetype\guesser + arguments: + - @mimetype.guesser_collection diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index c6490a21d7..09fcb5dc8f 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -6,6 +6,7 @@ imports: - { resource: avatars.yml } - { resource: feed.yml } - { resource: auth_providers.yml } + - { resource: mimetype_guessers.yml } services: acl.permissions: @@ -266,6 +267,7 @@ services: - @request - @user - @php_ini + - @mimetype.guesser request: class: phpbb\request\request diff --git a/phpBB/phpbb/plupload/plupload.php b/phpBB/phpbb/plupload/plupload.php index 6eb5adf864..29a4aff39b 100644 --- a/phpBB/phpbb/plupload/plupload.php +++ b/phpBB/phpbb/plupload/plupload.php @@ -49,6 +49,11 @@ class plupload */ protected $php_ini; + /** + * @var \phpbb\mimetype\guesser + */ + protected $mimetype_guesser; + /** * Final destination for uploaded files, i.e. the "files" directory. * @var string @@ -69,16 +74,18 @@ class plupload * @param \phpbb\request\request_interface $request * @param \phpbb\user $user * @param \phpbb\php\ini $php_ini + * @param \phpbb\mimetype\guesser $mimetype_guesser * * @return null */ - public function __construct($phpbb_root_path, \phpbb\config\config $config, \phpbb\request\request_interface $request, \phpbb\user $user, \phpbb\php\ini $php_ini) + public function __construct($phpbb_root_path, \phpbb\config\config $config, \phpbb\request\request_interface $request, \phpbb\user $user, \phpbb\php\ini $php_ini, \phpbb\mimetype\guesser $mimetype_guesser) { $this->phpbb_root_path = $phpbb_root_path; $this->config = $config; $this->request = $request; $this->user = $user; $this->php_ini = $php_ini; + $this->mimetype_guesser = $mimetype_guesser; $this->upload_directory = $this->phpbb_root_path . $this->config['upload_path']; $this->temporary_directory = $this->upload_directory . '/plupload'; @@ -128,7 +135,7 @@ class plupload 'tmp_name' => $file_path, 'name' => $this->request->variable('real_filename', ''), 'size' => filesize($file_path), - 'type' => $file_info->getMimeType($file_path), + 'type' => $this->mimetype_guesser->guess($file_path), ); } else From 36d314e032757fc8d86f8f0daddc596e0e95ca8e Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 23 Oct 2013 18:34:35 +0200 Subject: [PATCH 02/20] [ticket/11912] Add phpbb mimetype guesser Mimetype guesser will be used as front-end file for mimetype guessing. PHPBB3-11912 --- phpBB/phpbb/mimetype/guesser.php | 105 +++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 phpBB/phpbb/mimetype/guesser.php diff --git a/phpBB/phpbb/mimetype/guesser.php b/phpBB/phpbb/mimetype/guesser.php new file mode 100644 index 0000000000..5ae094cd63 --- /dev/null +++ b/phpBB/phpbb/mimetype/guesser.php @@ -0,0 +1,105 @@ +register_guessers($mimetype_guessers); + } + + /** + * Register MimeTypeGuessers + * + * @param array $mimetype_guessers Mimetype guesser service collection + * + * @throws \LogicException If incorrect or not mimetype guessers have + * been supplied to class + */ + protected function register_guessers($mimetype_guessers) + { + foreach ($mimetype_guessers as $guesser) + { + $is_supported = (method_exists($guesser, 'is_supported')) ? 'is_supported' : ''; + $is_supported = (method_exists($guesser, 'isSupported')) ? 'isSupported' : $is_supported; + + if (empty($is_supported)) + { + throw new \LogicException('Incorrect mimetype guesser supplied.'); + } + + if ($guesser->$is_supported()) + { + $this->guessers[] = $guesser; + } + } + + if (empty($this->guessers)) + { + throw new \LogicException('No mimetype guesser supplied.'); + } + } + + /** + * Guess mimetype of supplied file + * + * @param string $file Path to file + * + * @return string Guess for mimetype of file + */ + public function guess($file) + { + if (!is_file($file)) + { + return false; + } + + if (!is_readable($file)) + { + return false; + } + + foreach ($this->guessers as $guesser) + { + $mimetype = $guesser->guess($file); + + // Try to guess something that is not the fallback application/octet-stream + if ($mimetype !== null && $mimetype !== 'application/octet-stream') + { + return $mimetype; + } + } + // Return any mimetype if we got a result or the fallback value + return (!empty($mimetype)) ? $mimetype : 'application/octet-stream'; + } +} From c8040024cb9c1d28b669568789c5dfacc0941f54 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 23 Oct 2013 18:36:11 +0200 Subject: [PATCH 03/20] [ticket/11912] Add tests for phpbb mimetype guesser PHPBB3-11912 --- tests/mimetype/fixtures/jpg | Bin 0 -> 519 bytes tests/mimetype/guesser_test.php | 83 +++++++++++++++++++++++++++ tests/mimetype/incorrect_guesser.php | 18 ++++++ tests/mimetype/null_guesser.php | 30 ++++++++++ 4 files changed, 131 insertions(+) create mode 100644 tests/mimetype/fixtures/jpg create mode 100644 tests/mimetype/guesser_test.php create mode 100644 tests/mimetype/incorrect_guesser.php create mode 100644 tests/mimetype/null_guesser.php diff --git a/tests/mimetype/fixtures/jpg b/tests/mimetype/fixtures/jpg new file mode 100644 index 0000000000000000000000000000000000000000..3cd5038e38a45d49127638da67a2faaa551fd32f GIT binary patch literal 519 zcmbu4yA1+C3`A#afi58MN>BhavH{WwXzE&_7DN$z5;`$nP9X8QB{(~?o;}Zg@*8Z| zZd;JVCK`Ul8a}q-2*=*=15yKm$`vG06a9!qsN%gO#`CW!{DPShVrl^QU7_rAw@^*& rav~2P{RWiGtO4=@1|z1qj~E1)m)%nu8b6vA=Zcd3Q|f_AVgTnmym`8t literal 0 HcmV?d00001 diff --git a/tests/mimetype/guesser_test.php b/tests/mimetype/guesser_test.php new file mode 100644 index 0000000000..3728961460 --- /dev/null +++ b/tests/mimetype/guesser_test.php @@ -0,0 +1,83 @@ +guesser = new \phpbb\mimetype\guesser($guessers); + $this->path = dirname(__FILE__); + $this->jpg_file = $this->path . '/fixtures/jpg'; + } + + public function data_guess_files() + { + return array( + array('image/gif', 'gif'), + array('image/png', 'png'), + array('image/jpeg', 'jpg'), + array('image/tiff', 'tif'), + array('text/html', 'txt'), + array(false, 'foobar'), + ); + } + + /** + * @dataProvider data_guess_files + */ + public function test_guess_files($expected, $file) + { + $this->assertEquals($expected, $this->guesser->guess($this->path . '/../upload/fixture/' . $file)); + } + + public function test_file_not_readable() + { + @chmod($this->jpg_file, 0000); + if (is_readable($this->jpg_file)) + { + @chmod($this->jpg_file, 0644); + $this->markTestSkipped('is_readable always returns true if user is superuser or chmod does not work'); + } + $this->assertEquals(false, $this->guesser->guess($this->jpg_file)); + @chmod($this->jpg_file, 0644); + $this->assertEquals('image/jpeg', $this->guesser->guess($this->jpg_file)); + } + + public function test_null_guess() + { + $guesser = new \phpbb\mimetype\guesser(array(new \phpbb\mimetype\null_guesser)); + $this->assertEquals('application/octet-stream', $guesser->guess($this->jpg_file)); + } + + public function data_incorrect_guessers() + { + return array( + array(array(new \phpbb\mimetype\incorrect_guesser)), + array(array(new \phpbb\mimetype\null_guesser(false))), + array(array()), + ); + } + + /** + * @dataProvider data_incorrect_guessers + * + * @expectedException \LogicException + */ + public function test_incorrect_guesser($guessers) + { + $guesser = new \phpbb\mimetype\guesser($guessers); + } +} diff --git a/tests/mimetype/incorrect_guesser.php b/tests/mimetype/incorrect_guesser.php new file mode 100644 index 0000000000..3939826faa --- /dev/null +++ b/tests/mimetype/incorrect_guesser.php @@ -0,0 +1,18 @@ +is_supported = $is_supported; + } + + public function is_supported() + { + return $this->is_supported; + } + + public function guess($file) + { + return null; + } +} From 63945f3687f57fc341c6c28c7b8940805efa99b7 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 23 Oct 2013 23:11:33 +0200 Subject: [PATCH 04/20] [ticket/11912] Add content_guesser The content_guesser will try to use the function mime_content_type() if it's available. If that is not the case, the content_guesser will try to guess the mimetype using the file extension of the supplied file. Since this guesser will be registered after the other guessers, it will be only used if the other guessers are not available. PHPBB3-11912 --- phpBB/config/mimetype_guessers.yml | 8 + phpBB/phpbb/mimetype/content_guesser.php | 548 +++++++++++++++++++++++ 2 files changed, 556 insertions(+) create mode 100644 phpBB/phpbb/mimetype/content_guesser.php diff --git a/phpBB/config/mimetype_guessers.yml b/phpBB/config/mimetype_guessers.yml index 1b5cdee97d..c19fb85254 100644 --- a/phpBB/config/mimetype_guessers.yml +++ b/phpBB/config/mimetype_guessers.yml @@ -9,6 +9,14 @@ services: tags: - { name: mimetype.guessers } + mimetype.content_guesser: + class: phpbb\mimetype\content_guesser + arguments: + - %core.root_path% + - @php_ini + tags: + - { name: mimetype.guessers } + mimetype.guesser_collection: class: phpbb\di\service_collection arguments: diff --git a/phpBB/phpbb/mimetype/content_guesser.php b/phpBB/phpbb/mimetype/content_guesser.php new file mode 100644 index 0000000000..4eeac75499 --- /dev/null +++ b/phpBB/phpbb/mimetype/content_guesser.php @@ -0,0 +1,548 @@ + 'x-world/x-3dmf', + '3dmf' => 'x-world/x-3dmf', + 'a' => 'application/octet-stream', + 'aab' => 'application/x-authorware-bin', + 'aam' => 'application/x-authorware-map', + 'aas' => 'application/x-authorware-seg', + 'abc' => 'text/vnd.abc', + 'acgi' => 'text/html', + 'afl' => 'video/animaflex', + 'ai' => 'application/postscript', + 'aif' => 'audio/aiff', + 'aifc' => 'audio/aiff', + 'aiff' => 'audio/aiff', + 'aim' => 'application/x-aim', + 'aip' => 'text/x-audiosoft-intra', + 'ani' => 'application/x-navi-animation', + 'aos' => 'application/x-nokia-9000-communicator-add-on-software', + 'aps' => 'application/mime', + 'arc' => 'application/octet-stream', + 'arj' => 'application/arj', + 'art' => 'image/x-jg', + 'asf' => 'video/x-ms-asf', + 'asm' => 'text/x-asm', + 'asp' => 'text/asp', + 'asx' => 'application/x-mplayer2', + 'au' => 'audio/basic', + 'avi' => 'application/x-troff-msvideo', + 'avs' => 'video/avs-video', + 'bcpio' => 'application/x-bcpio', + 'bin' => 'application/mac-binary', + 'bm' => 'image/bmp', + 'bmp' => 'image/bmp', + 'boo' => 'application/book', + 'book' => 'application/book', + 'boz' => 'application/x-bzip2', + 'bsh' => 'application/x-bsh', + 'bz' => 'application/x-bzip', + 'bz2' => 'application/x-bzip2', + 'c' => 'text/plain', + 'c++' => 'text/plain', + 'cat' => 'application/vnd.ms-pki.seccat', + 'cc' => 'text/plain', + 'ccad' => 'application/clariscad', + 'cco' => 'application/x-cocoa', + 'cdf' => 'application/cdf', + 'cer' => 'application/pkix-cert', + 'cha' => 'application/x-chat', + 'chat' => 'application/x-chat', + 'class' => 'application/java', + 'com' => 'application/octet-stream', + 'conf' => 'text/plain', + 'cpio' => 'application/x-cpio', + 'cpp' => 'text/x-c', + 'cpt' => 'application/mac-compactpro', + 'crl' => 'application/pkcs-crl', + 'crt' => 'application/pkix-cert', + 'csh' => 'application/x-csh', + 'css' => 'application/x-pointplus', + 'cxx' => 'text/plain', + 'dcr' => 'application/x-director', + 'deepv' => 'application/x-deepv', + 'def' => 'text/plain', + 'der' => 'application/x-x509-ca-cert', + 'dif' => 'video/x-dv', + 'dir' => 'application/x-director', + 'dl' => 'video/dl', + 'doc' => 'application/msword', + 'dot' => 'application/msword', + 'dp' => 'application/commonground', + 'drw' => 'application/drafting', + 'dump' => 'application/octet-stream', + 'dv' => 'video/x-dv', + 'dvi' => 'application/x-dvi', + 'dwf' => 'drawing/x-dwf (old)', + 'dwg' => 'application/acad', + 'dxf' => 'application/dxf', + 'dxr' => 'application/x-director', + 'el' => 'text/x-script.elisp', + 'elc' => 'application/x-bytecode.elisp (compiled elisp)', + 'env' => 'application/x-envoy', + 'eps' => 'application/postscript', + 'es' => 'application/x-esrehber', + 'etx' => 'text/x-setext', + 'evy' => 'application/envoy', + 'exe' => 'application/octet-stream', + 'f' => 'text/plain', + 'f77' => 'text/x-fortran', + 'f90' => 'text/plain', + 'fdf' => 'application/vnd.fdf', + 'fif' => 'application/fractals', + 'fli' => 'video/fli', + 'flo' => 'image/florian', + 'flx' => 'text/vnd.fmi.flexstor', + 'fmf' => 'video/x-atomic3d-feature', + 'for' => 'text/plain', + 'fpx' => 'image/vnd.fpx', + 'frl' => 'application/freeloader', + 'funk' => 'audio/make', + 'g' => 'text/plain', + 'g3' => 'image/g3fax', + 'gif' => 'image/gif', + 'gl' => 'video/gl', + 'gsd' => 'audio/x-gsm', + 'gsm' => 'audio/x-gsm', + 'gsp' => 'application/x-gsp', + 'gss' => 'application/x-gss', + 'gtar' => 'application/x-gtar', + 'gz' => 'application/x-compressed', + 'gzip' => 'application/x-gzip', + 'h' => 'text/plain', + 'hdf' => 'application/x-hdf', + 'help' => 'application/x-helpfile', + 'hgl' => 'application/vnd.hp-hpgl', + 'hh' => 'text/plain', + 'hlb' => 'text/x-script', + 'hlp' => 'application/hlp', + 'hpg' => 'application/vnd.hp-hpgl', + 'hpgl' => 'application/vnd.hp-hpgl', + 'hqx' => 'application/binhex', + 'hta' => 'application/hta', + 'htc' => 'text/x-component', + 'htm' => 'text/html', + 'html' => 'text/html', + 'htmls' => 'text/html', + 'htt' => 'text/webviewhtml', + 'htx' => 'text/html', + 'ice' => 'x-conference/x-cooltalk', + 'ico' => 'image/x-icon', + 'idc' => 'text/plain', + 'ief' => 'image/ief', + 'iefs' => 'image/ief', + 'iges' => 'application/iges', + 'igs' => 'application/iges', + 'ima' => 'application/x-ima', + 'imap' => 'application/x-httpd-imap', + 'inf' => 'application/inf', + 'ins' => 'application/x-internett-signup', + 'ip' => 'application/x-ip2', + 'isu' => 'video/x-isvideo', + 'it' => 'audio/it', + 'iv' => 'application/x-inventor', + 'ivr' => 'i-world/i-vrml', + 'ivy' => 'application/x-livescreen', + 'jam' => 'audio/x-jam', + 'jav' => 'text/plain', + 'java' => 'text/plain', + 'jcm' => 'application/x-java-commerce', + 'jfif' => 'image/jpeg', + 'jfif-tbnl' => 'image/jpeg', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'jps' => 'image/x-jps', + 'js' => 'application/x-javascript', + 'jut' => 'image/jutvision', + 'kar' => 'audio/midi', + 'ksh' => 'application/x-ksh', + 'la' => 'audio/nspaudio', + 'lam' => 'audio/x-liveaudio', + 'latex' => 'application/x-latex', + 'lha' => 'application/lha', + 'lhx' => 'application/octet-stream', + 'list' => 'text/plain', + 'lma' => 'audio/nspaudio', + 'log' => 'text/plain', + 'lsp' => 'application/x-lisp', + 'lst' => 'text/plain', + 'lsx' => 'text/x-la-asf', + 'ltx' => 'application/x-latex', + 'lzh' => 'application/octet-stream', + 'lzx' => 'application/lzx', + 'm' => 'text/plain', + 'm1v' => 'video/mpeg', + 'm2a' => 'audio/mpeg', + 'm2v' => 'video/mpeg', + 'm3u' => 'audio/x-mpequrl', + 'man' => 'application/x-troff-man', + 'map' => 'application/x-navimap', + 'mar' => 'text/plain', + 'mbd' => 'application/mbedlet', + 'mc$' => 'application/x-magic-cap-package-1.0', + 'mcd' => 'application/mcad', + 'mcf' => 'image/vasa', + 'mcp' => 'application/netmc', + 'me' => 'application/x-troff-me', + 'mht' => 'message/rfc822', + 'mhtml' => 'message/rfc822', + 'mid' => 'application/x-midi', + 'midi' => 'application/x-midi', + 'mif' => 'application/x-frame', + 'mime' => 'message/rfc822', + 'mjf' => 'audio/x-vnd.audioexplosion.mjuicemediafile', + 'mjpg' => 'video/x-motion-jpeg', + 'mm' => 'application/base64', + 'mme' => 'application/base64', + 'mod' => 'audio/mod', + 'moov' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'movie' => 'video/x-sgi-movie', + 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg3', + 'mpa' => 'audio/mpeg', + 'mpc' => 'application/x-project', + 'mpe' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpg' => 'audio/mpeg', + 'mpga' => 'audio/mpeg', + 'mpp' => 'application/vnd.ms-project', + 'mpt' => 'application/x-project', + 'mpv' => 'application/x-project', + 'mpx' => 'application/x-project', + 'mrc' => 'application/marc', + 'ms' => 'application/x-troff-ms', + 'mv' => 'video/x-sgi-movie', + 'my' => 'audio/make', + 'mzz' => 'application/x-vnd.audioexplosion.mzz', + 'nap' => 'image/naplps', + 'naplps' => 'image/naplps', + 'nc' => 'application/x-netcdf', + 'ncm' => 'application/vnd.nokia.configuration-message', + 'nif' => 'image/x-niff', + 'niff' => 'image/x-niff', + 'nix' => 'application/x-mix-transfer', + 'nsc' => 'application/x-conference', + 'nvd' => 'application/x-navidoc', + 'o' => 'application/octet-stream', + 'oda' => 'application/oda', + 'omc' => 'application/x-omc', + 'omcd' => 'application/x-omcdatamaker', + 'omcr' => 'application/x-omcregerator', + 'p' => 'text/x-pascal', + 'p10' => 'application/pkcs10', + 'p12' => 'application/pkcs-12', + 'p7a' => 'application/x-pkcs7-signature', + 'p7c' => 'application/pkcs7-mime', + 'p7m' => 'application/pkcs7-mime', + 'p7r' => 'application/x-pkcs7-certreqresp', + 'p7s' => 'application/pkcs7-signature', + 'part' => 'application/pro_eng', + 'pas' => 'text/pascal', + 'pbm' => 'image/x-portable-bitmap', + 'pcl' => 'application/vnd.hp-pcl', + 'pct' => 'image/x-pict', + 'pcx' => 'image/x-pcx', + 'pdb' => 'chemical/x-pdb', + 'pdf' => 'application/pdf', + 'pfunk' => 'audio/make', + 'pgm' => 'image/x-portable-graymap', + 'pic' => 'image/pict', + 'pict' => 'image/pict', + 'pkg' => 'application/x-newton-compatible-pkg', + 'pko' => 'application/vnd.ms-pki.pko', + 'pl' => 'text/plain', + 'plx' => 'application/x-pixclscript', + 'pm' => 'image/x-xpixmap', + 'pm4' => 'application/x-pagemaker', + 'pm5' => 'application/x-pagemaker', + 'png' => 'image/png', + 'pnm' => 'application/x-portable-anymap', + 'pot' => 'application/mspowerpoint', + 'pov' => 'model/x-pov', + 'ppa' => 'application/vnd.ms-powerpoint', + 'ppm' => 'image/x-portable-pixmap', + 'pps' => 'application/mspowerpoint', + 'ppt' => 'application/mspowerpoint', + 'ppz' => 'application/mspowerpoint', + 'pre' => 'application/x-freelance', + 'prt' => 'application/pro_eng', + 'ps' => 'application/postscript', + 'psd' => 'application/octet-stream', + 'pvu' => 'paleovu/x-pv', + 'pwz' => 'application/vnd.ms-powerpoint', + 'py' => 'text/x-script.phyton', + 'pyc' => 'applicaiton/x-bytecode.python', + 'qcp' => 'audio/vnd.qcelp', + 'qd3' => 'x-world/x-3dmf', + 'qd3d' => 'x-world/x-3dmf', + 'qif' => 'image/x-quicktime', + 'qt' => 'video/quicktime', + 'qtc' => 'video/x-qtc', + 'qti' => 'image/x-quicktime', + 'qtif' => 'image/x-quicktime', + 'ra' => 'audio/x-pn-realaudio', + 'ram' => 'audio/x-pn-realaudio', + 'ras' => 'application/x-cmu-raster', + 'rast' => 'image/cmu-raster', + 'rexx' => 'text/x-script.rexx', + 'rf' => 'image/vnd.rn-realflash', + 'rgb' => 'image/x-rgb', + 'rm' => 'application/vnd.rn-realmedia', + 'rmi' => 'audio/mid', + 'rmm' => 'audio/x-pn-realaudio', + 'rmp' => 'audio/x-pn-realaudio', + 'rng' => 'application/ringing-tones', + 'rnx' => 'application/vnd.rn-realplayer', + 'roff' => 'application/x-troff', + 'rp' => 'image/vnd.rn-realpix', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'rt' => 'text/richtext', + 'rtf' => 'application/rtf', + 'rtx' => 'application/rtf', + 'rv' => 'video/vnd.rn-realvideo', + 's' => 'text/x-asm', + 's3m' => 'audio/s3m', + 'saveme' => 'application/octet-stream', + 'sbk' => 'application/x-tbook', + 'scm' => 'application/x-lotusscreencam', + 'sdml' => 'text/plain', + 'sdp' => 'application/sdp', + 'sdr' => 'application/sounder', + 'sea' => 'application/sea', + 'set' => 'application/set', + 'sgm' => 'text/sgml', + 'sgml' => 'text/sgml', + 'sh' => 'application/x-bsh', + 'shar' => 'application/x-bsh', + 'shtml' => 'text/html', + 'sid' => 'audio/x-psid', + 'sit' => 'application/x-sit', + 'skd' => 'application/x-koan', + 'skm' => 'application/x-koan', + 'skp' => 'application/x-koan', + 'skt' => 'application/x-koan', + 'sl' => 'application/x-seelogo', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'snd' => 'audio/basic', + 'sol' => 'application/solids', + 'spc' => 'application/x-pkcs7-certificates', + 'spl' => 'application/futuresplash', + 'spr' => 'application/x-sprite', + 'sprite' => 'application/x-sprite', + 'src' => 'application/x-wais-source', + 'ssi' => 'text/x-server-parsed-html', + 'ssm' => 'application/streamingmedia', + 'sst' => 'application/vnd.ms-pki.certstore', + 'step' => 'application/step', + 'stl' => 'application/sla', + 'stp' => 'application/step', + 'sv4cpio' => 'application/x-sv4cpio', + 'sv4crc' => 'application/x-sv4crc', + 'svf' => 'image/vnd.dwg', + 'svr' => 'application/x-world', + 'swf' => 'application/x-shockwave-flash', + 't' => 'application/x-troff', + 'talk' => 'text/x-speech', + 'tar' => 'application/x-tar', + 'tbk' => 'application/toolbook', + 'tcl' => 'application/x-tcl', + 'tcsh' => 'text/x-script.tcsh', + 'tex' => 'application/x-tex', + 'texi' => 'application/x-texinfo', + 'texinfo' => 'application/x-texinfo', + 'text' => 'application/plain', + 'tgz' => 'application/gnutar', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'tr' => 'application/x-troff', + 'tsi' => 'audio/tsp-audio', + 'tsp' => 'application/dsptype', + 'tsv' => 'text/tab-separated-values', + 'turbot' => 'image/florian', + 'txt' => 'text/plain', + 'uil' => 'text/x-uil', + 'uni' => 'text/uri-list', + 'unis' => 'text/uri-list', + 'unv' => 'application/i-deas', + 'uri' => 'text/uri-list', + 'uris' => 'text/uri-list', + 'ustar' => 'application/x-ustar', + 'uu' => 'application/octet-stream', + 'uue' => 'text/x-uuencode', + 'vcd' => 'application/x-cdlink', + 'vcs' => 'text/x-vcalendar', + 'vda' => 'application/vda', + 'vdo' => 'video/vdo', + 'vew' => 'application/groupwise', + 'viv' => 'video/vivo', + 'vivo' => 'video/vivo', + 'vmd' => 'application/vocaltec-media-desc', + 'vmf' => 'application/vocaltec-media-file', + 'voc' => 'audio/voc', + 'vos' => 'video/vosaic', + 'vox' => 'audio/voxware', + 'vqe' => 'audio/x-twinvq-plugin', + 'vqf' => 'audio/x-twinvq', + 'vql' => 'audio/x-twinvq-plugin', + 'vrml' => 'application/x-vrml', + 'vrt' => 'x-world/x-vrt', + 'vsd' => 'application/x-visio', + 'vst' => 'application/x-visio', + 'vsw' => 'application/x-visio', + 'w60' => 'application/wordperfect6.0', + 'w61' => 'application/wordperfect6.1', + 'w6w' => 'application/msword', + 'wav' => 'audio/wav', + 'wb1' => 'application/x-qpro', + 'wbmp' => 'image/vnd.wap.wbmp', + 'web' => 'application/vnd.xara', + 'wiz' => 'application/msword', + 'wk1' => 'application/x-123', + 'wmf' => 'windows/metafile', + 'wml' => 'text/vnd.wap.wml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'wmls' => 'text/vnd.wap.wmlscript', + 'wmlsc' => 'application/vnd.wap.wmlscriptc', + 'word' => 'application/msword', + 'wp' => 'application/wordperfect', + 'wp5' => 'application/wordperfect', + 'wp6' => 'application/wordperfect', + 'wpd' => 'application/wordperfect', + 'wq1' => 'application/x-lotus', + 'wri' => 'application/mswrite', + 'wrl' => 'application/x-world', + 'wrz' => 'model/vrml', + 'wsc' => 'text/scriplet', + 'wsrc' => 'application/x-wais-source', + 'wtk' => 'application/x-wintalk', + 'xbm' => 'image/x-xbitmap', + 'xdr' => 'video/x-amt-demorun', + 'xgz' => 'xgl/drawing', + 'xif' => 'image/vnd.xiff', + 'xl' => 'application/excel', + 'xla' => 'application/excel', + 'xlb' => 'application/excel', + 'xlc' => 'application/excel', + 'xld' => 'application/excel', + 'xlk' => 'application/excel', + 'xll' => 'application/excel', + 'xlm' => 'application/excel', + 'xls' => 'application/excel', + 'xlt' => 'application/excel', + 'xlv' => 'application/excel', + 'xlw' => 'application/excel', + 'xm' => 'audio/xm', + 'xml' => 'application/xml', + 'xmz' => 'xgl/movie', + 'xpix' => 'application/x-vnd.ls-xpix', + 'xpm' => 'image/x-xpixmap', + 'x-png' => 'image/png', + 'xsr' => 'video/x-amt-showrun', + 'xwd' => 'image/x-xwd', + 'xyz' => 'chemical/x-pdb', + 'z' => 'application/x-compress', + 'zip' => 'application/x-compressed', + 'zoo' => 'application/octet-stream', + 'zsh' => 'text/x-script.zsh', + ); + + /** + * @const mime_magic_file + */ + const mime_magic_file = 'phpbb/mimetype/fixture/magic.mgc'; + + /** + * Construct a content_guesser object + * + * @param string $phpbb_root_path phpBB root path + * @param \phpbb\php\ini $php_ini + */ + public function __construct($phpbb_root_path, \phpbb\php\ini $php_ini) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ini = $php_ini; + } + + /** + * + */ + public function is_supported() + { + return true; + } + + /** + * Guess mimetype of supplied file + * + * @param string $file Path to file + * + * @return string Guess for mimetype of file + */ + public function guess($file) + { + $mimetype = null; + if (function_exists('mime_content_type')) + { + $mimetype = mime_content_type($file); + } + else + { + $mimetype = $this->map_extension_to_type($file); + } + return $mimetype; + } + + protected function map_extension_to_type($file) + { + $extension = pathinfo($file, PATHINFO_EXTENSION); + + if (isset($this->extension_map[$extension])) + { + return $this->extension_map[$extension]; + } + else + { + return null; + } + } +} From f617aff182f5f291d5b7d0ff854abea12a04cb0b Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 23 Oct 2013 23:18:40 +0200 Subject: [PATCH 05/20] [ticket/11912] Add tests for content_guesser PHPBB3-11912 --- tests/mimetype/guesser_test.php | 51 +++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/tests/mimetype/guesser_test.php b/tests/mimetype/guesser_test.php index 3728961460..6484606210 100644 --- a/tests/mimetype/guesser_test.php +++ b/tests/mimetype/guesser_test.php @@ -7,20 +7,32 @@ * */ +namespace phpbb\mimetype; + require_once dirname(__FILE__) . '/null_guesser.php'; require_once dirname(__FILE__) . '/incorrect_guesser.php'; -class phpbb_mimetype_guesser_test extends phpbb_test_case +function function_exists($name) { + return guesser_test::$function_exists; +} + +class guesser_test extends \phpbb_test_case +{ + public static $function_exists = true; + public function setUp() { + global $phpbb_root_path; + $guessers = array( - new Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser(), - new Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser(), + new \Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser(), + new \Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser(), ); $this->guesser = new \phpbb\mimetype\guesser($guessers); $this->path = dirname(__FILE__); $this->jpg_file = $this->path . '/fixtures/jpg'; + $this->phpbb_root_path = $phpbb_root_path; } public function data_guess_files() @@ -80,4 +92,37 @@ class phpbb_mimetype_guesser_test extends phpbb_test_case { $guesser = new \phpbb\mimetype\guesser($guessers); } + + public function data_content_guesser() + { + return array( + array( + array( + 'image/jpeg', + 'image/jpeg', + ), + false, + ), + array( + array( + 'application/octet-stream', + 'image/jpeg', + ), + true, + ), + ); + } + + /** + * @dataProvider data_content_guesser + */ + public function test_content_guesser($expected, $overload = false) + { + self::$function_exists = ($overload) ? false : true; + $guesser = new \phpbb\mimetype\guesser(array(new \phpbb\mimetype\content_guesser($this->phpbb_root_path, new \phpbb\php\ini))); + $this->assertEquals($expected[0], $guesser->guess($this->jpg_file)); + @copy($this->jpg_file, $this->jpg_file . '.jpg'); + $this->assertEquals($expected[1], $guesser->guess($this->jpg_file . '.jpg')); + @unlink($this->jpg_file . '.jpg'); + } } From 4af6270d0fb90a918841d63186497888ffb92bbb Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 24 Oct 2013 11:28:49 +0200 Subject: [PATCH 06/20] [ticket/11912] Improve extension map in content_guesser PHPBB3-11912 --- phpBB/phpbb/mimetype/content_guesser.php | 181 ++++++++++++----------- 1 file changed, 91 insertions(+), 90 deletions(-) diff --git a/phpBB/phpbb/mimetype/content_guesser.php b/phpBB/phpbb/mimetype/content_guesser.php index 4eeac75499..e6554666fc 100644 --- a/phpBB/phpbb/mimetype/content_guesser.php +++ b/phpBB/phpbb/mimetype/content_guesser.php @@ -61,12 +61,12 @@ class content_guesser 'asf' => 'video/x-ms-asf', 'asm' => 'text/x-asm', 'asp' => 'text/asp', - 'asx' => 'application/x-mplayer2', - 'au' => 'audio/basic', - 'avi' => 'application/x-troff-msvideo', + 'asx' => 'video/x-ms-asf', + 'au' => 'audio/x-au', + 'avi' => 'video/avi', 'avs' => 'video/avs-video', 'bcpio' => 'application/x-bcpio', - 'bin' => 'application/mac-binary', + 'bin' => 'application/x-binary', 'bm' => 'image/bmp', 'bmp' => 'image/bmp', 'boo' => 'application/book', @@ -75,14 +75,14 @@ class content_guesser 'bsh' => 'application/x-bsh', 'bz' => 'application/x-bzip', 'bz2' => 'application/x-bzip2', - 'c' => 'text/plain', - 'c++' => 'text/plain', + 'c' => 'text/x-c', + 'c++' => 'text/x-c', 'cat' => 'application/vnd.ms-pki.seccat', 'cc' => 'text/plain', 'ccad' => 'application/clariscad', 'cco' => 'application/x-cocoa', 'cdf' => 'application/cdf', - 'cer' => 'application/pkix-cert', + 'cer' => 'application/x-x509-ca-cert', 'cha' => 'application/x-chat', 'chat' => 'application/x-chat', 'class' => 'application/java', @@ -90,11 +90,11 @@ class content_guesser 'conf' => 'text/plain', 'cpio' => 'application/x-cpio', 'cpp' => 'text/x-c', - 'cpt' => 'application/mac-compactpro', - 'crl' => 'application/pkcs-crl', - 'crt' => 'application/pkix-cert', + 'cpt' => 'application/x-cpt', + 'crl' => 'application/pkix-crl', + 'crt' => 'application/x-x509-ca-cert', 'csh' => 'application/x-csh', - 'css' => 'application/x-pointplus', + 'css' => 'text/css', 'cxx' => 'text/plain', 'dcr' => 'application/x-director', 'deepv' => 'application/x-deepv', @@ -110,52 +110,52 @@ class content_guesser 'dump' => 'application/octet-stream', 'dv' => 'video/x-dv', 'dvi' => 'application/x-dvi', - 'dwf' => 'drawing/x-dwf (old)', - 'dwg' => 'application/acad', - 'dxf' => 'application/dxf', + 'dwf' => 'model/vnd.dwf', + 'dwg' => 'image/x-dwg', + 'dxf' => 'image/x-dwg', 'dxr' => 'application/x-director', 'el' => 'text/x-script.elisp', - 'elc' => 'application/x-bytecode.elisp (compiled elisp)', + 'elc' => 'application/x-elc', 'env' => 'application/x-envoy', 'eps' => 'application/postscript', 'es' => 'application/x-esrehber', 'etx' => 'text/x-setext', - 'evy' => 'application/envoy', + 'evy' => 'application/x-envoy', 'exe' => 'application/octet-stream', - 'f' => 'text/plain', + 'f' => 'text/x-fortran', 'f77' => 'text/x-fortran', - 'f90' => 'text/plain', + 'f90' => 'text/x-fortran', 'fdf' => 'application/vnd.fdf', - 'fif' => 'application/fractals', - 'fli' => 'video/fli', + 'fif' => 'image/fif', + 'fli' => 'video/x-fli', 'flo' => 'image/florian', 'flx' => 'text/vnd.fmi.flexstor', 'fmf' => 'video/x-atomic3d-feature', - 'for' => 'text/plain', + 'for' => 'text/x-fortran', 'fpx' => 'image/vnd.fpx', 'frl' => 'application/freeloader', 'funk' => 'audio/make', 'g' => 'text/plain', 'g3' => 'image/g3fax', 'gif' => 'image/gif', - 'gl' => 'video/gl', + 'gl' => 'video/x-gl', 'gsd' => 'audio/x-gsm', 'gsm' => 'audio/x-gsm', 'gsp' => 'application/x-gsp', 'gss' => 'application/x-gss', 'gtar' => 'application/x-gtar', - 'gz' => 'application/x-compressed', + 'gz' => 'application/x-gzip', 'gzip' => 'application/x-gzip', - 'h' => 'text/plain', + 'h' => 'text/x-h', 'hdf' => 'application/x-hdf', 'help' => 'application/x-helpfile', 'hgl' => 'application/vnd.hp-hpgl', - 'hh' => 'text/plain', + 'hh' => 'text/x-h', 'hlb' => 'text/x-script', 'hlp' => 'application/hlp', 'hpg' => 'application/vnd.hp-hpgl', 'hpgl' => 'application/vnd.hp-hpgl', - 'hqx' => 'application/binhex', + 'hqx' => 'application/x-binhex40', 'hta' => 'application/hta', 'htc' => 'text/x-component', 'htm' => 'text/html', @@ -182,7 +182,8 @@ class content_guesser 'ivy' => 'application/x-livescreen', 'jam' => 'audio/x-jam', 'jav' => 'text/plain', - 'java' => 'text/plain', + 'jav' => 'text/x-java-source', + 'java' => 'text/x-java-source', 'jcm' => 'application/x-java-commerce', 'jfif' => 'image/jpeg', 'jfif-tbnl' => 'image/jpeg', @@ -193,22 +194,22 @@ class content_guesser 'js' => 'application/x-javascript', 'jut' => 'image/jutvision', 'kar' => 'audio/midi', - 'ksh' => 'application/x-ksh', - 'la' => 'audio/nspaudio', + 'ksh' => 'text/x-script.ksh', + 'la' => 'audio/x-nspaudio', 'lam' => 'audio/x-liveaudio', 'latex' => 'application/x-latex', - 'lha' => 'application/lha', + 'lha' => 'application/x-lha', 'lhx' => 'application/octet-stream', 'list' => 'text/plain', - 'lma' => 'audio/nspaudio', + 'lma' => 'audio/x-nspaudio', 'log' => 'text/plain', - 'lsp' => 'application/x-lisp', + 'lsp' => 'text/x-script.lisp', 'lst' => 'text/plain', 'lsx' => 'text/x-la-asf', 'ltx' => 'application/x-latex', - 'lzh' => 'application/octet-stream', - 'lzx' => 'application/lzx', - 'm' => 'text/plain', + 'lzh' => 'application/x-lzh', + 'lzx' => 'application/x-lzx', + 'm' => 'text/x-m', 'm1v' => 'video/mpeg', 'm2a' => 'audio/mpeg', 'm2v' => 'video/mpeg', @@ -218,31 +219,31 @@ class content_guesser 'mar' => 'text/plain', 'mbd' => 'application/mbedlet', 'mc$' => 'application/x-magic-cap-package-1.0', - 'mcd' => 'application/mcad', - 'mcf' => 'image/vasa', + 'mcd' => 'application/x-mathcad', + 'mcf' => 'text/mcf', 'mcp' => 'application/netmc', 'me' => 'application/x-troff-me', 'mht' => 'message/rfc822', 'mhtml' => 'message/rfc822', - 'mid' => 'application/x-midi', - 'midi' => 'application/x-midi', - 'mif' => 'application/x-frame', - 'mime' => 'message/rfc822', + 'mid' => 'audio/x-midi', + 'midi' => 'audio/x-midi', + 'mif' => 'application/x-mif', + 'mime' => 'www/mime', 'mjf' => 'audio/x-vnd.audioexplosion.mjuicemediafile', 'mjpg' => 'video/x-motion-jpeg', - 'mm' => 'application/base64', + 'mm' => 'application/x-meme', 'mme' => 'application/base64', - 'mod' => 'audio/mod', + 'mod' => 'audio/x-mod', 'moov' => 'video/quicktime', 'mov' => 'video/quicktime', 'movie' => 'video/x-sgi-movie', - 'mp2' => 'audio/mpeg', - 'mp3' => 'audio/mpeg3', + 'mp2' => 'audio/x-mpeg', + 'mp3' => 'audio/x-mpeg-3', 'mpa' => 'audio/mpeg', 'mpc' => 'application/x-project', 'mpe' => 'video/mpeg', 'mpeg' => 'video/mpeg', - 'mpg' => 'audio/mpeg', + 'mpg' => 'video/mpeg', 'mpga' => 'audio/mpeg', 'mpp' => 'application/vnd.ms-project', 'mpt' => 'application/x-project', @@ -268,34 +269,34 @@ class content_guesser 'omcd' => 'application/x-omcdatamaker', 'omcr' => 'application/x-omcregerator', 'p' => 'text/x-pascal', - 'p10' => 'application/pkcs10', - 'p12' => 'application/pkcs-12', + 'p10' => 'application/x-pkcs10', + 'p12' => 'application/x-pkcs12', 'p7a' => 'application/x-pkcs7-signature', - 'p7c' => 'application/pkcs7-mime', - 'p7m' => 'application/pkcs7-mime', + 'p7c' => 'application/x-pkcs7-mime', + 'p7m' => 'application/x-pkcs7-mime', 'p7r' => 'application/x-pkcs7-certreqresp', 'p7s' => 'application/pkcs7-signature', 'part' => 'application/pro_eng', 'pas' => 'text/pascal', 'pbm' => 'image/x-portable-bitmap', - 'pcl' => 'application/vnd.hp-pcl', + 'pcl' => 'application/x-pcl', 'pct' => 'image/x-pict', 'pcx' => 'image/x-pcx', 'pdb' => 'chemical/x-pdb', 'pdf' => 'application/pdf', - 'pfunk' => 'audio/make', - 'pgm' => 'image/x-portable-graymap', + 'pfunk' => 'audio/make.my.funk', + 'pgm' => 'image/x-portable-greymap', 'pic' => 'image/pict', 'pict' => 'image/pict', 'pkg' => 'application/x-newton-compatible-pkg', 'pko' => 'application/vnd.ms-pki.pko', - 'pl' => 'text/plain', + 'pl' => 'text/x-script.perl', 'plx' => 'application/x-pixclscript', - 'pm' => 'image/x-xpixmap', + 'pm' => 'text/x-script.perl-module', 'pm4' => 'application/x-pagemaker', 'pm5' => 'application/x-pagemaker', 'png' => 'image/png', - 'pnm' => 'application/x-portable-anymap', + 'pnm' => 'image/x-portable-anymap', 'pot' => 'application/mspowerpoint', 'pov' => 'model/x-pov', 'ppa' => 'application/vnd.ms-powerpoint', @@ -319,43 +320,43 @@ class content_guesser 'qtc' => 'video/x-qtc', 'qti' => 'image/x-quicktime', 'qtif' => 'image/x-quicktime', - 'ra' => 'audio/x-pn-realaudio', + 'ra' => 'audio/x-realaudio', 'ram' => 'audio/x-pn-realaudio', - 'ras' => 'application/x-cmu-raster', + 'ras' => 'image/x-cmu-raster', 'rast' => 'image/cmu-raster', 'rexx' => 'text/x-script.rexx', 'rf' => 'image/vnd.rn-realflash', 'rgb' => 'image/x-rgb', - 'rm' => 'application/vnd.rn-realmedia', + 'rm' => 'audio/x-pn-realaudio', 'rmi' => 'audio/mid', 'rmm' => 'audio/x-pn-realaudio', 'rmp' => 'audio/x-pn-realaudio', - 'rng' => 'application/ringing-tones', + 'rng' => 'application/vnd.nokia.ringing-tone', 'rnx' => 'application/vnd.rn-realplayer', 'roff' => 'application/x-troff', 'rp' => 'image/vnd.rn-realpix', 'rpm' => 'audio/x-pn-realaudio-plugin', 'rt' => 'text/richtext', - 'rtf' => 'application/rtf', - 'rtx' => 'application/rtf', + 'rtf' => 'text/richtext', + 'rtx' => 'text/richtext', 'rv' => 'video/vnd.rn-realvideo', 's' => 'text/x-asm', 's3m' => 'audio/s3m', 'saveme' => 'application/octet-stream', 'sbk' => 'application/x-tbook', - 'scm' => 'application/x-lotusscreencam', + 'scm' => 'video/x-scm', 'sdml' => 'text/plain', - 'sdp' => 'application/sdp', + 'sdp' => 'application/x-sdp', 'sdr' => 'application/sounder', - 'sea' => 'application/sea', + 'sea' => 'application/x-sea', 'set' => 'application/set', - 'sgm' => 'text/sgml', - 'sgml' => 'text/sgml', - 'sh' => 'application/x-bsh', - 'shar' => 'application/x-bsh', - 'shtml' => 'text/html', + 'sgm' => 'text/x-sgml', + 'sgml' => 'text/x-sgml', + 'sh' => 'text/x-script.sh', + 'shar' => 'application/x-shar', + 'shtml' => 'text/x-server-parsed-html', 'sid' => 'audio/x-psid', - 'sit' => 'application/x-sit', + 'sit' => 'application/x-stuffit', 'skd' => 'application/x-koan', 'skm' => 'application/x-koan', 'skp' => 'application/x-koan', @@ -363,9 +364,9 @@ class content_guesser 'sl' => 'application/x-seelogo', 'smi' => 'application/smil', 'smil' => 'application/smil', - 'snd' => 'audio/basic', + 'snd' => 'audio/x-adpcm', 'sol' => 'application/solids', - 'spc' => 'application/x-pkcs7-certificates', + 'spc' => 'text/x-speech', 'spl' => 'application/futuresplash', 'spr' => 'application/x-sprite', 'sprite' => 'application/x-sprite', @@ -374,29 +375,29 @@ class content_guesser 'ssm' => 'application/streamingmedia', 'sst' => 'application/vnd.ms-pki.certstore', 'step' => 'application/step', - 'stl' => 'application/sla', + 'stl' => 'application/vnd.ms-pki.stl', 'stp' => 'application/step', 'sv4cpio' => 'application/x-sv4cpio', 'sv4crc' => 'application/x-sv4crc', - 'svf' => 'image/vnd.dwg', + 'svf' => 'image/x-dwg', 'svr' => 'application/x-world', 'swf' => 'application/x-shockwave-flash', 't' => 'application/x-troff', 'talk' => 'text/x-speech', 'tar' => 'application/x-tar', - 'tbk' => 'application/toolbook', - 'tcl' => 'application/x-tcl', + 'tbk' => 'application/x-tbook', + 'tcl' => 'text/x-script.tcl', 'tcsh' => 'text/x-script.tcsh', 'tex' => 'application/x-tex', 'texi' => 'application/x-texinfo', 'texinfo' => 'application/x-texinfo', - 'text' => 'application/plain', - 'tgz' => 'application/gnutar', + 'text' => 'text/plain', + 'tgz' => 'application/x-compressed', 'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'tr' => 'application/x-troff', 'tsi' => 'audio/tsp-audio', - 'tsp' => 'application/dsptype', + 'tsp' => 'audio/tsplayer', 'tsv' => 'text/tab-separated-values', 'turbot' => 'image/florian', 'txt' => 'text/plain', @@ -406,8 +407,8 @@ class content_guesser 'unv' => 'application/i-deas', 'uri' => 'text/uri-list', 'uris' => 'text/uri-list', - 'ustar' => 'application/x-ustar', - 'uu' => 'application/octet-stream', + 'ustar' => 'multipart/x-ustar', + 'uu' => 'text/x-uuencode', 'uue' => 'text/x-uuencode', 'vcd' => 'application/x-cdlink', 'vcs' => 'text/x-vcalendar', @@ -450,18 +451,18 @@ class content_guesser 'wpd' => 'application/wordperfect', 'wq1' => 'application/x-lotus', 'wri' => 'application/mswrite', - 'wrl' => 'application/x-world', + 'wrl' => 'model/vrml', 'wrz' => 'model/vrml', 'wsc' => 'text/scriplet', 'wsrc' => 'application/x-wais-source', 'wtk' => 'application/x-wintalk', - 'xbm' => 'image/x-xbitmap', + 'xbm' => 'image/xbm', 'xdr' => 'video/x-amt-demorun', 'xgz' => 'xgl/drawing', 'xif' => 'image/vnd.xiff', 'xl' => 'application/excel', 'xla' => 'application/excel', - 'xlb' => 'application/excel', + 'xlb' => 'application/excel',, 'xlc' => 'application/excel', 'xld' => 'application/excel', 'xlk' => 'application/excel', @@ -472,16 +473,16 @@ class content_guesser 'xlv' => 'application/excel', 'xlw' => 'application/excel', 'xm' => 'audio/xm', - 'xml' => 'application/xml', + 'xml' => 'text/xml', 'xmz' => 'xgl/movie', 'xpix' => 'application/x-vnd.ls-xpix', - 'xpm' => 'image/x-xpixmap', + 'xpm' => 'image/xpm', 'x-png' => 'image/png', 'xsr' => 'video/x-amt-showrun', - 'xwd' => 'image/x-xwd', + 'xwd' => 'image/x-xwindowdump', 'xyz' => 'chemical/x-pdb', - 'z' => 'application/x-compress', - 'zip' => 'application/x-compressed', + 'z' => 'application/x-compressed', + 'zip' => 'application/x-zip-compressed', 'zoo' => 'application/octet-stream', 'zsh' => 'text/x-script.zsh', ); From 973682cb2ddba8022622bdccc870925ea6a7237c Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 24 Oct 2013 12:02:40 +0200 Subject: [PATCH 07/20] =?UTF-8?q?[=C5=A7icket/11912]=20Get=20rid=20of=20ob?= =?UTF-8?q?solete=20variables=20in=20content=5Fguesser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PHPBB3-11912 --- phpBB/config/mimetype_guessers.yml | 3 --- phpBB/phpbb/mimetype/content_guesser.php | 29 +----------------------- 2 files changed, 1 insertion(+), 31 deletions(-) diff --git a/phpBB/config/mimetype_guessers.yml b/phpBB/config/mimetype_guessers.yml index c19fb85254..2949b0aa96 100644 --- a/phpBB/config/mimetype_guessers.yml +++ b/phpBB/config/mimetype_guessers.yml @@ -11,9 +11,6 @@ services: mimetype.content_guesser: class: phpbb\mimetype\content_guesser - arguments: - - %core.root_path% - - @php_ini tags: - { name: mimetype.guessers } diff --git a/phpBB/phpbb/mimetype/content_guesser.php b/phpBB/phpbb/mimetype/content_guesser.php index e6554666fc..65c4703e2a 100644 --- a/phpBB/phpbb/mimetype/content_guesser.php +++ b/phpBB/phpbb/mimetype/content_guesser.php @@ -23,16 +23,6 @@ if (!defined('IN_PHPBB')) class content_guesser { - /** - * @var phpbb_root_path - */ - protected $phpbb_root_path; - - /** - * @var \phpbb\php\ini - */ - protected $php_ini; - /** * @var file extension map */ @@ -488,24 +478,7 @@ class content_guesser ); /** - * @const mime_magic_file - */ - const mime_magic_file = 'phpbb/mimetype/fixture/magic.mgc'; - - /** - * Construct a content_guesser object - * - * @param string $phpbb_root_path phpBB root path - * @param \phpbb\php\ini $php_ini - */ - public function __construct($phpbb_root_path, \phpbb\php\ini $php_ini) - { - $this->phpbb_root_path = $phpbb_root_path; - $this->php_ini = $php_ini; - } - - /** - * + * @inheritdoc */ public function is_supported() { From 24099583a32608c2350bdb10d018d6c8a0551e6c Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 24 Oct 2013 12:03:46 +0200 Subject: [PATCH 08/20] [ticket/11912] Remove typo in content_guesser PHPBB3-11912 --- phpBB/phpbb/mimetype/content_guesser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/phpbb/mimetype/content_guesser.php b/phpBB/phpbb/mimetype/content_guesser.php index 65c4703e2a..6bdd410af4 100644 --- a/phpBB/phpbb/mimetype/content_guesser.php +++ b/phpBB/phpbb/mimetype/content_guesser.php @@ -452,7 +452,7 @@ class content_guesser 'xif' => 'image/vnd.xiff', 'xl' => 'application/excel', 'xla' => 'application/excel', - 'xlb' => 'application/excel',, + 'xlb' => 'application/excel', 'xlc' => 'application/excel', 'xld' => 'application/excel', 'xlk' => 'application/excel', From bc7ff47537bae4f6db9de781cf8ba3487e28a30b Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 24 Oct 2013 12:05:00 +0200 Subject: [PATCH 09/20] [ticket/11912] Supply filename to content_guesser for guessing on windows The filename of the files sent to the guesser by plupload do not contain the file extension. Therefore, it's impossible to guess the mimetype if only the content_guesser is available and the function mime_content_type() doesn't exist. By supplying the filename we can circumvent this issue. PHPBB3-11912 --- phpBB/phpbb/mimetype/content_guesser.php | 16 ++++++++++++---- phpBB/phpbb/mimetype/guesser.php | 4 ++-- phpBB/phpbb/plupload/plupload.php | 2 +- tests/mimetype/guesser_test.php | 3 ++- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/phpBB/phpbb/mimetype/content_guesser.php b/phpBB/phpbb/mimetype/content_guesser.php index 6bdd410af4..6326bf73fa 100644 --- a/phpBB/phpbb/mimetype/content_guesser.php +++ b/phpBB/phpbb/mimetype/content_guesser.php @@ -492,7 +492,7 @@ class content_guesser * * @return string Guess for mimetype of file */ - public function guess($file) + public function guess($file, $file_name = '') { $mimetype = null; if (function_exists('mime_content_type')) @@ -501,14 +501,22 @@ class content_guesser } else { - $mimetype = $this->map_extension_to_type($file); + $file_name = (empty($file_name)) ? $file : $file_name; + $mimetype = $this->map_extension_to_type($file_name); } return $mimetype; } - protected function map_extension_to_type($file) + /** + * Map extension of supplied file_name to mime type + * + * @param string $file_name Path to file or filename + * + * @return string|null Mimetype if known or null if not + */ + protected function map_extension_to_type($file_name) { - $extension = pathinfo($file, PATHINFO_EXTENSION); + $extension = pathinfo($file_name, PATHINFO_EXTENSION); if (isset($this->extension_map[$extension])) { diff --git a/phpBB/phpbb/mimetype/guesser.php b/phpBB/phpbb/mimetype/guesser.php index 5ae094cd63..231b75f604 100644 --- a/phpBB/phpbb/mimetype/guesser.php +++ b/phpBB/phpbb/mimetype/guesser.php @@ -77,7 +77,7 @@ class guesser * * @return string Guess for mimetype of file */ - public function guess($file) + public function guess($file, $file_name = '') { if (!is_file($file)) { @@ -91,7 +91,7 @@ class guesser foreach ($this->guessers as $guesser) { - $mimetype = $guesser->guess($file); + $mimetype = $guesser->guess($file, $file_name); // Try to guess something that is not the fallback application/octet-stream if ($mimetype !== null && $mimetype !== 'application/octet-stream') diff --git a/phpBB/phpbb/plupload/plupload.php b/phpBB/phpbb/plupload/plupload.php index 29a4aff39b..dedc3cbcd4 100644 --- a/phpBB/phpbb/plupload/plupload.php +++ b/phpBB/phpbb/plupload/plupload.php @@ -135,7 +135,7 @@ class plupload 'tmp_name' => $file_path, 'name' => $this->request->variable('real_filename', ''), 'size' => filesize($file_path), - 'type' => $this->mimetype_guesser->guess($file_path), + 'type' => $this->mimetype_guesser->guess($file_path, $file_name), ); } else diff --git a/tests/mimetype/guesser_test.php b/tests/mimetype/guesser_test.php index 6484606210..9d4d965d63 100644 --- a/tests/mimetype/guesser_test.php +++ b/tests/mimetype/guesser_test.php @@ -119,8 +119,9 @@ class guesser_test extends \phpbb_test_case public function test_content_guesser($expected, $overload = false) { self::$function_exists = ($overload) ? false : true; - $guesser = new \phpbb\mimetype\guesser(array(new \phpbb\mimetype\content_guesser($this->phpbb_root_path, new \phpbb\php\ini))); + $guesser = new \phpbb\mimetype\guesser(array(new \phpbb\mimetype\content_guesser)); $this->assertEquals($expected[0], $guesser->guess($this->jpg_file)); + $this->assertEquals($expected[1], $guesser->guess($this->jpg_file, $this->jpg_file . '.jpg')); @copy($this->jpg_file, $this->jpg_file . '.jpg'); $this->assertEquals($expected[1], $guesser->guess($this->jpg_file . '.jpg')); @unlink($this->jpg_file . '.jpg'); From d25ab02ef34c5e20deb278e4379a6a3a365a93a0 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 24 Oct 2013 12:07:26 +0200 Subject: [PATCH 10/20] [ticket/11912] Introduce guesser_interface This will contain proper documentation of the required methods if anyone would implement a newer guesser. PHPBB3-11912 --- phpBB/phpbb/mimetype/content_guesser.php | 8 ++--- phpBB/phpbb/mimetype/guesser_interface.php | 41 ++++++++++++++++++++++ 2 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 phpBB/phpbb/mimetype/guesser_interface.php diff --git a/phpBB/phpbb/mimetype/content_guesser.php b/phpBB/phpbb/mimetype/content_guesser.php index 6326bf73fa..f5be9cd44b 100644 --- a/phpBB/phpbb/mimetype/content_guesser.php +++ b/phpBB/phpbb/mimetype/content_guesser.php @@ -21,7 +21,7 @@ if (!defined('IN_PHPBB')) * @package mimetype */ -class content_guesser +class content_guesser implements guesser_interface { /** * @var file extension map @@ -486,11 +486,7 @@ class content_guesser } /** - * Guess mimetype of supplied file - * - * @param string $file Path to file - * - * @return string Guess for mimetype of file + * @inheritdoc */ public function guess($file, $file_name = '') { diff --git a/phpBB/phpbb/mimetype/guesser_interface.php b/phpBB/phpbb/mimetype/guesser_interface.php new file mode 100644 index 0000000000..a9b238d7aa --- /dev/null +++ b/phpBB/phpbb/mimetype/guesser_interface.php @@ -0,0 +1,41 @@ + Date: Thu, 24 Oct 2013 12:10:17 +0200 Subject: [PATCH 11/20] [ticket/11912] Use lowercase names for guesser services PHPBB3-11912 --- phpBB/config/mimetype_guessers.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/config/mimetype_guessers.yml b/phpBB/config/mimetype_guessers.yml index 2949b0aa96..fde28348a0 100644 --- a/phpBB/config/mimetype_guessers.yml +++ b/phpBB/config/mimetype_guessers.yml @@ -1,10 +1,10 @@ services: - mimetype.FileinfoMimeTypeGuesser: + mimetype.fileinfo_mimetype_guesser: class: Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser tags: - { name: mimetype.guessers } - mimetype.FileBinaryMimeTypeGuesser: + mimetype.filebinary_mimetype_guesser: class: Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser tags: - { name: mimetype.guessers } From b1719db47df4f3089f90bbfac2ca0bec24dcf027 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 11 Nov 2013 20:15:28 +0100 Subject: [PATCH 12/20] [ticket/11912] Add extension_guesser for guessing mimetype by extension The content_guesser now only guesses the mimetype with the function mime_content_type() while the guessing by extension is done using the extension_guesser. PHPBB3-11912 --- phpBB/config/mimetype_guessers.yml | 5 + phpBB/phpbb/mimetype/content_guesser.php | 481 +------------------ phpBB/phpbb/mimetype/extension_guesser.php | 517 +++++++++++++++++++++ tests/mimetype/guesser_test.php | 15 +- 4 files changed, 535 insertions(+), 483 deletions(-) create mode 100644 phpBB/phpbb/mimetype/extension_guesser.php diff --git a/phpBB/config/mimetype_guessers.yml b/phpBB/config/mimetype_guessers.yml index fde28348a0..be5064a525 100644 --- a/phpBB/config/mimetype_guessers.yml +++ b/phpBB/config/mimetype_guessers.yml @@ -14,6 +14,11 @@ services: tags: - { name: mimetype.guessers } + mimetype.extension_guesser: + class: phpbb\mimetype\extension_guesser + tags: + - { name: mimetype.guessers } + mimetype.guesser_collection: class: phpbb\di\service_collection arguments: diff --git a/phpBB/phpbb/mimetype/content_guesser.php b/phpBB/phpbb/mimetype/content_guesser.php index f5be9cd44b..21631ae6d3 100644 --- a/phpBB/phpbb/mimetype/content_guesser.php +++ b/phpBB/phpbb/mimetype/content_guesser.php @@ -23,460 +23,6 @@ if (!defined('IN_PHPBB')) class content_guesser implements guesser_interface { - /** - * @var file extension map - */ - protected $extension_map = array( - '3dm' => 'x-world/x-3dmf', - '3dmf' => 'x-world/x-3dmf', - 'a' => 'application/octet-stream', - 'aab' => 'application/x-authorware-bin', - 'aam' => 'application/x-authorware-map', - 'aas' => 'application/x-authorware-seg', - 'abc' => 'text/vnd.abc', - 'acgi' => 'text/html', - 'afl' => 'video/animaflex', - 'ai' => 'application/postscript', - 'aif' => 'audio/aiff', - 'aifc' => 'audio/aiff', - 'aiff' => 'audio/aiff', - 'aim' => 'application/x-aim', - 'aip' => 'text/x-audiosoft-intra', - 'ani' => 'application/x-navi-animation', - 'aos' => 'application/x-nokia-9000-communicator-add-on-software', - 'aps' => 'application/mime', - 'arc' => 'application/octet-stream', - 'arj' => 'application/arj', - 'art' => 'image/x-jg', - 'asf' => 'video/x-ms-asf', - 'asm' => 'text/x-asm', - 'asp' => 'text/asp', - 'asx' => 'video/x-ms-asf', - 'au' => 'audio/x-au', - 'avi' => 'video/avi', - 'avs' => 'video/avs-video', - 'bcpio' => 'application/x-bcpio', - 'bin' => 'application/x-binary', - 'bm' => 'image/bmp', - 'bmp' => 'image/bmp', - 'boo' => 'application/book', - 'book' => 'application/book', - 'boz' => 'application/x-bzip2', - 'bsh' => 'application/x-bsh', - 'bz' => 'application/x-bzip', - 'bz2' => 'application/x-bzip2', - 'c' => 'text/x-c', - 'c++' => 'text/x-c', - 'cat' => 'application/vnd.ms-pki.seccat', - 'cc' => 'text/plain', - 'ccad' => 'application/clariscad', - 'cco' => 'application/x-cocoa', - 'cdf' => 'application/cdf', - 'cer' => 'application/x-x509-ca-cert', - 'cha' => 'application/x-chat', - 'chat' => 'application/x-chat', - 'class' => 'application/java', - 'com' => 'application/octet-stream', - 'conf' => 'text/plain', - 'cpio' => 'application/x-cpio', - 'cpp' => 'text/x-c', - 'cpt' => 'application/x-cpt', - 'crl' => 'application/pkix-crl', - 'crt' => 'application/x-x509-ca-cert', - 'csh' => 'application/x-csh', - 'css' => 'text/css', - 'cxx' => 'text/plain', - 'dcr' => 'application/x-director', - 'deepv' => 'application/x-deepv', - 'def' => 'text/plain', - 'der' => 'application/x-x509-ca-cert', - 'dif' => 'video/x-dv', - 'dir' => 'application/x-director', - 'dl' => 'video/dl', - 'doc' => 'application/msword', - 'dot' => 'application/msword', - 'dp' => 'application/commonground', - 'drw' => 'application/drafting', - 'dump' => 'application/octet-stream', - 'dv' => 'video/x-dv', - 'dvi' => 'application/x-dvi', - 'dwf' => 'model/vnd.dwf', - 'dwg' => 'image/x-dwg', - 'dxf' => 'image/x-dwg', - 'dxr' => 'application/x-director', - 'el' => 'text/x-script.elisp', - 'elc' => 'application/x-elc', - 'env' => 'application/x-envoy', - 'eps' => 'application/postscript', - 'es' => 'application/x-esrehber', - 'etx' => 'text/x-setext', - 'evy' => 'application/x-envoy', - 'exe' => 'application/octet-stream', - 'f' => 'text/x-fortran', - 'f77' => 'text/x-fortran', - 'f90' => 'text/x-fortran', - 'fdf' => 'application/vnd.fdf', - 'fif' => 'image/fif', - 'fli' => 'video/x-fli', - 'flo' => 'image/florian', - 'flx' => 'text/vnd.fmi.flexstor', - 'fmf' => 'video/x-atomic3d-feature', - 'for' => 'text/x-fortran', - 'fpx' => 'image/vnd.fpx', - 'frl' => 'application/freeloader', - 'funk' => 'audio/make', - 'g' => 'text/plain', - 'g3' => 'image/g3fax', - 'gif' => 'image/gif', - 'gl' => 'video/x-gl', - 'gsd' => 'audio/x-gsm', - 'gsm' => 'audio/x-gsm', - 'gsp' => 'application/x-gsp', - 'gss' => 'application/x-gss', - 'gtar' => 'application/x-gtar', - 'gz' => 'application/x-gzip', - 'gzip' => 'application/x-gzip', - 'h' => 'text/x-h', - 'hdf' => 'application/x-hdf', - 'help' => 'application/x-helpfile', - 'hgl' => 'application/vnd.hp-hpgl', - 'hh' => 'text/x-h', - 'hlb' => 'text/x-script', - 'hlp' => 'application/hlp', - 'hpg' => 'application/vnd.hp-hpgl', - 'hpgl' => 'application/vnd.hp-hpgl', - 'hqx' => 'application/x-binhex40', - 'hta' => 'application/hta', - 'htc' => 'text/x-component', - 'htm' => 'text/html', - 'html' => 'text/html', - 'htmls' => 'text/html', - 'htt' => 'text/webviewhtml', - 'htx' => 'text/html', - 'ice' => 'x-conference/x-cooltalk', - 'ico' => 'image/x-icon', - 'idc' => 'text/plain', - 'ief' => 'image/ief', - 'iefs' => 'image/ief', - 'iges' => 'application/iges', - 'igs' => 'application/iges', - 'ima' => 'application/x-ima', - 'imap' => 'application/x-httpd-imap', - 'inf' => 'application/inf', - 'ins' => 'application/x-internett-signup', - 'ip' => 'application/x-ip2', - 'isu' => 'video/x-isvideo', - 'it' => 'audio/it', - 'iv' => 'application/x-inventor', - 'ivr' => 'i-world/i-vrml', - 'ivy' => 'application/x-livescreen', - 'jam' => 'audio/x-jam', - 'jav' => 'text/plain', - 'jav' => 'text/x-java-source', - 'java' => 'text/x-java-source', - 'jcm' => 'application/x-java-commerce', - 'jfif' => 'image/jpeg', - 'jfif-tbnl' => 'image/jpeg', - 'jpe' => 'image/jpeg', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'jps' => 'image/x-jps', - 'js' => 'application/x-javascript', - 'jut' => 'image/jutvision', - 'kar' => 'audio/midi', - 'ksh' => 'text/x-script.ksh', - 'la' => 'audio/x-nspaudio', - 'lam' => 'audio/x-liveaudio', - 'latex' => 'application/x-latex', - 'lha' => 'application/x-lha', - 'lhx' => 'application/octet-stream', - 'list' => 'text/plain', - 'lma' => 'audio/x-nspaudio', - 'log' => 'text/plain', - 'lsp' => 'text/x-script.lisp', - 'lst' => 'text/plain', - 'lsx' => 'text/x-la-asf', - 'ltx' => 'application/x-latex', - 'lzh' => 'application/x-lzh', - 'lzx' => 'application/x-lzx', - 'm' => 'text/x-m', - 'm1v' => 'video/mpeg', - 'm2a' => 'audio/mpeg', - 'm2v' => 'video/mpeg', - 'm3u' => 'audio/x-mpequrl', - 'man' => 'application/x-troff-man', - 'map' => 'application/x-navimap', - 'mar' => 'text/plain', - 'mbd' => 'application/mbedlet', - 'mc$' => 'application/x-magic-cap-package-1.0', - 'mcd' => 'application/x-mathcad', - 'mcf' => 'text/mcf', - 'mcp' => 'application/netmc', - 'me' => 'application/x-troff-me', - 'mht' => 'message/rfc822', - 'mhtml' => 'message/rfc822', - 'mid' => 'audio/x-midi', - 'midi' => 'audio/x-midi', - 'mif' => 'application/x-mif', - 'mime' => 'www/mime', - 'mjf' => 'audio/x-vnd.audioexplosion.mjuicemediafile', - 'mjpg' => 'video/x-motion-jpeg', - 'mm' => 'application/x-meme', - 'mme' => 'application/base64', - 'mod' => 'audio/x-mod', - 'moov' => 'video/quicktime', - 'mov' => 'video/quicktime', - 'movie' => 'video/x-sgi-movie', - 'mp2' => 'audio/x-mpeg', - 'mp3' => 'audio/x-mpeg-3', - 'mpa' => 'audio/mpeg', - 'mpc' => 'application/x-project', - 'mpe' => 'video/mpeg', - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mpga' => 'audio/mpeg', - 'mpp' => 'application/vnd.ms-project', - 'mpt' => 'application/x-project', - 'mpv' => 'application/x-project', - 'mpx' => 'application/x-project', - 'mrc' => 'application/marc', - 'ms' => 'application/x-troff-ms', - 'mv' => 'video/x-sgi-movie', - 'my' => 'audio/make', - 'mzz' => 'application/x-vnd.audioexplosion.mzz', - 'nap' => 'image/naplps', - 'naplps' => 'image/naplps', - 'nc' => 'application/x-netcdf', - 'ncm' => 'application/vnd.nokia.configuration-message', - 'nif' => 'image/x-niff', - 'niff' => 'image/x-niff', - 'nix' => 'application/x-mix-transfer', - 'nsc' => 'application/x-conference', - 'nvd' => 'application/x-navidoc', - 'o' => 'application/octet-stream', - 'oda' => 'application/oda', - 'omc' => 'application/x-omc', - 'omcd' => 'application/x-omcdatamaker', - 'omcr' => 'application/x-omcregerator', - 'p' => 'text/x-pascal', - 'p10' => 'application/x-pkcs10', - 'p12' => 'application/x-pkcs12', - 'p7a' => 'application/x-pkcs7-signature', - 'p7c' => 'application/x-pkcs7-mime', - 'p7m' => 'application/x-pkcs7-mime', - 'p7r' => 'application/x-pkcs7-certreqresp', - 'p7s' => 'application/pkcs7-signature', - 'part' => 'application/pro_eng', - 'pas' => 'text/pascal', - 'pbm' => 'image/x-portable-bitmap', - 'pcl' => 'application/x-pcl', - 'pct' => 'image/x-pict', - 'pcx' => 'image/x-pcx', - 'pdb' => 'chemical/x-pdb', - 'pdf' => 'application/pdf', - 'pfunk' => 'audio/make.my.funk', - 'pgm' => 'image/x-portable-greymap', - 'pic' => 'image/pict', - 'pict' => 'image/pict', - 'pkg' => 'application/x-newton-compatible-pkg', - 'pko' => 'application/vnd.ms-pki.pko', - 'pl' => 'text/x-script.perl', - 'plx' => 'application/x-pixclscript', - 'pm' => 'text/x-script.perl-module', - 'pm4' => 'application/x-pagemaker', - 'pm5' => 'application/x-pagemaker', - 'png' => 'image/png', - 'pnm' => 'image/x-portable-anymap', - 'pot' => 'application/mspowerpoint', - 'pov' => 'model/x-pov', - 'ppa' => 'application/vnd.ms-powerpoint', - 'ppm' => 'image/x-portable-pixmap', - 'pps' => 'application/mspowerpoint', - 'ppt' => 'application/mspowerpoint', - 'ppz' => 'application/mspowerpoint', - 'pre' => 'application/x-freelance', - 'prt' => 'application/pro_eng', - 'ps' => 'application/postscript', - 'psd' => 'application/octet-stream', - 'pvu' => 'paleovu/x-pv', - 'pwz' => 'application/vnd.ms-powerpoint', - 'py' => 'text/x-script.phyton', - 'pyc' => 'applicaiton/x-bytecode.python', - 'qcp' => 'audio/vnd.qcelp', - 'qd3' => 'x-world/x-3dmf', - 'qd3d' => 'x-world/x-3dmf', - 'qif' => 'image/x-quicktime', - 'qt' => 'video/quicktime', - 'qtc' => 'video/x-qtc', - 'qti' => 'image/x-quicktime', - 'qtif' => 'image/x-quicktime', - 'ra' => 'audio/x-realaudio', - 'ram' => 'audio/x-pn-realaudio', - 'ras' => 'image/x-cmu-raster', - 'rast' => 'image/cmu-raster', - 'rexx' => 'text/x-script.rexx', - 'rf' => 'image/vnd.rn-realflash', - 'rgb' => 'image/x-rgb', - 'rm' => 'audio/x-pn-realaudio', - 'rmi' => 'audio/mid', - 'rmm' => 'audio/x-pn-realaudio', - 'rmp' => 'audio/x-pn-realaudio', - 'rng' => 'application/vnd.nokia.ringing-tone', - 'rnx' => 'application/vnd.rn-realplayer', - 'roff' => 'application/x-troff', - 'rp' => 'image/vnd.rn-realpix', - 'rpm' => 'audio/x-pn-realaudio-plugin', - 'rt' => 'text/richtext', - 'rtf' => 'text/richtext', - 'rtx' => 'text/richtext', - 'rv' => 'video/vnd.rn-realvideo', - 's' => 'text/x-asm', - 's3m' => 'audio/s3m', - 'saveme' => 'application/octet-stream', - 'sbk' => 'application/x-tbook', - 'scm' => 'video/x-scm', - 'sdml' => 'text/plain', - 'sdp' => 'application/x-sdp', - 'sdr' => 'application/sounder', - 'sea' => 'application/x-sea', - 'set' => 'application/set', - 'sgm' => 'text/x-sgml', - 'sgml' => 'text/x-sgml', - 'sh' => 'text/x-script.sh', - 'shar' => 'application/x-shar', - 'shtml' => 'text/x-server-parsed-html', - 'sid' => 'audio/x-psid', - 'sit' => 'application/x-stuffit', - 'skd' => 'application/x-koan', - 'skm' => 'application/x-koan', - 'skp' => 'application/x-koan', - 'skt' => 'application/x-koan', - 'sl' => 'application/x-seelogo', - 'smi' => 'application/smil', - 'smil' => 'application/smil', - 'snd' => 'audio/x-adpcm', - 'sol' => 'application/solids', - 'spc' => 'text/x-speech', - 'spl' => 'application/futuresplash', - 'spr' => 'application/x-sprite', - 'sprite' => 'application/x-sprite', - 'src' => 'application/x-wais-source', - 'ssi' => 'text/x-server-parsed-html', - 'ssm' => 'application/streamingmedia', - 'sst' => 'application/vnd.ms-pki.certstore', - 'step' => 'application/step', - 'stl' => 'application/vnd.ms-pki.stl', - 'stp' => 'application/step', - 'sv4cpio' => 'application/x-sv4cpio', - 'sv4crc' => 'application/x-sv4crc', - 'svf' => 'image/x-dwg', - 'svr' => 'application/x-world', - 'swf' => 'application/x-shockwave-flash', - 't' => 'application/x-troff', - 'talk' => 'text/x-speech', - 'tar' => 'application/x-tar', - 'tbk' => 'application/x-tbook', - 'tcl' => 'text/x-script.tcl', - 'tcsh' => 'text/x-script.tcsh', - 'tex' => 'application/x-tex', - 'texi' => 'application/x-texinfo', - 'texinfo' => 'application/x-texinfo', - 'text' => 'text/plain', - 'tgz' => 'application/x-compressed', - 'tif' => 'image/tiff', - 'tiff' => 'image/tiff', - 'tr' => 'application/x-troff', - 'tsi' => 'audio/tsp-audio', - 'tsp' => 'audio/tsplayer', - 'tsv' => 'text/tab-separated-values', - 'turbot' => 'image/florian', - 'txt' => 'text/plain', - 'uil' => 'text/x-uil', - 'uni' => 'text/uri-list', - 'unis' => 'text/uri-list', - 'unv' => 'application/i-deas', - 'uri' => 'text/uri-list', - 'uris' => 'text/uri-list', - 'ustar' => 'multipart/x-ustar', - 'uu' => 'text/x-uuencode', - 'uue' => 'text/x-uuencode', - 'vcd' => 'application/x-cdlink', - 'vcs' => 'text/x-vcalendar', - 'vda' => 'application/vda', - 'vdo' => 'video/vdo', - 'vew' => 'application/groupwise', - 'viv' => 'video/vivo', - 'vivo' => 'video/vivo', - 'vmd' => 'application/vocaltec-media-desc', - 'vmf' => 'application/vocaltec-media-file', - 'voc' => 'audio/voc', - 'vos' => 'video/vosaic', - 'vox' => 'audio/voxware', - 'vqe' => 'audio/x-twinvq-plugin', - 'vqf' => 'audio/x-twinvq', - 'vql' => 'audio/x-twinvq-plugin', - 'vrml' => 'application/x-vrml', - 'vrt' => 'x-world/x-vrt', - 'vsd' => 'application/x-visio', - 'vst' => 'application/x-visio', - 'vsw' => 'application/x-visio', - 'w60' => 'application/wordperfect6.0', - 'w61' => 'application/wordperfect6.1', - 'w6w' => 'application/msword', - 'wav' => 'audio/wav', - 'wb1' => 'application/x-qpro', - 'wbmp' => 'image/vnd.wap.wbmp', - 'web' => 'application/vnd.xara', - 'wiz' => 'application/msword', - 'wk1' => 'application/x-123', - 'wmf' => 'windows/metafile', - 'wml' => 'text/vnd.wap.wml', - 'wmlc' => 'application/vnd.wap.wmlc', - 'wmls' => 'text/vnd.wap.wmlscript', - 'wmlsc' => 'application/vnd.wap.wmlscriptc', - 'word' => 'application/msword', - 'wp' => 'application/wordperfect', - 'wp5' => 'application/wordperfect', - 'wp6' => 'application/wordperfect', - 'wpd' => 'application/wordperfect', - 'wq1' => 'application/x-lotus', - 'wri' => 'application/mswrite', - 'wrl' => 'model/vrml', - 'wrz' => 'model/vrml', - 'wsc' => 'text/scriplet', - 'wsrc' => 'application/x-wais-source', - 'wtk' => 'application/x-wintalk', - 'xbm' => 'image/xbm', - 'xdr' => 'video/x-amt-demorun', - 'xgz' => 'xgl/drawing', - 'xif' => 'image/vnd.xiff', - 'xl' => 'application/excel', - 'xla' => 'application/excel', - 'xlb' => 'application/excel', - 'xlc' => 'application/excel', - 'xld' => 'application/excel', - 'xlk' => 'application/excel', - 'xll' => 'application/excel', - 'xlm' => 'application/excel', - 'xls' => 'application/excel', - 'xlt' => 'application/excel', - 'xlv' => 'application/excel', - 'xlw' => 'application/excel', - 'xm' => 'audio/xm', - 'xml' => 'text/xml', - 'xmz' => 'xgl/movie', - 'xpix' => 'application/x-vnd.ls-xpix', - 'xpm' => 'image/xpm', - 'x-png' => 'image/png', - 'xsr' => 'video/x-amt-showrun', - 'xwd' => 'image/x-xwindowdump', - 'xyz' => 'chemical/x-pdb', - 'z' => 'application/x-compressed', - 'zip' => 'application/x-zip-compressed', - 'zoo' => 'application/octet-stream', - 'zsh' => 'text/x-script.zsh', - ); - /** * @inheritdoc */ @@ -495,32 +41,7 @@ class content_guesser implements guesser_interface { $mimetype = mime_content_type($file); } - else - { - $file_name = (empty($file_name)) ? $file : $file_name; - $mimetype = $this->map_extension_to_type($file_name); - } + return $mimetype; } - - /** - * Map extension of supplied file_name to mime type - * - * @param string $file_name Path to file or filename - * - * @return string|null Mimetype if known or null if not - */ - protected function map_extension_to_type($file_name) - { - $extension = pathinfo($file_name, PATHINFO_EXTENSION); - - if (isset($this->extension_map[$extension])) - { - return $this->extension_map[$extension]; - } - else - { - return null; - } - } } diff --git a/phpBB/phpbb/mimetype/extension_guesser.php b/phpBB/phpbb/mimetype/extension_guesser.php new file mode 100644 index 0000000000..8cca974efc --- /dev/null +++ b/phpBB/phpbb/mimetype/extension_guesser.php @@ -0,0 +1,517 @@ + 'x-world/x-3dmf', + '3dmf' => 'x-world/x-3dmf', + 'a' => 'application/octet-stream', + 'aab' => 'application/x-authorware-bin', + 'aam' => 'application/x-authorware-map', + 'aas' => 'application/x-authorware-seg', + 'abc' => 'text/vnd.abc', + 'acgi' => 'text/html', + 'afl' => 'video/animaflex', + 'ai' => 'application/postscript', + 'aif' => 'audio/aiff', + 'aifc' => 'audio/aiff', + 'aiff' => 'audio/aiff', + 'aim' => 'application/x-aim', + 'aip' => 'text/x-audiosoft-intra', + 'ani' => 'application/x-navi-animation', + 'aos' => 'application/x-nokia-9000-communicator-add-on-software', + 'aps' => 'application/mime', + 'arc' => 'application/octet-stream', + 'arj' => 'application/arj', + 'art' => 'image/x-jg', + 'asf' => 'video/x-ms-asf', + 'asm' => 'text/x-asm', + 'asp' => 'text/asp', + 'asx' => 'video/x-ms-asf', + 'au' => 'audio/x-au', + 'avi' => 'video/avi', + 'avs' => 'video/avs-video', + 'bcpio' => 'application/x-bcpio', + 'bin' => 'application/x-binary', + 'bm' => 'image/bmp', + 'bmp' => 'image/bmp', + 'boo' => 'application/book', + 'book' => 'application/book', + 'boz' => 'application/x-bzip2', + 'bsh' => 'application/x-bsh', + 'bz' => 'application/x-bzip', + 'bz2' => 'application/x-bzip2', + 'c' => 'text/x-c', + 'c++' => 'text/x-c', + 'cat' => 'application/vnd.ms-pki.seccat', + 'cc' => 'text/plain', + 'ccad' => 'application/clariscad', + 'cco' => 'application/x-cocoa', + 'cdf' => 'application/cdf', + 'cer' => 'application/x-x509-ca-cert', + 'cha' => 'application/x-chat', + 'chat' => 'application/x-chat', + 'class' => 'application/java', + 'com' => 'application/octet-stream', + 'conf' => 'text/plain', + 'cpio' => 'application/x-cpio', + 'cpp' => 'text/x-c', + 'cpt' => 'application/x-cpt', + 'crl' => 'application/pkix-crl', + 'crt' => 'application/x-x509-ca-cert', + 'csh' => 'application/x-csh', + 'css' => 'text/css', + 'cxx' => 'text/plain', + 'dcr' => 'application/x-director', + 'deepv' => 'application/x-deepv', + 'def' => 'text/plain', + 'der' => 'application/x-x509-ca-cert', + 'dif' => 'video/x-dv', + 'dir' => 'application/x-director', + 'dl' => 'video/dl', + 'doc' => 'application/msword', + 'dot' => 'application/msword', + 'dp' => 'application/commonground', + 'drw' => 'application/drafting', + 'dump' => 'application/octet-stream', + 'dv' => 'video/x-dv', + 'dvi' => 'application/x-dvi', + 'dwf' => 'model/vnd.dwf', + 'dwg' => 'image/x-dwg', + 'dxf' => 'image/x-dwg', + 'dxr' => 'application/x-director', + 'el' => 'text/x-script.elisp', + 'elc' => 'application/x-elc', + 'env' => 'application/x-envoy', + 'eps' => 'application/postscript', + 'es' => 'application/x-esrehber', + 'etx' => 'text/x-setext', + 'evy' => 'application/x-envoy', + 'exe' => 'application/octet-stream', + 'f' => 'text/x-fortran', + 'f77' => 'text/x-fortran', + 'f90' => 'text/x-fortran', + 'fdf' => 'application/vnd.fdf', + 'fif' => 'image/fif', + 'fli' => 'video/x-fli', + 'flo' => 'image/florian', + 'flx' => 'text/vnd.fmi.flexstor', + 'fmf' => 'video/x-atomic3d-feature', + 'for' => 'text/x-fortran', + 'fpx' => 'image/vnd.fpx', + 'frl' => 'application/freeloader', + 'funk' => 'audio/make', + 'g' => 'text/plain', + 'g3' => 'image/g3fax', + 'gif' => 'image/gif', + 'gl' => 'video/x-gl', + 'gsd' => 'audio/x-gsm', + 'gsm' => 'audio/x-gsm', + 'gsp' => 'application/x-gsp', + 'gss' => 'application/x-gss', + 'gtar' => 'application/x-gtar', + 'gz' => 'application/x-gzip', + 'gzip' => 'application/x-gzip', + 'h' => 'text/x-h', + 'hdf' => 'application/x-hdf', + 'help' => 'application/x-helpfile', + 'hgl' => 'application/vnd.hp-hpgl', + 'hh' => 'text/x-h', + 'hlb' => 'text/x-script', + 'hlp' => 'application/hlp', + 'hpg' => 'application/vnd.hp-hpgl', + 'hpgl' => 'application/vnd.hp-hpgl', + 'hqx' => 'application/x-binhex40', + 'hta' => 'application/hta', + 'htc' => 'text/x-component', + 'htm' => 'text/html', + 'html' => 'text/html', + 'htmls' => 'text/html', + 'htt' => 'text/webviewhtml', + 'htx' => 'text/html', + 'ice' => 'x-conference/x-cooltalk', + 'ico' => 'image/x-icon', + 'idc' => 'text/plain', + 'ief' => 'image/ief', + 'iefs' => 'image/ief', + 'iges' => 'application/iges', + 'igs' => 'application/iges', + 'ima' => 'application/x-ima', + 'imap' => 'application/x-httpd-imap', + 'inf' => 'application/inf', + 'ins' => 'application/x-internett-signup', + 'ip' => 'application/x-ip2', + 'isu' => 'video/x-isvideo', + 'it' => 'audio/it', + 'iv' => 'application/x-inventor', + 'ivr' => 'i-world/i-vrml', + 'ivy' => 'application/x-livescreen', + 'jam' => 'audio/x-jam', + 'jav' => 'text/plain', + 'jav' => 'text/x-java-source', + 'java' => 'text/x-java-source', + 'jcm' => 'application/x-java-commerce', + 'jfif' => 'image/jpeg', + 'jfif-tbnl' => 'image/jpeg', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'jps' => 'image/x-jps', + 'js' => 'application/x-javascript', + 'jut' => 'image/jutvision', + 'kar' => 'audio/midi', + 'ksh' => 'text/x-script.ksh', + 'la' => 'audio/x-nspaudio', + 'lam' => 'audio/x-liveaudio', + 'latex' => 'application/x-latex', + 'lha' => 'application/x-lha', + 'lhx' => 'application/octet-stream', + 'list' => 'text/plain', + 'lma' => 'audio/x-nspaudio', + 'log' => 'text/plain', + 'lsp' => 'text/x-script.lisp', + 'lst' => 'text/plain', + 'lsx' => 'text/x-la-asf', + 'ltx' => 'application/x-latex', + 'lzh' => 'application/x-lzh', + 'lzx' => 'application/x-lzx', + 'm' => 'text/x-m', + 'm1v' => 'video/mpeg', + 'm2a' => 'audio/mpeg', + 'm2v' => 'video/mpeg', + 'm3u' => 'audio/x-mpequrl', + 'man' => 'application/x-troff-man', + 'map' => 'application/x-navimap', + 'mar' => 'text/plain', + 'mbd' => 'application/mbedlet', + 'mc$' => 'application/x-magic-cap-package-1.0', + 'mcd' => 'application/x-mathcad', + 'mcf' => 'text/mcf', + 'mcp' => 'application/netmc', + 'me' => 'application/x-troff-me', + 'mht' => 'message/rfc822', + 'mhtml' => 'message/rfc822', + 'mid' => 'audio/x-midi', + 'midi' => 'audio/x-midi', + 'mif' => 'application/x-mif', + 'mime' => 'www/mime', + 'mjf' => 'audio/x-vnd.audioexplosion.mjuicemediafile', + 'mjpg' => 'video/x-motion-jpeg', + 'mm' => 'application/x-meme', + 'mme' => 'application/base64', + 'mod' => 'audio/x-mod', + 'moov' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'movie' => 'video/x-sgi-movie', + 'mp2' => 'audio/x-mpeg', + 'mp3' => 'audio/x-mpeg-3', + 'mpa' => 'audio/mpeg', + 'mpc' => 'application/x-project', + 'mpe' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpga' => 'audio/mpeg', + 'mpp' => 'application/vnd.ms-project', + 'mpt' => 'application/x-project', + 'mpv' => 'application/x-project', + 'mpx' => 'application/x-project', + 'mrc' => 'application/marc', + 'ms' => 'application/x-troff-ms', + 'mv' => 'video/x-sgi-movie', + 'my' => 'audio/make', + 'mzz' => 'application/x-vnd.audioexplosion.mzz', + 'nap' => 'image/naplps', + 'naplps' => 'image/naplps', + 'nc' => 'application/x-netcdf', + 'ncm' => 'application/vnd.nokia.configuration-message', + 'nif' => 'image/x-niff', + 'niff' => 'image/x-niff', + 'nix' => 'application/x-mix-transfer', + 'nsc' => 'application/x-conference', + 'nvd' => 'application/x-navidoc', + 'o' => 'application/octet-stream', + 'oda' => 'application/oda', + 'omc' => 'application/x-omc', + 'omcd' => 'application/x-omcdatamaker', + 'omcr' => 'application/x-omcregerator', + 'p' => 'text/x-pascal', + 'p10' => 'application/x-pkcs10', + 'p12' => 'application/x-pkcs12', + 'p7a' => 'application/x-pkcs7-signature', + 'p7c' => 'application/x-pkcs7-mime', + 'p7m' => 'application/x-pkcs7-mime', + 'p7r' => 'application/x-pkcs7-certreqresp', + 'p7s' => 'application/pkcs7-signature', + 'part' => 'application/pro_eng', + 'pas' => 'text/pascal', + 'pbm' => 'image/x-portable-bitmap', + 'pcl' => 'application/x-pcl', + 'pct' => 'image/x-pict', + 'pcx' => 'image/x-pcx', + 'pdb' => 'chemical/x-pdb', + 'pdf' => 'application/pdf', + 'pfunk' => 'audio/make.my.funk', + 'pgm' => 'image/x-portable-greymap', + 'pic' => 'image/pict', + 'pict' => 'image/pict', + 'pkg' => 'application/x-newton-compatible-pkg', + 'pko' => 'application/vnd.ms-pki.pko', + 'pl' => 'text/x-script.perl', + 'plx' => 'application/x-pixclscript', + 'pm' => 'text/x-script.perl-module', + 'pm4' => 'application/x-pagemaker', + 'pm5' => 'application/x-pagemaker', + 'png' => 'image/png', + 'pnm' => 'image/x-portable-anymap', + 'pot' => 'application/mspowerpoint', + 'pov' => 'model/x-pov', + 'ppa' => 'application/vnd.ms-powerpoint', + 'ppm' => 'image/x-portable-pixmap', + 'pps' => 'application/mspowerpoint', + 'ppt' => 'application/mspowerpoint', + 'ppz' => 'application/mspowerpoint', + 'pre' => 'application/x-freelance', + 'prt' => 'application/pro_eng', + 'ps' => 'application/postscript', + 'psd' => 'application/octet-stream', + 'pvu' => 'paleovu/x-pv', + 'pwz' => 'application/vnd.ms-powerpoint', + 'py' => 'text/x-script.phyton', + 'pyc' => 'applicaiton/x-bytecode.python', + 'qcp' => 'audio/vnd.qcelp', + 'qd3' => 'x-world/x-3dmf', + 'qd3d' => 'x-world/x-3dmf', + 'qif' => 'image/x-quicktime', + 'qt' => 'video/quicktime', + 'qtc' => 'video/x-qtc', + 'qti' => 'image/x-quicktime', + 'qtif' => 'image/x-quicktime', + 'ra' => 'audio/x-realaudio', + 'ram' => 'audio/x-pn-realaudio', + 'ras' => 'image/x-cmu-raster', + 'rast' => 'image/cmu-raster', + 'rexx' => 'text/x-script.rexx', + 'rf' => 'image/vnd.rn-realflash', + 'rgb' => 'image/x-rgb', + 'rm' => 'audio/x-pn-realaudio', + 'rmi' => 'audio/mid', + 'rmm' => 'audio/x-pn-realaudio', + 'rmp' => 'audio/x-pn-realaudio', + 'rng' => 'application/vnd.nokia.ringing-tone', + 'rnx' => 'application/vnd.rn-realplayer', + 'roff' => 'application/x-troff', + 'rp' => 'image/vnd.rn-realpix', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'rt' => 'text/richtext', + 'rtf' => 'text/richtext', + 'rtx' => 'text/richtext', + 'rv' => 'video/vnd.rn-realvideo', + 's' => 'text/x-asm', + 's3m' => 'audio/s3m', + 'saveme' => 'application/octet-stream', + 'sbk' => 'application/x-tbook', + 'scm' => 'video/x-scm', + 'sdml' => 'text/plain', + 'sdp' => 'application/x-sdp', + 'sdr' => 'application/sounder', + 'sea' => 'application/x-sea', + 'set' => 'application/set', + 'sgm' => 'text/x-sgml', + 'sgml' => 'text/x-sgml', + 'sh' => 'text/x-script.sh', + 'shar' => 'application/x-shar', + 'shtml' => 'text/x-server-parsed-html', + 'sid' => 'audio/x-psid', + 'sit' => 'application/x-stuffit', + 'skd' => 'application/x-koan', + 'skm' => 'application/x-koan', + 'skp' => 'application/x-koan', + 'skt' => 'application/x-koan', + 'sl' => 'application/x-seelogo', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'snd' => 'audio/x-adpcm', + 'sol' => 'application/solids', + 'spc' => 'text/x-speech', + 'spl' => 'application/futuresplash', + 'spr' => 'application/x-sprite', + 'sprite' => 'application/x-sprite', + 'src' => 'application/x-wais-source', + 'ssi' => 'text/x-server-parsed-html', + 'ssm' => 'application/streamingmedia', + 'sst' => 'application/vnd.ms-pki.certstore', + 'step' => 'application/step', + 'stl' => 'application/vnd.ms-pki.stl', + 'stp' => 'application/step', + 'sv4cpio' => 'application/x-sv4cpio', + 'sv4crc' => 'application/x-sv4crc', + 'svf' => 'image/x-dwg', + 'svr' => 'application/x-world', + 'swf' => 'application/x-shockwave-flash', + 't' => 'application/x-troff', + 'talk' => 'text/x-speech', + 'tar' => 'application/x-tar', + 'tbk' => 'application/x-tbook', + 'tcl' => 'text/x-script.tcl', + 'tcsh' => 'text/x-script.tcsh', + 'tex' => 'application/x-tex', + 'texi' => 'application/x-texinfo', + 'texinfo' => 'application/x-texinfo', + 'text' => 'text/plain', + 'tgz' => 'application/x-compressed', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'tr' => 'application/x-troff', + 'tsi' => 'audio/tsp-audio', + 'tsp' => 'audio/tsplayer', + 'tsv' => 'text/tab-separated-values', + 'turbot' => 'image/florian', + 'txt' => 'text/plain', + 'uil' => 'text/x-uil', + 'uni' => 'text/uri-list', + 'unis' => 'text/uri-list', + 'unv' => 'application/i-deas', + 'uri' => 'text/uri-list', + 'uris' => 'text/uri-list', + 'ustar' => 'multipart/x-ustar', + 'uu' => 'text/x-uuencode', + 'uue' => 'text/x-uuencode', + 'vcd' => 'application/x-cdlink', + 'vcs' => 'text/x-vcalendar', + 'vda' => 'application/vda', + 'vdo' => 'video/vdo', + 'vew' => 'application/groupwise', + 'viv' => 'video/vivo', + 'vivo' => 'video/vivo', + 'vmd' => 'application/vocaltec-media-desc', + 'vmf' => 'application/vocaltec-media-file', + 'voc' => 'audio/voc', + 'vos' => 'video/vosaic', + 'vox' => 'audio/voxware', + 'vqe' => 'audio/x-twinvq-plugin', + 'vqf' => 'audio/x-twinvq', + 'vql' => 'audio/x-twinvq-plugin', + 'vrml' => 'application/x-vrml', + 'vrt' => 'x-world/x-vrt', + 'vsd' => 'application/x-visio', + 'vst' => 'application/x-visio', + 'vsw' => 'application/x-visio', + 'w60' => 'application/wordperfect6.0', + 'w61' => 'application/wordperfect6.1', + 'w6w' => 'application/msword', + 'wav' => 'audio/wav', + 'wb1' => 'application/x-qpro', + 'wbmp' => 'image/vnd.wap.wbmp', + 'web' => 'application/vnd.xara', + 'wiz' => 'application/msword', + 'wk1' => 'application/x-123', + 'wmf' => 'windows/metafile', + 'wml' => 'text/vnd.wap.wml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'wmls' => 'text/vnd.wap.wmlscript', + 'wmlsc' => 'application/vnd.wap.wmlscriptc', + 'word' => 'application/msword', + 'wp' => 'application/wordperfect', + 'wp5' => 'application/wordperfect', + 'wp6' => 'application/wordperfect', + 'wpd' => 'application/wordperfect', + 'wq1' => 'application/x-lotus', + 'wri' => 'application/mswrite', + 'wrl' => 'model/vrml', + 'wrz' => 'model/vrml', + 'wsc' => 'text/scriplet', + 'wsrc' => 'application/x-wais-source', + 'wtk' => 'application/x-wintalk', + 'xbm' => 'image/xbm', + 'xdr' => 'video/x-amt-demorun', + 'xgz' => 'xgl/drawing', + 'xif' => 'image/vnd.xiff', + 'xl' => 'application/excel', + 'xla' => 'application/excel', + 'xlb' => 'application/excel', + 'xlc' => 'application/excel', + 'xld' => 'application/excel', + 'xlk' => 'application/excel', + 'xll' => 'application/excel', + 'xlm' => 'application/excel', + 'xls' => 'application/excel', + 'xlt' => 'application/excel', + 'xlv' => 'application/excel', + 'xlw' => 'application/excel', + 'xm' => 'audio/xm', + 'xml' => 'text/xml', + 'xmz' => 'xgl/movie', + 'xpix' => 'application/x-vnd.ls-xpix', + 'xpm' => 'image/xpm', + 'x-png' => 'image/png', + 'xsr' => 'video/x-amt-showrun', + 'xwd' => 'image/x-xwindowdump', + 'xyz' => 'chemical/x-pdb', + 'z' => 'application/x-compressed', + 'zip' => 'application/x-zip-compressed', + 'zoo' => 'application/octet-stream', + 'zsh' => 'text/x-script.zsh', + ); + + /** + * @inheritdoc + */ + public function is_supported() + { + return true; + } + + /** + * @inheritdoc + */ + public function guess($file, $file_name = '') + { + $file_name = (empty($file_name)) ? $file : $file_name; + return $this->map_extension_to_type($file_name); + } + + /** + * Map extension of supplied file_name to mime type + * + * @param string $file_name Path to file or filename + * + * @return string|null Mimetype if known or null if not + */ + protected function map_extension_to_type($file_name) + { + $extension = pathinfo($file_name, PATHINFO_EXTENSION); + + if (isset($this->extension_map[$extension])) + { + return $this->extension_map[$extension]; + } + else + { + return null; + } + } +} diff --git a/tests/mimetype/guesser_test.php b/tests/mimetype/guesser_test.php index 9d4d965d63..8d076abae5 100644 --- a/tests/mimetype/guesser_test.php +++ b/tests/mimetype/guesser_test.php @@ -101,14 +101,23 @@ class guesser_test extends \phpbb_test_case 'image/jpeg', 'image/jpeg', ), + array(new \phpbb\mimetype\content_guesser), false, ), + array( + array( + 'application/octet-stream', + 'application/octet-stream', + ), + array(new \phpbb\mimetype\content_guesser), + true, + ), array( array( 'application/octet-stream', 'image/jpeg', ), - true, + array(new \phpbb\mimetype\extension_guesser), ), ); } @@ -116,10 +125,10 @@ class guesser_test extends \phpbb_test_case /** * @dataProvider data_content_guesser */ - public function test_content_guesser($expected, $overload = false) + public function test_content_guesser($expected, $guessers, $overload = false) { self::$function_exists = ($overload) ? false : true; - $guesser = new \phpbb\mimetype\guesser(array(new \phpbb\mimetype\content_guesser)); + $guesser = new \phpbb\mimetype\guesser($guessers); $this->assertEquals($expected[0], $guesser->guess($this->jpg_file)); $this->assertEquals($expected[1], $guesser->guess($this->jpg_file, $this->jpg_file . '.jpg')); @copy($this->jpg_file, $this->jpg_file . '.jpg'); From bef6a5a6401314da7e5688907f4ebfc06ef83f2b Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 11 Nov 2013 21:18:23 +0100 Subject: [PATCH 13/20] [ticket/11912] Introduce guesser priority to mimetype guessers The mimetype guesser priority can now be set through the service definition. Mimetypes will be guessed from the guesser with the highest priority to the one with the lowest priority. Standard priority types have been added to the service definition file. Any integer value can be used though. Standard mimetype guessers that do not have the methods get_priority and set_priority implemented, like the standard MimeTypeGuessers of symfony, will have the default priority with the value of 0. Lower priority guessers have values lower than 0 while high priority ones can be added with values higher than 0. PHPBB3-11912 --- phpBB/config/mimetype_guessers.yml | 11 ++++++ phpBB/phpbb/mimetype/content_guesser.php | 2 +- phpBB/phpbb/mimetype/extension_guesser.php | 2 +- phpBB/phpbb/mimetype/guesser.php | 35 +++++++++++++++- phpBB/phpbb/mimetype/guesser_base.php | 46 ++++++++++++++++++++++ phpBB/phpbb/mimetype/guesser_interface.php | 16 ++++++++ tests/mimetype/guesser_test.php | 15 +++++++ 7 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 phpBB/phpbb/mimetype/guesser_base.php diff --git a/phpBB/config/mimetype_guessers.yml b/phpBB/config/mimetype_guessers.yml index be5064a525..0115146deb 100644 --- a/phpBB/config/mimetype_guessers.yml +++ b/phpBB/config/mimetype_guessers.yml @@ -1,3 +1,10 @@ +parameters: + mimetype.guesser.priority.lowest: -2 + mimetype.guesser.priority.low: -1 + mimetype.guesser.priority.default: 0 + mimetype.guesser.priority.high: 1 + mimetype.guesser.priority.highest: 2 + services: mimetype.fileinfo_mimetype_guesser: class: Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser @@ -11,11 +18,15 @@ services: mimetype.content_guesser: class: phpbb\mimetype\content_guesser + calls: + - [set_priority, [%mimetype.guesser.priority.low%]] tags: - { name: mimetype.guessers } mimetype.extension_guesser: class: phpbb\mimetype\extension_guesser + calls: + - [set_priority, [%mimetype.guesser.priority.lowest%]] tags: - { name: mimetype.guessers } diff --git a/phpBB/phpbb/mimetype/content_guesser.php b/phpBB/phpbb/mimetype/content_guesser.php index 21631ae6d3..ffaed9136a 100644 --- a/phpBB/phpbb/mimetype/content_guesser.php +++ b/phpBB/phpbb/mimetype/content_guesser.php @@ -21,7 +21,7 @@ if (!defined('IN_PHPBB')) * @package mimetype */ -class content_guesser implements guesser_interface +class content_guesser extends guesser_base { /** * @inheritdoc diff --git a/phpBB/phpbb/mimetype/extension_guesser.php b/phpBB/phpbb/mimetype/extension_guesser.php index 8cca974efc..f9459c84ec 100644 --- a/phpBB/phpbb/mimetype/extension_guesser.php +++ b/phpBB/phpbb/mimetype/extension_guesser.php @@ -21,7 +21,7 @@ if (!defined('IN_PHPBB')) * @package mimetype */ -class extension_guesser implements guesser_interface +class extension_guesser extends guesser_base { /** * @var file extension map diff --git a/phpBB/phpbb/mimetype/guesser.php b/phpBB/phpbb/mimetype/guesser.php index 231b75f604..753fd65b0d 100644 --- a/phpBB/phpbb/mimetype/guesser.php +++ b/phpBB/phpbb/mimetype/guesser.php @@ -23,6 +23,11 @@ if (!defined('IN_PHPBB')) class guesser { + /** + * @const Default priority for mimetype guessers + */ + const PRIORITY_DEFAULT = 0; + /** * @var mimetype guessers */ @@ -39,7 +44,7 @@ class guesser } /** - * Register MimeTypeGuessers + * Register MimeTypeGuessers and sort them by priority * * @param array $mimetype_guessers Mimetype guesser service collection * @@ -68,6 +73,34 @@ class guesser { throw new \LogicException('No mimetype guesser supplied.'); } + + // Sort guessers by priority + usort($this->guessers, array($this, 'sort_priority')); + } + + /** + * Sort the priority of supplied guessers + * This is a compare function for usort. A guesser with higher priority + * should be used first and vice versa. usort() orders the array values + * from low to high depending on what the comparison function returns + * to it. Return value should be smaller than 0 if value a is smaller + * than value b. This has been reversed in the comparision function in + * order to sort the guessers from high to low. + * Method has been set to public in order to allow proper testing. + * + * @param object $guesser_a Mimetype guesser a + * @param object $guesser_b Mimetype guesser b + * + * @return int If both guessers have the same priority 0, bigger + * than 0 if first guesser has lower priority, and lower + * than 0 if first guesser has higher priority + */ + public function sort_priority($guesser_a, $guesser_b) + { + $priority_a = (int) (method_exists($guesser_a, 'get_priority')) ? $guesser_a->get_priority() : self::PRIORITY_DEFAULT; + $priority_b = (int) (method_exists($guesser_b, 'get_priority')) ? $guesser_b->get_priority() : self::PRIORITY_DEFAULT; + + return $priority_b - $priority_a; } /** diff --git a/phpBB/phpbb/mimetype/guesser_base.php b/phpBB/phpbb/mimetype/guesser_base.php new file mode 100644 index 0000000000..b35badea54 --- /dev/null +++ b/phpBB/phpbb/mimetype/guesser_base.php @@ -0,0 +1,46 @@ +priority; + } + + /** + * @inheritdoc + */ + public function set_priority($priority) + { + $this->priority = $priority; + } +} diff --git a/phpBB/phpbb/mimetype/guesser_interface.php b/phpBB/phpbb/mimetype/guesser_interface.php index a9b238d7aa..defff90654 100644 --- a/phpBB/phpbb/mimetype/guesser_interface.php +++ b/phpBB/phpbb/mimetype/guesser_interface.php @@ -38,4 +38,20 @@ interface guesser_interface * @return string Guess for mimetype of file */ public function guess($file, $file_name = ''); + + /** + * Get the guesser priority + * + * @return int Guesser priority + */ + public function get_priority(); + + /** + * Set the guesser priority + * + * @param int Guesser priority + * + * @return void + */ + public function set_priority($priority); } diff --git a/tests/mimetype/guesser_test.php b/tests/mimetype/guesser_test.php index 8d076abae5..a489e68b40 100644 --- a/tests/mimetype/guesser_test.php +++ b/tests/mimetype/guesser_test.php @@ -135,4 +135,19 @@ class guesser_test extends \phpbb_test_case $this->assertEquals($expected[1], $guesser->guess($this->jpg_file . '.jpg')); @unlink($this->jpg_file . '.jpg'); } + + public function test_sort_priority() + { + $guessers = array( + 'FileinfoMimeTypeGuesser' => new \Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser, + 'extension_guesser' => new \phpbb\mimetype\extension_guesser, + 'FileBinaryMimeTypeGuesser' => new \Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser, + 'content_guesser' => new \phpbb\mimetype\content_guesser, + ); + $guessers['content_guesser']->set_priority(5); + $guessers['extension_guesser']->set_priority(-5); + usort($guessers, array($this->guesser, 'sort_priority')); + $this->assertInstanceOf('\phpbb\mimetype\content_guesser', $guessers[0]); + $this->assertInstanceOf('\phpbb\mimetype\extension_guesser', $guessers[3]); + } } From 81caa35955b696e1ffdcafe4ccdd72a83700b773 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 11 Nov 2013 21:24:44 +0100 Subject: [PATCH 14/20] [ticket/11912] Remove obsolete $file_info from plupload PHPBB3-11912 --- phpBB/phpbb/plupload/plupload.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/phpBB/phpbb/plupload/plupload.php b/phpBB/phpbb/plupload/plupload.php index dedc3cbcd4..f9f2fdd812 100644 --- a/phpBB/phpbb/plupload/plupload.php +++ b/phpBB/phpbb/plupload/plupload.php @@ -128,8 +128,6 @@ class plupload { rename("{$file_path}.part", $file_path); - $file_info = new \Symfony\Component\HttpFoundation\File\File($file_path); - // Need to modify some of the $_FILES values to reflect the new file return array( 'tmp_name' => $file_path, From 9d4893b04760e3e1bff023e3615ad19beb699068 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 11 Nov 2013 21:29:11 +0100 Subject: [PATCH 15/20] [ticket/11912] Remove IN_PHPBB checks from mimetype guesser files PHPBB3-11912 --- phpBB/phpbb/mimetype/content_guesser.php | 8 -------- phpBB/phpbb/mimetype/extension_guesser.php | 8 -------- phpBB/phpbb/mimetype/guesser.php | 8 -------- phpBB/phpbb/mimetype/guesser_base.php | 8 -------- phpBB/phpbb/mimetype/guesser_interface.php | 8 -------- 5 files changed, 40 deletions(-) diff --git a/phpBB/phpbb/mimetype/content_guesser.php b/phpBB/phpbb/mimetype/content_guesser.php index ffaed9136a..ea15393b94 100644 --- a/phpBB/phpbb/mimetype/content_guesser.php +++ b/phpBB/phpbb/mimetype/content_guesser.php @@ -9,14 +9,6 @@ namespace phpbb\mimetype; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - /** * @package mimetype */ diff --git a/phpBB/phpbb/mimetype/extension_guesser.php b/phpBB/phpbb/mimetype/extension_guesser.php index f9459c84ec..f6f4ae0138 100644 --- a/phpBB/phpbb/mimetype/extension_guesser.php +++ b/phpBB/phpbb/mimetype/extension_guesser.php @@ -9,14 +9,6 @@ namespace phpbb\mimetype; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - /** * @package mimetype */ diff --git a/phpBB/phpbb/mimetype/guesser.php b/phpBB/phpbb/mimetype/guesser.php index 753fd65b0d..3499b3b0f7 100644 --- a/phpBB/phpbb/mimetype/guesser.php +++ b/phpBB/phpbb/mimetype/guesser.php @@ -9,14 +9,6 @@ namespace phpbb\mimetype; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - /** * @package mimetype */ diff --git a/phpBB/phpbb/mimetype/guesser_base.php b/phpBB/phpbb/mimetype/guesser_base.php index b35badea54..082b098028 100644 --- a/phpBB/phpbb/mimetype/guesser_base.php +++ b/phpBB/phpbb/mimetype/guesser_base.php @@ -9,14 +9,6 @@ namespace phpbb\mimetype; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - /** * @package mimetype */ diff --git a/phpBB/phpbb/mimetype/guesser_interface.php b/phpBB/phpbb/mimetype/guesser_interface.php index defff90654..103689765e 100644 --- a/phpBB/phpbb/mimetype/guesser_interface.php +++ b/phpBB/phpbb/mimetype/guesser_interface.php @@ -9,14 +9,6 @@ namespace phpbb\mimetype; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - /** * @package mimetype */ From 95b22819a7c0f6bddee0f6b095f8bf777ef653b6 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 11 Nov 2013 21:59:47 +0100 Subject: [PATCH 16/20] [ticket/11912] Use inverted $overload for setting function_exists in tests PHPBB3-11912 --- tests/mimetype/guesser_test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mimetype/guesser_test.php b/tests/mimetype/guesser_test.php index a489e68b40..2c1a35544f 100644 --- a/tests/mimetype/guesser_test.php +++ b/tests/mimetype/guesser_test.php @@ -127,7 +127,7 @@ class guesser_test extends \phpbb_test_case */ public function test_content_guesser($expected, $guessers, $overload = false) { - self::$function_exists = ($overload) ? false : true; + self::$function_exists = !$overload; $guesser = new \phpbb\mimetype\guesser($guessers); $this->assertEquals($expected[0], $guesser->guess($this->jpg_file)); $this->assertEquals($expected[1], $guesser->guess($this->jpg_file, $this->jpg_file . '.jpg')); From e380eed78e6f3076c5d7cb3df3a016165781e73d Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 12 Nov 2013 00:35:52 +0100 Subject: [PATCH 17/20] [ticket/11912] Remove obsolete variable $mimetype from content_guesser PHPBB3-11912 --- phpBB/phpbb/mimetype/content_guesser.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/phpBB/phpbb/mimetype/content_guesser.php b/phpBB/phpbb/mimetype/content_guesser.php index ea15393b94..623438ee0b 100644 --- a/phpBB/phpbb/mimetype/content_guesser.php +++ b/phpBB/phpbb/mimetype/content_guesser.php @@ -28,12 +28,11 @@ class content_guesser extends guesser_base */ public function guess($file, $file_name = '') { - $mimetype = null; if (function_exists('mime_content_type')) { - $mimetype = mime_content_type($file); + return mime_content_type($file); } - return $mimetype; + return null; // optional } } From df6e03266fbe13e64a1f889136b6b1244b9111ae Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 14 Nov 2013 15:12:42 +0100 Subject: [PATCH 18/20] [ticket/11912] Remove obsolete "return null" in content_guesser PHPBB3-11912 --- phpBB/phpbb/mimetype/content_guesser.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/phpBB/phpbb/mimetype/content_guesser.php b/phpBB/phpbb/mimetype/content_guesser.php index 623438ee0b..60e5a905e2 100644 --- a/phpBB/phpbb/mimetype/content_guesser.php +++ b/phpBB/phpbb/mimetype/content_guesser.php @@ -32,7 +32,5 @@ class content_guesser extends guesser_base { return mime_content_type($file); } - - return null; // optional } } From e108418824857e670a92f516285455f79bf6e12a Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sat, 23 Nov 2013 00:51:29 +0100 Subject: [PATCH 19/20] [ticket/11912] Check if content_guesser is supported with function_exists PHPBB3-11912 --- phpBB/phpbb/mimetype/content_guesser.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/phpBB/phpbb/mimetype/content_guesser.php b/phpBB/phpbb/mimetype/content_guesser.php index 60e5a905e2..2d74582a21 100644 --- a/phpBB/phpbb/mimetype/content_guesser.php +++ b/phpBB/phpbb/mimetype/content_guesser.php @@ -20,7 +20,7 @@ class content_guesser extends guesser_base */ public function is_supported() { - return true; + return function_exists('mime_content_type'); } /** @@ -28,9 +28,6 @@ class content_guesser extends guesser_base */ public function guess($file, $file_name = '') { - if (function_exists('mime_content_type')) - { - return mime_content_type($file); - } + return mime_content_type($file); } } From c9c419c4317ddd12b49082368e245f881a001610 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sat, 23 Nov 2013 01:19:43 +0100 Subject: [PATCH 20/20] [ticket/11912] Expect logic exceptions in test if no guesser available PHPBB3-11912 --- tests/mimetype/guesser_test.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/mimetype/guesser_test.php b/tests/mimetype/guesser_test.php index 2c1a35544f..9f0371262b 100644 --- a/tests/mimetype/guesser_test.php +++ b/tests/mimetype/guesser_test.php @@ -127,7 +127,20 @@ class guesser_test extends \phpbb_test_case */ public function test_content_guesser($expected, $guessers, $overload = false) { + $supported = false; self::$function_exists = !$overload; + + // Cover possible LogicExceptions + foreach ($guessers as $cur_guesser) + { + $supported += $cur_guesser->is_supported(); + } + + if (!$supported) + { + $this->setExpectedException('\LogicException'); + } + $guesser = new \phpbb\mimetype\guesser($guessers); $this->assertEquals($expected[0], $guesser->guess($this->jpg_file)); $this->assertEquals($expected[1], $guesser->guess($this->jpg_file, $this->jpg_file . '.jpg'));