Encoding: Use encoding libcurl expects with file: urls.

For unescaped file: URLs on Windows, libcurl expects
the ANSI code page.

This fixes the CMake.FileUpload test when CMake is configured
to use UTF-8 internally with a non-ascii build directory name.
This commit is contained in:
Clinton Stimpson 2014-11-05 07:16:29 -07:00
parent d5a373a10d
commit e63dcb1378
1 changed files with 38 additions and 0 deletions

View File

@ -33,6 +33,7 @@
#include <cmsys/Glob.hxx> #include <cmsys/Glob.hxx>
#include <cmsys/RegularExpression.hxx> #include <cmsys/RegularExpression.hxx>
#include <cmsys/FStream.hxx> #include <cmsys/FStream.hxx>
#include <cmsys/Encoding.hxx>
// Table of permissions flags. // Table of permissions flags.
#if defined(_WIN32) && !defined(__CYGWIN__) #if defined(_WIN32) && !defined(__CYGWIN__)
@ -61,6 +62,35 @@ static mode_t mode_setuid = S_ISUID;
static mode_t mode_setgid = S_ISGID; static mode_t mode_setgid = S_ISGID;
#endif #endif
#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8)
// libcurl doesn't support file:// urls for unicode filenames on Windows.
// Convert string from UTF-8 to ACP if this is a file:// URL.
static std::string fix_file_url_windows(const std::string& url)
{
std::string ret = url;
if(strncmp(url.c_str(), "file://", 7) == 0)
{
cmsys_stl::wstring wurl = cmsys::Encoding::ToWide(url);
if(!wurl.empty())
{
int mblen = WideCharToMultiByte(CP_ACP, 0, wurl.c_str(), -1,
NULL, 0, NULL, NULL);
if(mblen > 0)
{
std::vector<char> chars(mblen);
mblen = WideCharToMultiByte(CP_ACP, 0, wurl.c_str(), -1,
&chars[0], mblen, NULL, NULL);
if(mblen > 0)
{
ret = &chars[0];
}
}
}
}
return ret;
}
#endif
// cmLibraryCommand // cmLibraryCommand
bool cmFileCommand bool cmFileCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
@ -2988,6 +3018,10 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
return false; return false;
} }
#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8)
url = fix_file_url_windows(url);
#endif
::CURL *curl; ::CURL *curl;
::curl_global_init(CURL_GLOBAL_DEFAULT); ::curl_global_init(CURL_GLOBAL_DEFAULT);
curl = ::curl_easy_init(); curl = ::curl_easy_init();
@ -3250,6 +3284,10 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
unsigned long file_size = cmsys::SystemTools::FileLength(filename.c_str()); unsigned long file_size = cmsys::SystemTools::FileLength(filename.c_str());
#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8)
url = fix_file_url_windows(url);
#endif
::CURL *curl; ::CURL *curl;
::curl_global_init(CURL_GLOBAL_DEFAULT); ::curl_global_init(CURL_GLOBAL_DEFAULT);
curl = ::curl_easy_init(); curl = ::curl_easy_init();