From 011695dfdf52e7a83f0eeceb85d0d2c06e7df7da Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sat, 20 Apr 2019 18:14:32 -0400 Subject: Support Unicode in filenames (fixes #298) --- libqpdf/QUtil.cc | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'libqpdf') diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc index 7ea3f5e7..816c2dfa 100644 --- a/libqpdf/QUtil.cc +++ b/libqpdf/QUtil.cc @@ -354,11 +354,42 @@ FILE* QUtil::safe_fopen(char const* filename, char const* mode) { FILE* f = 0; +#ifdef _WIN32 + // Convert the utf-8 encoded filename argument to wchar_t*. First, + // convert to utf16, then to wchar_t*. Note that u16 will start + // with the UTF16 marker, which we skip. + std::string u16 = utf8_to_utf16(filename); + size_t len = u16.length(); + size_t wlen = (len / 2) - 1; + PointerHolder wfilenamep(true, new wchar_t[wlen + 1]); + wchar_t* wfilename = wfilenamep.getPointer(); + wfilename[wlen] = 0; + for (unsigned int i = 2; i < len; i += 2) + { + wfilename[(i/2) - 1] = + static_cast( + (static_cast(u16.at(i)) << 8) + + static_cast(u16.at(i+1))); + } + PointerHolder wmodep(true, new wchar_t(strlen(mode) + 1)); + wchar_t* wmode = wmodep.getPointer(); + wmode[strlen(mode)] = 0; + for (size_t i = 0; i < strlen(mode); ++i) + { + wmode[i] = mode[i]; + } + #ifdef _MSC_VER - errno_t err = fopen_s(&f, filename, mode); + errno_t err = _wfopen_s(&f, wfilename, wmode); if (err != 0) { errno = err; + } +#else + f = _wfopen(wfilename, wmode); +#endif + if (f == 0) + { throw_system_error(std::string("open ") + filename); } #else -- cgit v1.2.3-70-g09d2