Skip to content

Commit

Permalink
WIN32: stop forcing narrow-character API
Browse files Browse the repository at this point in the history
Except where the results are only used for character output or with
hardcoded string literals.

Fixes curl#5658
Fixes curl#5712
Closes
  • Loading branch information
MarcelRaad committed Jul 24, 2020
1 parent 13030d0 commit 132cbe4
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 20 deletions.
20 changes: 14 additions & 6 deletions lib/getenv.c
Expand Up @@ -23,6 +23,7 @@
#include "curl_setup.h"

#include <curl/curl.h>
#include "curl_multibyte.h"
#include "curl_memory.h"

#include "memdebug.h"
Expand All @@ -35,16 +36,18 @@ static char *GetEnv(const char *variable)
#elif defined(WIN32)
/* This uses Windows API instead of C runtime getenv() to get the environment
variable since some changes aren't always visible to the latter. #4774 */
char *buf = NULL;
char *tmp;
TCHAR *buf = NULL;
TCHAR *tmp;
DWORD bufsize;
DWORD rc = 1;
const DWORD max = 32768; /* max env var size from MSCRT source */
TCHAR *tchar_envvar = curlx_convert_UTF8_to_tchar((char *)variable);

for(;;) {
tmp = realloc(buf, rc);
tmp = realloc(buf, rc * sizeof(TCHAR));
if(!tmp) {
free(buf);
curlx_unicodefree(tchar_envvar);
return NULL;
}

Expand All @@ -53,15 +56,20 @@ static char *GetEnv(const char *variable)

/* It's possible for rc to be 0 if the variable was found but empty.
Since getenv doesn't make that distinction we ignore it as well. */
rc = GetEnvironmentVariableA(variable, buf, bufsize);
rc = GetEnvironmentVariable(tchar_envvar, buf, bufsize);
if(!rc || rc == bufsize || rc > max) {
free(buf);
curlx_unicodefree(tchar_envvar);
return NULL;
}

/* if rc < bufsize then rc is bytes written not including null */
if(rc < bufsize)
return buf;
if(rc < bufsize) {
char *path = curlx_convert_tchar_to_UTF8(buf);
curlx_unicodefree(buf);
curlx_unicodefree(tchar_envvar);
return path;
}

/* else rc is bytes needed, try again */
}
Expand Down
15 changes: 12 additions & 3 deletions lib/rename.c
Expand Up @@ -27,6 +27,7 @@
#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)) || \
defined(USE_ALTSVC)

#include "curl_multibyte.h"
#include "timeval.h"

/* The last 3 #include files should be in this order */
Expand All @@ -39,17 +40,25 @@ int Curl_rename(const char *oldpath, const char *newpath)
{
#ifdef WIN32
/* rename() on Windows doesn't overwrite, so we can't use it here.
MoveFileExA() will overwrite and is usually atomic, however it fails
MoveFileEx() will overwrite and is usually atomic, however it fails
when there are open handles to the file. */
const int max_wait_ms = 1000;
struct curltime start = Curl_now();
TCHAR *tchar_oldpath = curlx_convert_UTF8_to_tchar((char *)oldpath);
TCHAR *tchar_newpath = curlx_convert_UTF8_to_tchar((char *)newpath);
for(;;) {
timediff_t diff;
if(MoveFileExA(oldpath, newpath, MOVEFILE_REPLACE_EXISTING))
if(MoveFileEx(tchar_oldpath, tchar_newpath, MOVEFILE_REPLACE_EXISTING)) {
curlx_unicodefree(tchar_oldpath);
curlx_unicodefree(tchar_newpath);
break;
}
diff = Curl_timediff(Curl_now(), start);
if(diff < 0 || diff > max_wait_ms)
if(diff < 0 || diff > max_wait_ms) {
curlx_unicodefree(tchar_oldpath);
curlx_unicodefree(tchar_newpath);
return 1;
}
Sleep(1);
}
#else
Expand Down
19 changes: 12 additions & 7 deletions src/tool_doswin.c
Expand Up @@ -36,6 +36,7 @@
#include "tool_bname.h"
#include "tool_doswin.h"

#include "curlx.h"
#include "memdebug.h" /* keep this as LAST include */

#ifdef WIN32
Expand Down Expand Up @@ -612,7 +613,7 @@ char **__crt0_glob_function(char *arg)

CURLcode FindWin32CACert(struct OperationConfig *config,
curl_sslbackend backend,
const char *bundle_file)
const TCHAR *bundle_file)
{
CURLcode result = CURLE_OK;

Expand All @@ -626,15 +627,19 @@ CURLcode FindWin32CACert(struct OperationConfig *config,
backend != CURLSSLBACKEND_SCHANNEL) {

DWORD res_len;
char buf[PATH_MAX];
char *ptr = NULL;
TCHAR buf[PATH_MAX];
TCHAR *ptr = NULL;

buf[0] = '\0';
buf[0] = TEXT('\0');

res_len = SearchPathA(NULL, bundle_file, NULL, PATH_MAX, buf, &ptr);
res_len = SearchPath(NULL, bundle_file, NULL, PATH_MAX, buf, &ptr);
if(res_len > 0) {
Curl_safefree(config->cacert);
#ifdef UNICODE
config->cacert = curlx_convert_wchar_to_UTF8(buf);
#else
config->cacert = strdup(buf);
#endif
if(!config->cacert)
result = CURLE_OUT_OF_MEMORY;
}
Expand Down Expand Up @@ -702,7 +707,7 @@ bool tool_isVistaOrGreater;

CURLcode win32_init(void)
{
OSVERSIONINFOEXA osvi;
OSVERSIONINFOEX osvi;
unsigned __int64 mask = 0;
unsigned char op = VER_GREATER_EQUAL;

Expand All @@ -712,7 +717,7 @@ CURLcode win32_init(void)
VER_SET_CONDITION(mask, VER_MAJORVERSION, op);
VER_SET_CONDITION(mask, VER_MINORVERSION, op);

if(VerifyVersionInfoA(&osvi, (VER_MAJORVERSION | VER_MINORVERSION), mask))
if(VerifyVersionInfo(&osvi, (VER_MAJORVERSION | VER_MINORVERSION), mask))
tool_isVistaOrGreater = true;
else if(GetLastError() == ERROR_OLD_WIN_VERSION)
tool_isVistaOrGreater = false;
Expand Down
2 changes: 1 addition & 1 deletion src/tool_doswin.h
Expand Up @@ -59,7 +59,7 @@ char **__crt0_glob_function(char *arg);

CURLcode FindWin32CACert(struct OperationConfig *config,
curl_sslbackend backend,
const char *bundle_file);
const TCHAR *bundle_file);
struct curl_slist *GetLoadedModulePaths(void);
CURLcode win32_init(void);

Expand Down
11 changes: 9 additions & 2 deletions src/tool_filetime.c
Expand Up @@ -21,6 +21,8 @@
***************************************************************************/
#include "tool_filetime.h"

#include "curlx.h"

#ifdef HAVE_UTIME_H
# include <utime.h>
#elif defined(HAVE_SYS_UTIME_H)
Expand All @@ -36,11 +38,13 @@ curl_off_t getfiletime(const char *filename, FILE *error_stream)
access to a 64-bit type we can bypass stat and get the times directly. */
#if defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8)
HANDLE hfile;
TCHAR *filename_tchar = curlx_convert_UTF8_to_tchar((char *)filename);

hfile = CreateFileA(filename, FILE_READ_ATTRIBUTES,
hfile = CreateFile(filename_tchar, FILE_READ_ATTRIBUTES,
(FILE_SHARE_READ | FILE_SHARE_WRITE |
FILE_SHARE_DELETE),
NULL, OPEN_EXISTING, 0, NULL);
curlx_unicodefree(filename_tchar);
if(hfile != INVALID_HANDLE_VALUE) {
FILETIME ft;
if(GetFileTime(hfile, NULL, NULL, &ft)) {
Expand Down Expand Up @@ -93,20 +97,23 @@ void setfiletime(curl_off_t filetime, const char *filename,
access to a 64-bit type we can bypass utime and set the times directly. */
#if defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8)
HANDLE hfile;
TCHAR *filename_tchar = curlx_convert_UTF8_to_tchar((char *)filename);

/* 910670515199 is the maximum unix filetime that can be used as a
Windows FILETIME without overflow: 30827-12-31T23:59:59. */
if(filetime > CURL_OFF_T_C(910670515199)) {
fprintf(error_stream,
"Failed to set filetime %" CURL_FORMAT_CURL_OFF_T
" on outfile: overflow\n", filetime);
curlx_unicodefree(filename_tchar);
return;
}

hfile = CreateFileA(filename, FILE_WRITE_ATTRIBUTES,
hfile = CreateFile(filename_tchar, FILE_WRITE_ATTRIBUTES,
(FILE_SHARE_READ | FILE_SHARE_WRITE |
FILE_SHARE_DELETE),
NULL, OPEN_EXISTING, 0, NULL);
curlx_unicodefree(filename_tchar);
if(hfile != INVALID_HANDLE_VALUE) {
curl_off_t converted = ((curl_off_t)filetime * 10000000) +
CURL_OFF_T_C(116444736000000000);
Expand Down
2 changes: 1 addition & 1 deletion src/tool_operate.c
Expand Up @@ -2415,7 +2415,7 @@ static CURLcode transfer_per_config(struct GlobalConfig *global,
#ifdef WIN32
else {
result = FindWin32CACert(config, tls_backend_info->backend,
"curl-ca-bundle.crt");
TEXT("curl-ca-bundle.crt"));
}
#endif
}
Expand Down

0 comments on commit 132cbe4

Please sign in to comment.