Skip to content

Handle unicode filenames in FTP - #3064

Open
julianoes wants to merge 2 commits into
mainfrom
pr-ftp-unicode
Open

Handle unicode filenames in FTP#3064
julianoes wants to merge 2 commits into
mainfrom
pr-ftp-unicode

Conversation

@julianoes

Copy link
Copy Markdown
Collaborator

Filenames with emojis and other non-ASCII characters were never exercised over MAVLink FTP, so this tries them out in system_tests and fixes the one thing that turned out to be broken.

Tests (src/system_tests/ftp_unicode.cpp)

  • upload, download and CRC compare of 🚁 flight-log 🛰️.bin inside a directory called flights 🛫
  • listing a directory holding emoji, Japanese, Cyrillic and combining-accent names (mixed NFC/NFD, to check names are passed on byte for byte without normalization)
  • rename ASCII → unicode → unicode, plus remove file/directory with such names
  • a name that doesn't fit into the 239 byte payload is rejected with InvalidParameter rather than being cut in the middle of a code point, while a name that just fits still works

Everything above already worked, since to the protocol these are just UTF-8 bytes and the client validates lengths before it copies.

Fix

The last test found a real bug, which is not unicode specific but much easier to hit with it (each emoji is 4 bytes): a directory entry that doesn't fit into an empty payload — e.g. a 240 byte filename, which is perfectly legal on ext4 — made the server break out of the loop with nothing written, so it responded with EOF. The client took that as the end of the listing, and the long entry and every entry after it stayed invisible.

The server now emits a skip entry ('S') for such an entry, which the client already counts towards the offset, so the listing moves past it and the rest of the directory shows up.

Not covered

On Windows, std::filesystem::path's narrow conversions use the ANSI code page, so UTF-8 names would likely mangle there. The system tests only run on Linux and macOS (and hardcode /tmp), so this is untested and unchanged here.

Emojis, Japanese, Cyrillic and combining accents in filenames are all just
UTF-8 bytes to the FTP protocol, but nothing checked that they survive a
round trip.

These tests upload, download, list, rename and remove files and directories
with such names, and check that a name which doesn't fit into the 239 byte
payload is rejected instead of being cut in the middle of a code point.
A directory entry which doesn't fit into an empty payload, e.g. a file with
a 240 byte name, made the server respond with EOF at that offset. The client
took that as the end of the listing, so the long entry and everything after
it stayed invisible.

Send a skip entry ('S') for such an entry instead so the offset advances and
the rest of the directory is listed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant