From 17ac4753fd5248477a7d4960fd6cea6a50fc3575 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Fri, 3 Dec 2010 00:27:41 +0000 Subject: [PATCH] BUGFIX Check for valid locale in i18n::set_locale()/set_default_locale()/include_locale_file()/include_by_locale() (as defined in i18n::$allowed_locales). Implicitly sanitizes the data for usage in controllers. git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@114469 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- core/i18n.php | 28 ++++++++++++++++++++++++++++ tests/i18n/i18nTest.php | 8 ++++++++ 2 files changed, 36 insertions(+) diff --git a/core/i18n.php b/core/i18n.php index 2538bccf0..0e026a195 100755 --- a/core/i18n.php +++ b/core/i18n.php @@ -1714,6 +1714,26 @@ class i18n extends Object { return (isset($module)) ? $module[1] : false; } + + /** + * Validates a "long" locale format (e.g. "en_US") + * by checking it against {@link $all_locales}. + * + * To add a locale to {@link $all_locales}, use the following example + * in your mysite/_config.php: + * + * i18n::$allowed_locales['xx_XX'] = ''; + * + * + * Note: Does not check for {@link $allowed_locales}. + * + * @return boolean + */ + static function validate_locale($locale) { + // Convert en-US to en_US + $locale = str_replace('-', '_', $locale); + return (array_key_exists($locale, self::$all_locales)); + } /** * Set the current locale @@ -1722,6 +1742,8 @@ class i18n extends Object { * @param string $locale Locale to be set */ static function set_locale($locale) { + if(!self::validate_locale($locale)) throw new InvalidArgumentException(sprintf('Invalid locale "%s"', $locale)); + if ($locale) self::$current_locale = $locale; } @@ -1764,6 +1786,8 @@ class i18n extends Object { * @param String $locale */ static function set_default_locale($locale) { + if(!self::validate_locale($locale)) throw new InvalidArgumentException(sprintf('Invalid locale "%s"', $locale)); + self::$default_locale = $locale; } @@ -1792,6 +1816,8 @@ class i18n extends Object { * @param string $locale Locale to be loaded */ static function include_locale_file($module, $locale) { + if(!self::validate_locale($locale)) throw new InvalidArgumentException(sprintf('Invalid locale "%s"', $locale)); + if (file_exists($file = Director::getAbsFile("$module/lang/$locale.php"))) include_once($file); } @@ -1806,6 +1832,8 @@ class i18n extends Object { * and may need to reload them. */ static function include_by_locale($locale, $load_plugins = true, $force_load = false) { + if(!self::validate_locale($locale)) throw new InvalidArgumentException(sprintf('Invalid locale "%s"', $locale)); + global $lang; $base = Director::baseFolder(); diff --git a/tests/i18n/i18nTest.php b/tests/i18n/i18nTest.php index 083556a17..452f84e48 100644 --- a/tests/i18n/i18nTest.php +++ b/tests/i18n/i18nTest.php @@ -260,6 +260,14 @@ class i18nTest extends SapphireTest { $lang = $oldLang; } + + function testValidateLocale() { + $this->assertTrue(i18n::validate_locale('en_US'), 'Known locale in underscore format is valid'); + $this->assertTrue(i18n::validate_locale('en-US'), 'Known locale in dash format is valid'); + $this->assertFalse(i18n::validate_locale('en'), 'Short lang format is not valid'); + $this->assertFalse(i18n::validate_locale('xx_XX'), 'Unknown locale in correct format is not valid'); + $this->assertFalse(i18n::validate_locale(''), 'Empty string is not valid'); + } static function translationTestPlugin($locale) { $result = array();