• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

LibreSign / libresign / 32993735329

26 Aug 2026 05:19PM UTC coverage: 68.022% (+22.7%) from 45.341%
32993735329

push

github

web-flow
Merge pull request #8072 from LibreSign/chore/say-hello-to-nextcloud36

chore: say hello to Nextcloud 36

16292 of 23951 relevant lines covered (68.02%)

11.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.09
/lib/Helper/JavaHelper.php
1
<?php
2

3
declare(strict_types=1);
4
/**
5
 * SPDX-FileCopyrightText: 2025 LibreCode coop and contributors
6
 * SPDX-FileCopyrightText: 2023 Nextcloud GmbH <https://github.com/nextcloud/server>
7
 * SPDX-License-Identifier: AGPL-3.0-or-later
8
 */
9

10
namespace OCA\Libresign\Helper;
11

12
use OCA\Libresign\AppInfo\Application;
13
use OCP\IAppConfig;
14
use OCP\IL10N;
15
use Psr\Log\LoggerInterface;
16

17
class JavaHelper {
18
        private bool $isInitialized = false;
19
        public function __construct(
20
                protected IAppConfig $appConfig,
21
                protected IL10N $l10n,
22
                protected LoggerInterface $logger,
23
        ) {
24
        }
62✔
25

26
        public function init(): void {
27
                if ($this->isInitialized) {
4✔
28
                        return;
×
29
                }
30
                if ($this->isNonUTF8Locale()) {
4✔
31
                        $this->initializeUtf8Locale();
2✔
32
                }
33
                $this->isInitialized = true;
4✔
34
        }
35

36
        private function initializeUtf8Locale(): void {
37
                $originalLang = getenv('LANG');
2✔
38
                $originalLocale = setlocale(LC_CTYPE, '0');
2✔
39
                $attemptedLocales = $this->getUtf8LocaleCandidates();
2✔
40

41
                foreach ($attemptedLocales as $locale) {
2✔
42
                        putenv('LANG=' . $locale);
2✔
43
                        setlocale(LC_CTYPE, $locale, 'UTF-8');
2✔
44
                        if (!$this->isNonUTF8Locale()) {
2✔
45
                                return;
1✔
46
                        }
47
                }
48

49
                $this->restoreOriginalLocaleEnvironment($originalLang, $originalLocale);
1✔
50
                $this->logger->warning(sprintf(
1✔
51
                        'JavaHelper: setlocale did not work properly after attempting locales: %s',
1✔
52
                        implode(', ', $attemptedLocales)
1✔
53
                ));
1✔
54
        }
55

56
        /**
57
         * @return list<string>
58
         */
59
        private function getUtf8LocaleCandidates(): array {
60
                $localeCode = trim(str_replace('-', '_', $this->l10n->getLocaleCode()));
2✔
61
                $candidates = [];
2✔
62

63
                if ($localeCode !== '') {
2✔
64
                        if (preg_match('/^[A-Za-z]{2,3}_[A-Za-z]{2}$/', $localeCode) === 1) {
1✔
65
                                [$language, $region] = explode('_', $localeCode, 2);
1✔
66
                                $candidates[] = sprintf('%s_%s.UTF-8', strtolower($language), strtoupper($region));
1✔
67
                                $candidates[] = sprintf('%s_%s.utf8', strtolower($language), strtoupper($region));
1✔
68
                        } elseif (preg_match('/^[A-Za-z]{2,3}$/', $localeCode) === 1) {
×
69
                                $language = strtolower($localeCode);
×
70
                                $candidates[] = sprintf('%s_%s.UTF-8', $language, strtoupper($language));
×
71
                                $candidates[] = $language . '.UTF-8';
×
72
                        }
73
                }
74

75
                $candidates[] = 'C.UTF-8';
2✔
76
                $candidates[] = 'UTF-8';
2✔
77

78
                return array_values(array_unique($candidates));
2✔
79
        }
80

81
        private function restoreOriginalLocaleEnvironment(string|false $originalLang, string|false $originalLocale): void {
82
                if ($originalLang === false) {
1✔
83
                        putenv('LANG');
×
84
                } else {
85
                        putenv('LANG=' . $originalLang);
1✔
86
                }
87

88
                if (is_string($originalLocale) && $originalLocale !== '') {
1✔
89
                        setlocale(LC_CTYPE, $originalLocale);
1✔
90
                }
91
        }
92

93
        /**
94
         * Check if current locale is non-UTF8
95
         *
96
         * Based on: https://github.com/nextcloud/server/blob/cf1eed2769d928f4a7fe4543d51994331701f2d9/lib/private/legacy/OC_Util.php#L692-L705
97
         *
98
         * @return bool
99
         */
100
        protected function isNonUTF8Locale(): bool {
101
                if (function_exists('escapeshellcmd')) {
×
102
                        return escapeshellcmd('§') === '';
×
103
                }
104
                if (function_exists('escapeshellarg')) {
×
105
                        return escapeshellarg('§') === '\'\'';
×
106
                }
107
                return preg_match('/utf-?8/i', setlocale(LC_CTYPE, '0')) === 0;
×
108
        }
109

110
        /**
111
         * Returns the configured Java binary path.
112
         * Initializes the environment if needed.
113
         */
114
        public function getJavaPath(): string {
115
                if (!$this->isInitialized) {
1✔
116
                        $this->init();
1✔
117
                }
118
                return $this->appConfig->getValueString(Application::APP_ID, 'java_path');
1✔
119
        }
120
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc