From e72501a90302fc1190726d524b07d3643a31c5ac Mon Sep 17 00:00:00 2001 From: Hanne Moa <hanne.moa@uninett.no> Date: Wed, 13 Jul 2016 13:45:07 +0200 Subject: [PATCH] Load translation files safely --- lib/SimpleSAML/Locale/Localization.php | 53 +++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/lib/SimpleSAML/Locale/Localization.php b/lib/SimpleSAML/Locale/Localization.php index d0d706632..e539c241f 100644 --- a/lib/SimpleSAML/Locale/Localization.php +++ b/lib/SimpleSAML/Locale/Localization.php @@ -80,6 +80,38 @@ class Localization $this->localeDomainMap[$domain] = $localeDir; } + /* + * Get and check path of localization file + * + * @param string $domain Name of localization domain + * @throws Exception If the path does not exist even for the default, fallback language + */ + public function getLangPath($domain = self::DEFAULT_DOMAIN) { + $langcode = explode('_', $this->langcode); + $langcode = $langcode[0]; + $localeDir = $this->localeDomainMap[$domain]; + $langPath = $localeDir.'/'.$langcode.'/LC_MESSAGES/'; + if (is_dir($langPath) && is_readable($langPath)) { + return $langPath; + } + + // Language not found, fall back to default + $defLangcode = $this->language->getDefaultLanguage(); + $langPath = $localeDir.'/'.$defLangcode.'/LC_MESSAGES/'; + if (is_dir($langPath) && is_readable($langPath)) { + // Report that the localization for the preferred language is missing + $error = "Localization not found for langcode '$langcode' at '$langPath', falling back to langcode '$defLangcode'"; + \SimpleSAML_Logger::error($_SERVER['PHP_SELF'].' - '.$error); + + return $langPath; + } + + // Locale for default language missing even, error out + $error = "Localization directory missing/broken for langcode '$langcode' and domain '$domain'"; + \SimpleSAML_Logger::critical($_SERVER['PHP_SELF'].' - '.$error); + throw new Exception($error); + } + /** * Load translation domain from Gettext/Gettext using .po @@ -87,14 +119,23 @@ class Localization * @param string $domain Name of domain */ private function loadGettextGettextFromPO($domain = self::DEFAULT_DOMAIN) { - $langcode = explode('_', $this->langcode); - $langcode = $langcode[0]; - $localeDir = $this->localeDomainMap[$domain]; - $poPath = $localeDir.'/'.$langcode.'/LC_MESSAGES/'.$domain.'.po'; - $translations = Translations::fromPoFile($poPath); $t = new Translator(); - $t->loadTranslations($translations); $t->register(); + try { + $langPath = $this->getLangPath($domain); + } catch (\Exception $e) { + // bail out! + return; + } + $poFile = $domain.'.po'; + $poPath = $langPath.$poFile; + if (file_exists($poPath) && is_readable($poPath)) { + $translations = Translations::fromPoFile($poPath); + $t->loadTranslations($translations); + } else { + $error = "Localization file '$poFile' not found in '$langPath', falling back to default"; + \SimpleSAML_Logger::error($_SERVER['PHP_SELF'].' - '.$error); + } } -- GitLab