From bd0818b7e123cebb57768f652c503d0833a1a373 Mon Sep 17 00:00:00 2001 From: ralf Date: Thu, 20 Jun 2024 12:29:13 +0200 Subject: [PATCH] * Filemanager: automatic shorten too long filenames and replace 4-byte utf-8 characters, which gave an error when trying to store VFS --- api/src/Vfs.php | 13 +++++++++++++ api/src/Vfs/Sqlfs/StreamWrapper.php | 12 +++++++++++- filemanager/inc/class.filemanager_ui.inc.php | 2 +- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/api/src/Vfs.php b/api/src/Vfs.php index 1809cf7b08..86b193f934 100644 --- a/api/src/Vfs.php +++ b/api/src/Vfs.php @@ -1795,6 +1795,19 @@ class Vfs extends Vfs\Base return str_replace(array_keys(self::$encode),array_values(self::$encode),$component); } + /** + * Limit filename to precision of column while keeping the extension + * + * Also takes care to replace 4-byte utf-8 chars e.g. used in some Emojis with a replacement character. + * + * @param string $name + * @return string + */ + static public function limitFilename($name) + { + return Vfs\Sqlfs\StreamWrapper::limit_filename($name); + } + /** * Encode a path: replacing certain chars with their urlencoded counterparts * diff --git a/api/src/Vfs/Sqlfs/StreamWrapper.php b/api/src/Vfs/Sqlfs/StreamWrapper.php index 326549c9a7..6dc83c2e86 100644 --- a/api/src/Vfs/Sqlfs/StreamWrapper.php +++ b/api/src/Vfs/Sqlfs/StreamWrapper.php @@ -1767,16 +1767,26 @@ GROUP BY A.fs_id'; /** * Limit filename to precision of column while keeping the extension * + * Also takes care to replace 4-byte utf-8 chars e.g. used in some Emojis with a replacement character. + * * @param string $name * @return string */ - static protected function limit_filename($name) + static public function limit_filename($name) { static $fs_name_precision = null; if (!isset($fs_name_precision)) { $fs_name_precision = $GLOBALS['egw']->db->get_column_attribute('fs_name', self::TABLE, 'phpgwapi', 'precision'); } + // MySQL and MariaDB not 10.1 need 4-byte utf8 chars replaced with our default utf8 charset + // (MariaDB 10.1 does the replacement automatic, 10.0 cuts everything off behind and MySQL gives an error) + // (MariaDB 10.3 gives an error too: Incorrect string value: '\xF0\x9F\x98\x8A\x0AW...') + // Changing charset to utf8mb4 requires schema update, shortening of some indexes and probably have negative impact on performance! + if (isset($name) && substr($GLOBALS['egw']->db->Type, 0, 5) === 'mysql') + { + $name = preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $name); + } if (mb_strlen($name) > $fs_name_precision) { $parts = explode('.', $name); diff --git a/filemanager/inc/class.filemanager_ui.inc.php b/filemanager/inc/class.filemanager_ui.inc.php index 8e5d36e7b2..f169e5fdf3 100644 --- a/filemanager/inc/class.filemanager_ui.inc.php +++ b/filemanager/inc/class.filemanager_ui.inc.php @@ -1755,7 +1755,7 @@ class filemanager_ui foreach($selected as $tmp_name => &$data) { - $path = Vfs::concat($dir, Vfs::encodePathComponent($data['name'])); + $path = Vfs::concat($dir, Vfs::limitFilename(Vfs::encodePathComponent($data['name']))); if(Vfs::deny_script($path)) {