MDL-74097 core_text: Ensure that transliteration always happens

Before the patch, transliteration was only happening when the
encoding of the string was utf-8. For other encodings only a
simpler conversion (iconv) to ascii was done. For some reason
iconv() own transliteration abilities are not consistent
between systems (depends of libraries installed, locales and
other bits).

So now we always convert the string to utf-8, in order to
transliterate it. And finally, also perform an iconv to
cover some characters that transliterate doesn't handle ok.

Also, remove a block of code that does nothing (previously
it was executing some code, but now it just sets and restores
the error level for nothing).
This commit is contained in:
Eloy Lafuente (stronk7)
2022-03-08 10:37:47 +01:00
parent 01eb6d2e9b
commit 2def80568b
+10 -14
View File
@@ -158,21 +158,13 @@ class core_text {
}
if ($toCS === 'ascii') {
// Try to normalize the conversion a bit.
$text = self::specialtoascii($text, $fromCS);
// Try to normalize the conversion a bit if the target is ascii.
return self::specialtoascii($text, $fromCS);
}
// Prevent any error notices, do not use //IGNORE so that we get
// consistent result if iconv fails.
$result = @iconv($fromCS, $toCS.'//TRANSLIT', $text);
if ($result === false or $result === '') {
// Note: iconv is prone to return empty string when invalid char encountered, or false if encoding unsupported.
$oldlevel = error_reporting(E_PARSE);
error_reporting($oldlevel);
}
return $result;
return @iconv($fromCS, $toCS.'//TRANSLIT', $text);
}
/**
@@ -341,10 +333,14 @@ class core_text {
$charset = self::parse_charset($charset);
$oldlevel = error_reporting(E_PARSE);
if ($charset == 'utf-8') {
$text = transliterator_transliterate('Any-Latin; Latin-ASCII', (string) $text);
// Always convert to utf-8, so transliteration can do its work always.
if ($charset !== 'utf-8') {
$text = iconv($charset, 'utf-8'.'//TRANSLIT', $text);
}
$result = iconv($charset, 'ASCII//TRANSLIT//IGNORE', (string) $text);
$text = transliterator_transliterate('Any-Latin; Latin-ASCII', (string) $text);
// Still, apply iconv because some chars are not handled by transliterate.
$result = iconv('utf-8', 'ASCII//TRANSLIT//IGNORE', (string) $text);
error_reporting($oldlevel);
return $result;