From e9b414fbe39eea609c5cfdfb0266527977495802 Mon Sep 17 00:00:00 2001 From: Naoto Kobayashi Date: Tue, 16 Nov 2021 00:40:52 +0900 Subject: [PATCH] OC_Util: Add fallbacks to check if current locale is UTF8 Using escapeshellcmd to get current locale causes error if the function is disabled. Add fallbacks to prevent the error. Signed-off-by: Naoto Kobayashi --- lib/private/legacy/OC_Util.php | 19 +++++++++++++++++-- tests/lib/UtilTest.php | 6 ++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/lib/private/legacy/OC_Util.php b/lib/private/legacy/OC_Util.php index 75c337f8baa..ff9a3bb1af7 100644 --- a/lib/private/legacy/OC_Util.php +++ b/lib/private/legacy/OC_Util.php @@ -1238,6 +1238,21 @@ class OC_Util { return $content !== $testContent && $fallbackContent !== $testContent; } + /** + * Check if current locale is non-UTF8 + * + * @return bool + */ + private static function isNonUTF8Locale() { + if (function_exists("escapeshellcmd")) { + return ('' === escapeshellcmd('§')); + } else if (function_exists("escapeshellarg")) { + return ('\'\'' === escapeshellarg('§')); + } else { + return (0 === preg_match('/utf-?8/i', setlocale(LC_CTYPE, 0))); + } + } + /** * Check if the setlocal call does not work. This can happen if the right * local packages are not available on the server. @@ -1245,13 +1260,13 @@ class OC_Util { * @return bool */ public static function isSetLocaleWorking() { - if ('' === escapeshellcmd('§')) { + if (self::isNonUTF8Locale()) { // Borrowed from \Patchwork\Utf8\Bootup::initLocale setlocale(LC_ALL, 'C.UTF-8', 'C'); setlocale(LC_CTYPE, 'en_US.UTF-8', 'fr_FR.UTF-8', 'es_ES.UTF-8', 'de_DE.UTF-8', 'ru_RU.UTF-8', 'pt_BR.UTF-8', 'it_IT.UTF-8', 'ja_JP.UTF-8', 'zh_CN.UTF-8', '0'); // Check again - if ('' === escapeshellcmd('§')) { + if (self::isNonUTF8Locale()) { return false; } } diff --git a/tests/lib/UtilTest.php b/tests/lib/UtilTest.php index 65147ed52c9..bb328c5998d 100644 --- a/tests/lib/UtilTest.php +++ b/tests/lib/UtilTest.php @@ -74,13 +74,15 @@ class UtilTest extends \Test\TestCase { $this->assertEquals("/%C2%A7%23%40test%25%26%5E%C3%A4/-child", $result); } - public function testIsSetLocaleWorking() { - // OC_Util::isSetLocaleWorking() assumes escapeshellcmd('§') returns '' with non-UTF-8 locale. + public function testIsNonUTF8Locale() { + // OC_Util::isNonUTF8Locale() assumes escapeshellcmd('§') returns '' with non-UTF-8 locale. $locale = setlocale(LC_CTYPE, 0); setlocale(LC_CTYPE, 'C'); $this->assertEquals('', escapeshellcmd('§')); + $this->assertEquals('\'\'', escapeshellarg('§')); setlocale(LC_CTYPE, 'C.UTF-8'); $this->assertEquals('§', escapeshellcmd('§')); + $this->assertEquals('\'§\'', escapeshellarg('§')); setlocale(LC_CTYPE, $locale); } -- 2.39.5