]> git.mxchange.org Git - friendica.git/commitdiff
Improved Mime Type detection
authorMichael <heluecht@pirati.ca>
Wed, 1 Apr 2020 05:42:44 +0000 (05:42 +0000)
committerMichael <heluecht@pirati.ca>
Wed, 1 Apr 2020 05:42:44 +0000 (05:42 +0000)
include/api.php
mod/photos.php
mod/wall_upload.php
src/Content/Text/BBCode.php
src/Model/Photo.php
src/Model/User.php
src/Module/Settings/Profile/Photo/Index.php
src/Object/Image.php
src/Util/Images.php

index bcfd5af2464e570eba213853a6f6d57ebcaefd0b..8291d189269bdbfe26056df68c4a53632fe0e9b3 100644 (file)
@@ -4734,13 +4734,8 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $
                }
        }
 
-       if ($filetype == "") {
-               $filetype = Images::guessType($filename);
-       }
-       $imagedata = @getimagesize($src);
-       if ($imagedata) {
-               $filetype = $imagedata['mime'];
-       }
+       $filetype = Images::getMimeTypeBySource($src, $filename, $filetype);
+
        Logger::log(
                "File upload src: " . $src . " - filename: " . $filename .
                " - size: " . $filesize . " - type: " . $filetype,
index ef957ad5b05517110fd365b5d39a5ecb9e3ff9f4..3f558429d4ea4d45714044494b1a4b1b02e31f13 100644 (file)
@@ -706,9 +706,7 @@ function photos_post(App $a)
                return;
        }
 
-       if ($type == "") {
-               $type = Images::guessType($filename);
-       }
+       $type = Images::getMimeTypeBySource($src, $filename, $type);
 
        Logger::log('photos: upload: received file: ' . $filename . ' as ' . $src . ' ('. $type . ') ' . $filesize . ' bytes', Logger::DEBUG);
 
index fd33cdd17af813ce4b8f5b28172ae56df4dee3ee..3841ef97b52c399ae64b3374499c167944d45c3a 100644 (file)
@@ -174,23 +174,7 @@ function wall_upload_post(App $a, $desktopmode = true)
                exit();
        }
 
-       // This is a special treatment for picture upload from Twidere
-       if (($filename == "octet-stream") && ($filetype != "")) {
-               $filename = $filetype;
-               $filetype = "";
-       }
-
-       if ($filetype == "") {
-               $filetype = Images::guessType($filename);
-       }
-
-       // If there is a temp name, then do a manual check
-       // This is more reliable than the provided value
-
-       $imagedata = getimagesize($src);
-       if ($imagedata) {
-               $filetype = $imagedata['mime'];
-       }
+       $filetype = Images::getMimeTypeBySource($src, $filename, $filetype);
 
        Logger::log("File upload src: " . $src . " - filename: " . $filename .
                " - size: " . $filesize . " - type: " . $filetype, Logger::DEBUG);
index 7a316c251b737a7e1766b6d68cd4834b36cf59b3..334efb32a78dd4f7fc904b78320d20edf542b859 100644 (file)
@@ -453,6 +453,10 @@ class BBCode
        {
                $s = $srctext;
 
+               // Simplify image links
+               $s = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $s);
+               $s = preg_replace("/\[img\=(.*?)\](.*?)\[\/img\]/ism", '[img]$1[/img]', $s);
+
                $matches = null;
                $c = preg_match_all('/\[img.*?\](.*?)\[\/img\]/ism', $s, $matches, PREG_SET_ORDER);
                if ($c) {
@@ -464,13 +468,14 @@ class BBCode
                                        continue;
                                }
 
-                               $i = Network::fetchUrl($mtch[1]);
-                               if (!$i) {
-                                       return $srctext;
+                               $curlResult = Network::curl($mtch[1], true);
+                               if (!$curlResult->isSuccess()) {
+                                       continue;
                                }
 
-                               // guess mimetype from headers or filename
-                               $type = Images::guessType($mtch[1], true);
+                               $i = $curlResult->getBody();
+                               $type = $curlResult->getContentType();
+                               $type = Images::getMimeTypeByData($i, $mtch[1], $type);
 
                                if ($i) {
                                        $Image = new Image($i, $type);
index 45a8a92e1993ee1aa7caa6769ff2e33e26c4d9ce..9d8b5611f7f8b5f2543b0cc74e92521be7a6a0ba 100644 (file)
@@ -432,9 +432,7 @@ class Photo
                        return false;
                }
 
-               if (empty($type)) {
-                       $type = Images::guessType($image_url, true);
-               }
+               $type = Images::getMimeTypeByData($img_str, $image_url, $type);
 
                $Image = new Image($img_str, $type);
                if ($Image->isValid()) {
index 351982e8add93cccc2f726f197b7a4da1cfe3591..4ef5ffa33c05dba68c5b0698d58e357b79c58ba1 100644 (file)
@@ -839,9 +839,16 @@ class User
                        $photo_failure = false;
 
                        $filename = basename($photo);
-                       $img_str = Network::fetchUrl($photo, true);
-                       // guess mimetype from headers or filename
-                       $type = Images::guessType($photo, true);
+                       $curlResult = Network::curl($photo, true);
+                       if ($curlResult->isSuccess()) {
+                               $img_str = $curlResult->getBody();
+                               $type = $curlResult->getContentType();
+                       } else {
+                               $img_str = '';
+                               $type = '';
+                       }
+
+                       $type = Images::getMimeTypeByData($img_str, $photo, $type);
 
                        $Image = new Image($img_str, $type);
                        if ($Image->isValid()) {
index 40b4ab1539a227fc7b83c78b059be9ff79b41469..3e4f9b8a4efe7b1e8d7332045485bc2e1bd26a41 100644 (file)
@@ -52,9 +52,8 @@ class Index extends BaseSettings
                $filename = basename($_FILES['userfile']['name']);
                $filesize = intval($_FILES['userfile']['size']);
                $filetype = $_FILES['userfile']['type'];
-               if ($filetype == '') {
-                       $filetype = Images::guessType($filename);
-               }
+
+               $filetype = Images::getMimeTypeBySource($src, $filename, $filetype);
 
                $maximagesize = DI::config()->get('system', 'maximagesize', 0);
 
index 535eae0b33b8d845d52a506dbc086328a6a32a17..4d064f3c3a6522e6d0690cf9e4384bf1038d6aac 100644 (file)
@@ -708,22 +708,6 @@ class Image
                return Images::getFormatsMap();
        }
 
-       /**
-        * Guess image mimetype from filename or from Content-Type header
-        *
-        * @param string  $filename Image filename
-        * @param boolean $fromcurl Check Content-Type header from curl request
-        * @param string  $header   passed headers to take into account
-        *
-        * @return string|null
-        * @throws Exception
-        * @deprecated in version 2019.12 please use Util\Images::guessType() instead.
-        */
-       public static function guessType($filename, $fromcurl = false, $header = '')
-       {
-               return Images::guessType($filename, $fromcurl, $header);
-       }
-
        /**
         * @param string $url url
         * @return array
index 6471ed526bdbcc3e7733b4c8abf574262774bfd8..35f0cfc042e4be875e1116814b048bc361a846dc 100644 (file)
@@ -24,7 +24,6 @@ namespace Friendica\Util;
 use Friendica\Core\Logger;
 use Friendica\Core\System;
 use Friendica\DI;
-use Imagick;
 
 /**
  * Image utilities
@@ -74,62 +73,80 @@ class Images
        }
 
        /**
-        * Guess image mimetype from filename or from Content-Type header
+        * Fetch image mimetype from the image data or guessing from the file name
         *
-        * @param string  $filename Image filename
-        * @param boolean $fromcurl Check Content-Type header from curl request
-        * @param string  $header   passed headers to take into account
+        * @param string $image_data Image data
+        * @param string $filename   File name (for guessing the type via the extension)
+        * @param string $mime       default mime type
         *
-        * @return string|null
+        * @return string
         * @throws \Exception
         */
-       public static function guessType($filename, $fromcurl = false, $header = '')
+       public static function getMimeTypeByData(string $image_data, string $filename = '', string $mime = '')
        {
-               Logger::info('Image: guessType: ' . $filename . ($fromcurl ? ' from curl headers' : ''));
-               $type = null;
-               if ($fromcurl) {
-                       $headers = [];
-                       $h = explode("\n", $header);
-                       foreach ($h as $l) {
-                               $data = array_map("trim", explode(":", trim($l), 2));
-                               if (count($data) > 1) {
-                                       list($k, $v) = $data;
-                                       $headers[$k] = $v;
-                               }
-                       }
+               if (substr($mime, 0, 6) == 'image/') {
+                       Logger::info('Using default mime type', ['filename' => $filename, 'mime' => $mime]);
+                       return $mime;
+               }
 
-                       if (array_key_exists('Content-Type', $headers)) {
-                               $type = $headers['Content-Type'];
-                       }
+               $image = @getimagesizefromstring($image_data);
+               if (!empty($image['mime'])) {
+                       Logger::info('Mime type detected via data', ['filename' => $filename, 'default' => $mime, 'mime' => $image['mime']]);
+                       return $image['mime'];
                }
 
-               if (is_null($type)) {
-                       // Guessing from extension? Isn't that... dangerous?
-                       if (class_exists('Imagick') && file_exists($filename) && is_readable($filename)) {
-                               /**
-                                * Well, this not much better,
-                                * but at least it comes from the data inside the image,
-                                * we won't be tricked by a manipulated extension
-                                */
-                               $image = new Imagick($filename);
-                               $type = $image->getImageMimeType();
-                       } else {
-                               $ext = pathinfo($filename, PATHINFO_EXTENSION);
-                               $types = self::supportedTypes();
-                               $type = 'image/jpeg';
-                               foreach ($types as $m => $e) {
-                                       if ($ext == $e) {
-                                               $type = $m;
-                                       }
-                               }
+               return self::guessTypeByExtension($filename);
+       }
+
+       /**
+        * Fetch image mimetype from the image data or guessing from the file name
+        *
+        * @param string $sourcefile Source file of the image
+        * @param string $filename   File name (for guessing the type via the extension)
+        * @param string $mime       default mime type
+        *
+        * @return string
+        * @throws \Exception
+        */
+       public static function getMimeTypeBySource(string $sourcefile, string $filename = '', string $mime = '')
+       {
+               if (substr($mime, 0, 6) == 'image/') {
+                       Logger::info('Using default mime type', ['filename' => $filename, 'mime' => $mime]);
+                       return $mime;
+               }
+
+               $image = @getimagesize($sourcefile);
+               if (!empty($image['mime'])) {
+                       Logger::info('Mime type detected via file', ['filename' => $filename, 'default' => $mime, 'image' => $image]);
+                       return $image['mime'];
+               }
+
+               return self::guessTypeByExtension($filename);
+       }
+
+       /**
+        * Guess image mimetype from the filename
+        *
+        * @param string $filename   Image filename
+        *
+        * @return string
+        * @throws \Exception
+        */
+       public static function guessTypeByExtension(string $filename)
+       {
+               $ext = pathinfo(parse_url($filename, PHP_URL_PATH), PATHINFO_EXTENSION);
+               $types = self::supportedTypes();
+               $type = 'image/jpeg';
+               foreach ($types as $m => $e) {
+                       if ($ext == $e) {
+                               $type = $m;
                        }
                }
 
-               Logger::info('Image: guessType: type=' . $type);
+               Logger::info('Mime type guessed via extension', ['filename' => $filename, 'type' => $type]);
                return $type;
        }
 
-
        /**
         * @param string $url
         * @return array