|
|
|
|
@ -133,10 +133,7 @@ class Factory implements IFactory {
|
|
|
|
|
public function get($app, $lang = null, $locale = null) {
|
|
|
|
|
return new LazyL10N(function () use ($app, $lang, $locale) {
|
|
|
|
|
$app = \OC_App::cleanAppId($app);
|
|
|
|
|
if ($lang !== null) {
|
|
|
|
|
$lang = str_replace(['\0', '/', '\\', '..'], '', $lang);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$lang = $this->cleanLanguage($lang);
|
|
|
|
|
$forceLang = $this->config->getSystemValue('force_language', false);
|
|
|
|
|
if (is_string($forceLang)) {
|
|
|
|
|
$lang = $forceLang;
|
|
|
|
|
@ -169,6 +166,29 @@ class Factory implements IFactory {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Remove some invalid characters before using a string as a language
|
|
|
|
|
*
|
|
|
|
|
* @psalm-taint-escape callable
|
|
|
|
|
* @psalm-taint-escape cookie
|
|
|
|
|
* @psalm-taint-escape file
|
|
|
|
|
* @psalm-taint-escape has_quotes
|
|
|
|
|
* @psalm-taint-escape header
|
|
|
|
|
* @psalm-taint-escape html
|
|
|
|
|
* @psalm-taint-escape include
|
|
|
|
|
* @psalm-taint-escape ldap
|
|
|
|
|
* @psalm-taint-escape shell
|
|
|
|
|
* @psalm-taint-escape sql
|
|
|
|
|
* @psalm-taint-escape unserialize
|
|
|
|
|
*/
|
|
|
|
|
private function cleanLanguage(?string $lang): ?string {
|
|
|
|
|
if ($lang === null) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
$lang = preg_replace('/[^a-zA-Z0-9.;,=-]/', '', $lang);
|
|
|
|
|
return str_replace('..', '', $lang);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Find the best language
|
|
|
|
|
*
|
|
|
|
|
@ -478,7 +498,7 @@ class Factory implements IFactory {
|
|
|
|
|
* @throws LanguageNotFoundException
|
|
|
|
|
*/
|
|
|
|
|
private function getLanguageFromRequest(?string $app = null): string {
|
|
|
|
|
$header = $this->request->getHeader('ACCEPT_LANGUAGE');
|
|
|
|
|
$header = $this->cleanLanguage($this->request->getHeader('ACCEPT_LANGUAGE'));
|
|
|
|
|
if ($header !== '') {
|
|
|
|
|
$available = $this->findAvailableLanguages($app);
|
|
|
|
|
|
|
|
|
|
|