hexchat/hexchat — pull request #180 by Arnavion (2012-10-23 02:17:32+00:00)
Title: Fix filename encoding error for DCC transfers of files with non-ASCII characters in their name

(Reopened https://github.com/hexchat/hexchat/pull/179 after rebasing on HEAD.)

The original code maintained two filenames in the DCC structure. One was in utf8 and one was in the OS codepage. It then used ```g_locale_from/to_utf8``` on Windows and ```g_filename_from/to_utf8``` elsewhere, and used native OS API ```open``` and ```stat``` with the filename.

On my system (Windows 7, Japanese system locale), ```g_locale_from_utf8``` doesn't actually work for filenames (```G_CONVERT_ERROR_ILLEGAL_SEQUENCE```). It borks on all non-ASCII characters. Hexchat either crashes (only happens in my build, not on official) trying to dereference ```dcc->destfile_fs``` which is a nullptr, or throws up an error that the filename encoding is incorrect.

The reason I imagine it was done in the original code this way is that it uses POSIX file API directly with the string in ```dcc->destfile_fs```. I've instead changed all uses of ```dcc->destfile_fs``` + OS-native file API (```open```, ```stat```) to ```dcc->destfile``` and GLib file API (```g_open```, ```g_stat```), since GLib's file API works with UTF-8 and handles converting to the OS codepage itself.

Another change needed to work with ```g_stat``` in place of regular ```stat``` is that g_stat works with ```GStatBuf``` instead of the OS's ```struct stat```. This matters because on Windows, the two differ in the size of the filesize (32 vs 64 bits). Using ```struct stat``` with ```g_stat``` breaks DCC resume.

A minor change was to fix filenames being generated by concatenating ```'/'``` to the directory instead of the OS-specific directory separator. GLib already has two constants for this, so I've replaced some cases of ```#ifdef WIN32 '\\' #else '/' #endif``` with those.

I've tested with filenames containing entirely regular ASCII characters and containing non-ASCII characters. Filenames are correct on the file system. Filenames are logged correctly in the chat window. DCC resume works. The feature where if the file is completely downloaded, Hexchat starts downloading from the beginning as .1, etc. also works.

I have not tested this on Unix yet. I'm doing that now.