pydio / pydio-core

Pydio 8 official repository
https://pydio.com
GNU Affero General Public License v3.0
868 stars 289 forks source link

Can't upload file to access.fs repo if filename length exceeds fs limit #1296

Open sespivak opened 7 years ago

sespivak commented 7 years ago

If length of filename for uploaded file exceeds fs limit, file silently not appers at destination folder.

This error generated in log:

ERROR class.fsAccessDriver.php error l.1344 message=move_uploaded_file(/pydio_data_path/path_to_file/long_file_name: failed to open stream: File name too long

NODENAME_MAX_LENGTH is set to 255

The reason of this bug is that for most filesystems filename limits is in bytes, not in characters. For example:

BTRFS 255 bytes exFAT 255 UTF-16 characters - it works ok ext2 255 bytes ext3 255 bytes ext3cow 255 bytes ext4 255 bytes FAT32 8.3 (255 UCS-2 code units with VFAT LFNs) NTFS 255 characters - it works ok too XFS 255 bytes

NODENAME_MAX_LENGTH is used to get filename substring in characters, not in bytes.

This patch works for me:

$max_length = ConfService::getCoreConf("NODENAME_MAX_LENGTH");
$userfile_name = SystemTextEncoding::fromUTF8(mb_strcut(SystemTextEncoding::toUTF8($userfile_name), 0, $max_length, "UTF8"));
if (mb_strlen($userfile_name, '8bit') == $max_length) {
    $userfile_name = substr($userfile_name, 0, strlen($userfile_name) - 1);
}

instead of:

$userfile_name = substr($userfile_name, 0, ConfService::getCoreConf("NODENAME_MAX_LENGTH"));

in class.fsAccessDriver.php

Other code using NODENAME_MAX_LENGTH should be patched too.

Testcases:

"03 Указ о присвоении крепости звания «Крепость-герой». Мемориальный комплекс «Брестская крепость-герой», Брест, Беларусь. (автор фото тест).jpg" - not uploaded, but filename length is only 143 characters. Expected behaviour: filename is cropped to 255 bytes and file uploaded.

"03 Указ о присвоении крепости звания «Крепость-герой». Мемориальный комплекс «Брестская крепость-герой», Брест, Беларусь. (автор фото тест).j" - uploaded normally

Tested 24 Nov 2016 on http://demo.pydio.com/ as admin/admin

cdujeu commented 7 years ago

Hi, can you eventually submit a Pull Request ?

7omate commented 7 years ago

Not sure what's the status here... Just for reference

php -r 'echo strlen("03 Указ о присвоении крепости звания «Крепость-герой». Мемориальный комплекс «Брестская крепость-герой», Брест, Беларусь. (автор фото тест).jpg");'

257

php -r 'echo strlen(utf8_decode("03 Указ о присвоении крепости звания «Крепость-герой». Мемориальный комплекс «Брестская крепость-герой», Брест, Беларусь. (автор фото тест).jpg"));'

143

sespivak commented 7 years ago

Hi, can you eventually submit a Pull Request ?

ready: https://github.com/pydio/pydio-core/pull/1297 @cdujeu

7omate commented 7 years ago

Hi, I think names too long should ERROR and force the user to rename the file before upload.

I don't think auto cropping filenames is a good idea. It will make the sync impossible between systems with different limitations.

I think NODENAME_MAX_LENGTH should be detected automatically depending on where the upload is suppose to happen (maybe with something like getconf NAME_MAX /upload_folder)

But code is law, I don't know where to check the filename and throw an error, so your call guys.