From 0e03cf55defff9455ee1fdd462d5aec53eacb1fc Mon Sep 17 00:00:00 2001
From: Thomas Steur <thomas.steur@gmail.com>
Date: Tue, 22 Oct 2013 20:28:40 +0000
Subject: [PATCH] throw an exception in case a plugin contains a malformed json
 translation file

---
 core/Common.php         | 35 +++++++++++++++++++++++++++++++++++
 core/Plugin/Manager.php | 28 ++++++++++++++++++++++++----
 2 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/core/Common.php b/core/Common.php
index fd1fd15854..2c28ca720e 100644
--- a/core/Common.php
+++ b/core/Common.php
@@ -584,6 +584,41 @@ class Common
         return json_decode($json, $assoc);
     }
 
+    /**
+     * Detects whether an error occurred during the last json encode/decode.
+     * @return bool
+     */
+    public static function hasJsonErrorOccurred()
+    {
+        return json_last_error() != JSON_ERROR_NONE;
+    }
+
+    /**
+     * Returns a human readable error message in case an error occcurred during the last json encode/decode.
+     * Returns an empty string in case there was no error.
+     *
+     * @return string
+     */
+    public static function getLastJsonError()
+    {
+        switch (json_last_error()) {
+            case JSON_ERROR_NONE:
+                return '';
+            case JSON_ERROR_DEPTH:
+                return 'Maximum stack depth exceeded';
+            case JSON_ERROR_STATE_MISMATCH:
+                return 'Underflow or the modes mismatch';
+            case JSON_ERROR_CTRL_CHAR:
+                return 'Unexpected control character found';
+            case JSON_ERROR_SYNTAX:
+                return 'Syntax error, malformed JSON';
+            case JSON_ERROR_UTF8:
+                return 'Malformed UTF-8 characters, possibly incorrectly encoded';
+        }
+
+        return 'Unknown error';
+    }
+
     /**
      * Returns the list of parent classes for the given class.
      *
diff --git a/core/Plugin/Manager.php b/core/Plugin/Manager.php
index 1b536f8d8c..ff70bf98f7 100644
--- a/core/Plugin/Manager.php
+++ b/core/Plugin/Manager.php
@@ -11,6 +11,7 @@
 
 namespace Piwik\Plugin;
 
+use Piwik\Common;
 use Piwik\Config as PiwikConfig;
 use Piwik\EventDispatcher;
 use Piwik\Filesystem;
@@ -742,11 +743,9 @@ class Manager extends Singleton
         $defaultEnglishLangPath = sprintf($path, 'en');
 
         if (file_exists($defaultLangPath)) {
-            $data = file_get_contents($defaultLangPath);
-            $translations = json_decode($data, true);
+            $translations = $this->getTranslationsFromFile($defaultLangPath);
         } elseif (file_exists($defaultEnglishLangPath)) {
-            $data = file_get_contents($defaultEnglishLangPath);
-            $translations = json_decode($data, true);
+            $translations = $this->getTranslationsFromFile($defaultEnglishLangPath);
         } else {
             return false;
         }
@@ -897,6 +896,27 @@ class Manager extends Singleton
             }
         }
     }
+
+    /**
+     * @param  string $pathToTranslationFile
+     * @throws \Exception
+     * @return mixed
+     */
+    private function getTranslationsFromFile($pathToTranslationFile)
+    {
+        $data         = file_get_contents($pathToTranslationFile);
+        $translations = json_decode($data, true);
+
+        if (is_null($translations) && Common::hasJsonErrorOccurred()) {
+            $jsonError = Common::getLastJsonError();
+
+            $message = sprintf('Not able to load translation file %s: %s', $pathToTranslationFile, $jsonError);
+
+            throw new \Exception($message);
+        }
+
+        return $translations;
+    }
 }
 
 /**
-- 
GitLab