Skip to content

Commit b8318c2

Browse files
authored
Merge pull request #29737 from nextcloud/backport/29695/stable23
[stable23] Fix missing setlocale with php 8
2 parents a80d49a + acece8f commit b8318c2

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

lib/private/legacy/OC_Util.php

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,22 +1239,38 @@ public function isHtaccessWorking(\OCP\IConfig $config) {
12391239
}
12401240

12411241
/**
1242-
* Check if the setlocal call does not work. This can happen if the right
1242+
* Check if current locale is non-UTF8
1243+
*
1244+
* @return bool
1245+
*/
1246+
private static function isNonUTF8Locale() {
1247+
if (function_exists('escapeshellcmd')) {
1248+
return '' === escapeshellcmd('§');
1249+
} elseif (function_exists('escapeshellarg')) {
1250+
return '\'\'' === escapeshellarg('§');
1251+
} else {
1252+
return 0 === preg_match('/utf-?8/i', setlocale(LC_CTYPE, 0));
1253+
}
1254+
}
1255+
1256+
/**
1257+
* Check if the setlocale call does not work. This can happen if the right
12431258
* local packages are not available on the server.
12441259
*
12451260
* @return bool
12461261
*/
12471262
public static function isSetLocaleWorking() {
1248-
if ('' === basename('§')) {
1263+
if (self::isNonUTF8Locale()) {
12491264
// Borrowed from \Patchwork\Utf8\Bootup::initLocale
12501265
setlocale(LC_ALL, 'C.UTF-8', 'C');
12511266
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');
1252-
}
12531267

1254-
// Check again
1255-
if ('' === basename('§')) {
1256-
return false;
1268+
// Check again
1269+
if (self::isNonUTF8Locale()) {
1270+
return false;
1271+
}
12571272
}
1273+
12581274
return true;
12591275
}
12601276

tests/lib/UtilTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,18 @@ public function testEncodePath() {
7474
$this->assertEquals("/%C2%A7%23%40test%25%26%5E%C3%A4/-child", $result);
7575
}
7676

77+
public function testIsNonUTF8Locale() {
78+
// OC_Util::isNonUTF8Locale() assumes escapeshellcmd('§') returns '' with non-UTF-8 locale.
79+
$locale = setlocale(LC_CTYPE, 0);
80+
setlocale(LC_CTYPE, 'C');
81+
$this->assertEquals('', escapeshellcmd('§'));
82+
$this->assertEquals('\'\'', escapeshellarg('§'));
83+
setlocale(LC_CTYPE, 'C.UTF-8');
84+
$this->assertEquals('§', escapeshellcmd('§'));
85+
$this->assertEquals('\'§\'', escapeshellarg('§'));
86+
setlocale(LC_CTYPE, $locale);
87+
}
88+
7789
public function testFileInfoLoaded() {
7890
$expected = function_exists('finfo_open');
7991
$this->assertEquals($expected, \OC_Util::fileInfoLoaded());

0 commit comments

Comments
 (0)