]> git.immae.eu Git - github/wallabag/wallabag.git/blobdiff - src/Wallabag/CoreBundle/Helper/ContentProxy.php
Bugfix: Sanitize the title of a saved webpage from invalid UTF-8 characters
[github/wallabag/wallabag.git] / src / Wallabag / CoreBundle / Helper / ContentProxy.php
index fe795d42b5669c967368d685cc334dd0a193e52f..2628af190b3119a952394f382368c0ab914bfee9 100644 (file)
@@ -53,6 +53,7 @@ class ContentProxy
 
         if ((empty($content) || false === $this->validateContent($content)) && false === $disableContentUpdate) {
             $fetchedContent = $this->graby->fetchContent($url);
+            $fetchedContent['title'] = $this->sanitizeUTF8Text($fetchedContent['title']);
 
             // when content is imported, we have information in $content
             // in case fetching content goes bad, we'll keep the imported information instead of overriding them
@@ -68,6 +69,28 @@ class ContentProxy
         $this->stockEntry($entry, $content);
     }
 
+    /**
+     * Remove invalid UTF-8 characters from the given string in following steps:
+     * - try to interpret the given string as ISO-8859-1, convert it to UTF-8 and return it (if its valid)
+     * - simply remove every invalid UTF-8 character and return the result (https://stackoverflow.com/a/1433665)
+     * @param String $rawText
+     * @return string
+     */
+    private function sanitizeUTF8Text(String $rawText) {
+        if (mb_check_encoding($rawText, 'utf-8')) {
+            return $rawText; // return because its valid utf-8 text
+        }
+
+        // we assume that $text is encoded in ISO-8859-1 (and not the similar Windows-1252 or other encoding)
+        $convertedText = utf8_encode($rawText);
+        if (mb_check_encoding($convertedText, 'utf-8')) {
+            return $convertedText;
+        }
+
+        // last resort: simply remove invalid UTF-8 character because $rawText can have some every exotic encoding
+        return iconv("UTF-8", "UTF-8//IGNORE", $rawText);
+    }
+
     /**
      * Use a Symfony validator to ensure the language is well formatted.
      *
@@ -85,7 +108,7 @@ class ContentProxy
             (new LocaleConstraint())
         );
 
-        if (0 === count($errors)) {
+        if (0 === \count($errors)) {
             $entry->setLanguage($value);
 
             return;
@@ -107,7 +130,7 @@ class ContentProxy
             (new UrlConstraint())
         );
 
-        if (0 === count($errors)) {
+        if (0 === \count($errors)) {
             $entry->setPreviewPicture($value);
 
             return;
@@ -212,7 +235,7 @@ class ContentProxy
             $entry->setHttpStatus($content['status']);
         }
 
-        if (!empty($content['authors']) && is_array($content['authors'])) {
+        if (!empty($content['authors']) && \is_array($content['authors'])) {
             $entry->setPublishedBy($content['authors']);
         }
 
@@ -233,7 +256,7 @@ class ContentProxy
         }
 
         // if content is an image, define it as a preview too
-        if (!empty($content['content_type']) && in_array($this->mimeGuesser->guess($content['content_type']), ['jpeg', 'jpg', 'gif', 'png'], true)) {
+        if (!empty($content['content_type']) && \in_array($this->mimeGuesser->guess($content['content_type']), ['jpeg', 'jpg', 'gif', 'png'], true)) {
             $this->updatePreviewPicture($entry, $content['url']);
         }