diff --git a/include/git2/windows.h b/include/git2/windows.h deleted file mode 100644 index 8b743f0aa..000000000 --- a/include/git2/windows.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_windows_h__ -#define INCLUDE_git_windows_h__ - -#include "common.h" - -/** - * @file git2/windows.h - * @brief Windows-specific functions - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Set the active codepage for Windows syscalls - * - * All syscalls performed by the library will assume - * this codepage when converting paths and strings - * to use by the Windows kernel. - * - * The default value of UTF-8 will work automatically - * with most Git repositories created on Unix systems. - * - * This settings needs only be changed when working - * with repositories that contain paths in specific, - * non-UTF codepages. - * - * A full list of all available codepage identifiers may - * be found at: - * - * http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx - * - * @param codepage numeric codepage identifier - */ -GIT_EXTERN(void) gitwin_set_codepage(unsigned int codepage); - -/** - * Return the active codepage for Windows syscalls - * - * @return numeric codepage identifier - */ -GIT_EXTERN(unsigned int) gitwin_get_codepage(void); - -/** - * Set the active Windows codepage to UTF-8 (this is - * the default value) - */ -GIT_EXTERN(void) gitwin_set_utf8(void); - -/** @} */ -GIT_END_DECL -#endif - diff --git a/src/fileops.c b/src/fileops.c index 76ef8c910..95eacb5f1 100644 --- a/src/fileops.c +++ b/src/fileops.c @@ -54,11 +54,10 @@ int git_futils_creat_locked(const char *path, const mode_t mode) int fd; #ifdef GIT_WIN32 - wchar_t* buf; + wchar_t buf[GIT_WIN_PATH]; - buf = gitwin_to_utf16(path); + git__utf8_to_16(buf, GIT_WIN_PATH, path); fd = _wopen(buf, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_EXCL, mode); - git__free(buf); #else fd = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_EXCL, mode); #endif @@ -382,16 +381,16 @@ static int win32_expand_path(struct win32_path *s_root, const wchar_t *templ) static int win32_find_file(git_buf *path, const struct win32_path *root, const char *filename) { - int error = 0; - size_t len; + size_t len, alloc_len; wchar_t *file_utf16 = NULL; - char *file_utf8 = NULL; + char file_utf8[GIT_PATH_MAX]; if (!root || !filename || (len = strlen(filename)) == 0) return GIT_ENOTFOUND; /* allocate space for wchar_t path to file */ - file_utf16 = git__calloc(root->len + len + 2, sizeof(wchar_t)); + alloc_len = root->len + len + 2; + file_utf16 = git__calloc(alloc_len, sizeof(wchar_t)); GITERR_CHECK_ALLOC(file_utf16); /* append root + '\\' + filename as wchar_t */ @@ -400,29 +399,20 @@ static int win32_find_file(git_buf *path, const struct win32_path *root, const c if (*filename == '/' || *filename == '\\') filename++; - if (gitwin_append_utf16(file_utf16 + root->len - 1, filename, len + 1) != - (int)len + 1) { - error = -1; - goto cleanup; - } + git__utf8_to_16(file_utf16 + root->len - 1, alloc_len, filename); /* check access */ if (_waccess(file_utf16, F_OK) < 0) { - error = GIT_ENOTFOUND; - goto cleanup; + git__free(file_utf16); + return GIT_ENOTFOUND; } - /* convert to utf8 */ - if ((file_utf8 = gitwin_from_utf16(file_utf16)) == NULL) - error = -1; - else { - git_path_mkposix(file_utf8); - git_buf_attach(path, file_utf8, 0); - } + git__utf16_to_8(file_utf8, file_utf16); + git_path_mkposix(file_utf8); + git_buf_sets(path, file_utf8); -cleanup: git__free(file_utf16); - return error; + return 0; } #endif diff --git a/src/path.c b/src/path.c index 15188850d..09556bd3f 100644 --- a/src/path.c +++ b/src/path.c @@ -432,14 +432,14 @@ bool git_path_is_empty_dir(const char *path) { git_buf pathbuf = GIT_BUF_INIT; HANDLE hFind = INVALID_HANDLE_VALUE; - wchar_t *wbuf; + wchar_t wbuf[GIT_WIN_PATH]; WIN32_FIND_DATAW ffd; bool retval = true; if (!git_path_isdir(path)) return false; git_buf_printf(&pathbuf, "%s\\*", path); - wbuf = gitwin_to_utf16(git_buf_cstr(&pathbuf)); + git__utf8_to_16(wbuf, GIT_WIN_PATH, git_buf_cstr(&pathbuf)); hFind = FindFirstFileW(wbuf, &ffd); if (INVALID_HANDLE_VALUE == hFind) { @@ -455,7 +455,6 @@ bool git_path_is_empty_dir(const char *path) FindClose(hFind); git_buf_free(&pathbuf); - git__free(wbuf); return retval; } diff --git a/src/win32/dir.c b/src/win32/dir.c index bc3d40fa5..5cb1082bc 100644 --- a/src/win32/dir.c +++ b/src/win32/dir.c @@ -7,7 +7,6 @@ #define GIT__WIN32_NO_WRAP_DIR #include "dir.h" #include "utf-conv.h" -#include "git2/windows.h" static int init_filter(char *filter, size_t n, const char *dir) { @@ -26,8 +25,8 @@ static int init_filter(char *filter, size_t n, const char *dir) git__DIR *git__opendir(const char *dir) { - char filter[4096]; - wchar_t* filter_w = NULL; + char filter[GIT_WIN_PATH]; + wchar_t filter_w[GIT_WIN_PATH]; git__DIR *new = NULL; if (!dir || !init_filter(filter, sizeof(filter), dir)) @@ -41,12 +40,8 @@ git__DIR *git__opendir(const char *dir) if (!new->dir) goto fail; - filter_w = gitwin_to_utf16(filter); - if (!filter_w) - goto fail; - + git__utf8_to_16(filter_w, GIT_WIN_PATH, filter); new->h = FindFirstFileW(filter_w, &new->f); - git__free(filter_w); if (new->h == INVALID_HANDLE_VALUE) { giterr_set(GITERR_OS, "Could not open directory '%s'", dir); @@ -85,16 +80,9 @@ int git__readdir_ext( if (wcslen(d->f.cFileName) >= sizeof(entry->d_name)) return -1; + git__utf16_to_8(entry->d_name, d->f.cFileName); entry->d_ino = 0; - if (WideCharToMultiByte( - gitwin_get_codepage(), 0, d->f.cFileName, -1, - entry->d_name, GIT_PATH_MAX, NULL, NULL) == 0) - { - giterr_set(GITERR_OS, "Could not convert filename to UTF-8"); - return -1; - } - *result = entry; if (is_dir != NULL) @@ -113,8 +101,8 @@ struct git__dirent *git__readdir(git__DIR *d) void git__rewinddir(git__DIR *d) { - char filter[4096]; - wchar_t* filter_w; + char filter[GIT_WIN_PATH]; + wchar_t filter_w[GIT_WIN_PATH]; if (!d) return; @@ -125,12 +113,11 @@ void git__rewinddir(git__DIR *d) d->first = 0; } - if (!init_filter(filter, sizeof(filter), d->dir) || - (filter_w = gitwin_to_utf16(filter)) == NULL) + if (!init_filter(filter, sizeof(filter), d->dir)) return; + git__utf8_to_16(filter_w, GIT_WIN_PATH, filter); d->h = FindFirstFileW(filter_w, &d->f); - git__free(filter_w); if (d->h == INVALID_HANDLE_VALUE) giterr_set(GITERR_OS, "Could not open directory '%s'", d->dir); diff --git a/src/win32/posix.h b/src/win32/posix.h index 14caae418..da46cf514 100644 --- a/src/win32/posix.h +++ b/src/win32/posix.h @@ -21,13 +21,10 @@ GIT_INLINE(int) p_link(const char *old, const char *new) GIT_INLINE(int) p_mkdir(const char *path, mode_t mode) { - wchar_t* buf = gitwin_to_utf16(path); - int ret = _wmkdir(buf); - + wchar_t buf[GIT_WIN_PATH]; GIT_UNUSED(mode); - - git__free(buf); - return ret; + git__utf8_to_16(buf, GIT_WIN_PATH, path); + return _wmkdir(buf); } extern int p_unlink(const char *path); diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index aa34ad3ac..649fe9b95 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -15,16 +15,10 @@ int p_unlink(const char *path) { - int ret = 0; - wchar_t* buf; - - if ((buf = gitwin_to_utf16(path)) != NULL) { - _wchmod(buf, 0666); - ret = _wunlink(buf); - git__free(buf); - } - - return ret; + wchar_t buf[GIT_WIN_PATH]; + git__utf8_to_16(buf, GIT_WIN_PATH, path); + _wchmod(buf, 0666); + return _wunlink(buf); } int p_fsync(int fd) @@ -61,10 +55,10 @@ GIT_INLINE(time_t) filetime_to_time_t(const FILETIME *ft) static int do_lstat(const char *file_name, struct stat *buf) { WIN32_FILE_ATTRIBUTE_DATA fdata; + wchar_t fbuf[GIT_WIN_PATH]; DWORD last_error; - wchar_t* fbuf = gitwin_to_utf16(file_name); - if (!fbuf) - return -1; + + git__utf8_to_16(fbuf, GIT_WIN_PATH, file_name); if (GetFileAttributesExW(fbuf, GetFileExInfoStandard, &fdata)) { int fMode = S_IREAD; @@ -90,8 +84,6 @@ static int do_lstat(const char *file_name, struct stat *buf) buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime)); buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime)); buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime)); - - git__free(fbuf); return 0; } @@ -101,7 +93,6 @@ static int do_lstat(const char *file_name, struct stat *buf) else if (last_error == ERROR_PATH_NOT_FOUND) errno = ENOTDIR; - git__free(fbuf); return -1; } @@ -143,7 +134,7 @@ int p_readlink(const char *link, char *target, size_t target_len) static fpath_func pGetFinalPath = NULL; HANDLE hFile; DWORD dwRet; - wchar_t* link_w; + wchar_t link_w[GIT_WIN_PATH]; wchar_t* target_w; int error = 0; @@ -166,8 +157,7 @@ int p_readlink(const char *link, char *target, size_t target_len) } } - link_w = gitwin_to_utf16(link); - GITERR_CHECK_ALLOC(link_w); + git__utf8_to_16(link_w, GIT_WIN_PATH, link); hFile = CreateFileW(link_w, // file to open GENERIC_READ, // open for reading @@ -177,8 +167,6 @@ int p_readlink(const char *link, char *target, size_t target_len) FILE_FLAG_BACKUP_SEMANTICS, // normal file NULL); // no attr. template - git__free(link_w); - if (hFile == INVALID_HANDLE_VALUE) { giterr_set(GITERR_OS, "Cannot open '%s' for reading", link); return -1; @@ -235,16 +223,12 @@ int p_symlink(const char *old, const char *new) int p_open(const char *path, int flags, ...) { - int fd; - wchar_t* buf; + wchar_t buf[GIT_WIN_PATH]; mode_t mode = 0; - buf = gitwin_to_utf16(path); - if (!buf) - return -1; + git__utf8_to_16(buf, GIT_WIN_PATH, path); - if (flags & O_CREAT) - { + if (flags & O_CREAT) { va_list arg_list; va_start(arg_list, flags); @@ -252,27 +236,20 @@ int p_open(const char *path, int flags, ...) va_end(arg_list); } - fd = _wopen(buf, flags | _O_BINARY, mode); - - git__free(buf); - return fd; + return _wopen(buf, flags | _O_BINARY, mode); } int p_creat(const char *path, mode_t mode) { - int fd; - wchar_t* buf = gitwin_to_utf16(path); - if (!buf) - return -1; - fd = _wopen(buf, _O_WRONLY | _O_CREAT | _O_TRUNC | _O_BINARY, mode); - git__free(buf); - return fd; + wchar_t buf[GIT_WIN_PATH]; + git__utf8_to_16(buf, GIT_WIN_PATH, path); + return _wopen(buf, _O_WRONLY | _O_CREAT | _O_TRUNC | _O_BINARY, mode); } int p_getcwd(char *buffer_out, size_t size) { int ret; - wchar_t* buf; + wchar_t *buf; if ((size_t)((int)size) != size) return -1; @@ -296,64 +273,43 @@ int p_stat(const char* path, struct stat* buf) int p_chdir(const char* path) { - wchar_t* buf = gitwin_to_utf16(path); - int ret; - if (!buf) - return -1; - ret = _wchdir(buf); - git__free(buf); - return ret; + wchar_t buf[GIT_WIN_PATH]; + git__utf8_to_16(buf, GIT_WIN_PATH, path); + return _wchdir(buf); } int p_chmod(const char* path, mode_t mode) { - wchar_t* buf = gitwin_to_utf16(path); - int ret; - if (!buf) - return -1; - ret = _wchmod(buf, mode); - git__free(buf); - return ret; + wchar_t buf[GIT_WIN_PATH]; + git__utf8_to_16(buf, GIT_WIN_PATH, path); + return _wchmod(buf, mode); } int p_rmdir(const char* path) { - wchar_t* buf = gitwin_to_utf16(path); - int ret; - if (!buf) - return -1; - ret = _wrmdir(buf); - git__free(buf); - return ret; + wchar_t buf[GIT_WIN_PATH]; + git__utf8_to_16(buf, GIT_WIN_PATH, path); + return _wrmdir(buf); } int p_hide_directory__w32(const char *path) { - int res; - wchar_t* buf = gitwin_to_utf16(path); - if (!buf) - return -1; - - res = SetFileAttributesW(buf, FILE_ATTRIBUTE_HIDDEN); - git__free(buf); - - return (res != 0) ? 0 : -1; /* MSDN states a "non zero" value indicates a success */ + wchar_t buf[GIT_WIN_PATH]; + git__utf8_to_16(buf, GIT_WIN_PATH, path); + return (SetFileAttributesW(buf, FILE_ATTRIBUTE_HIDDEN) != 0) ? 0 : -1; } char *p_realpath(const char *orig_path, char *buffer) { int ret, buffer_sz = 0; - wchar_t* orig_path_w = gitwin_to_utf16(orig_path); - wchar_t* buffer_w = (wchar_t*)git__malloc(GIT_PATH_MAX * sizeof(wchar_t)); + wchar_t orig_path_w[GIT_WIN_PATH]; + wchar_t buffer_w[GIT_WIN_PATH]; - if (!orig_path_w || !buffer_w) - return NULL; - - ret = GetFullPathNameW(orig_path_w, GIT_PATH_MAX, buffer_w, NULL); - git__free(orig_path_w); + git__utf8_to_16(orig_path_w, GIT_WIN_PATH, orig_path); + ret = GetFullPathNameW(orig_path_w, GIT_WIN_PATH, buffer_w, NULL); /* According to MSDN, a return value equals to zero means a failure. */ - if (ret == 0 || ret > GIT_PATH_MAX) { + if (ret == 0 || ret > GIT_WIN_PATH) { buffer = NULL; goto done; } @@ -376,8 +332,7 @@ char *p_realpath(const char *orig_path, char *buffer) } } - if (!git_path_exists(buffer)) - { + if (!git_path_exists(buffer)) { if (buffer_sz > 0) git__free(buffer); @@ -386,9 +341,9 @@ char *p_realpath(const char *orig_path, char *buffer) } done: - git__free(buffer_w); if (buffer) git_path_mkposix(buffer); + return buffer; } @@ -443,32 +398,19 @@ int p_setenv(const char* name, const char* value, int overwrite) int p_access(const char* path, mode_t mode) { - wchar_t *buf = gitwin_to_utf16(path); - int ret; - if (!buf) - return -1; - - ret = _waccess(buf, mode); - git__free(buf); - - return ret; + wchar_t buf[GIT_WIN_PATH]; + git__utf8_to_16(buf, GIT_WIN_PATH, path); + return _waccess(buf, mode); } int p_rename(const char *from, const char *to) { - wchar_t *wfrom = gitwin_to_utf16(from); - wchar_t *wto = gitwin_to_utf16(to); - int ret; + wchar_t wfrom[GIT_WIN_PATH]; + wchar_t wto[GIT_WIN_PATH]; - if (!wfrom || !wto) - return -1; - - ret = MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) ? 0 : -1; - - git__free(wfrom); - git__free(wto); - - return ret; + git__utf8_to_16(wfrom, GIT_WIN_PATH, from); + git__utf8_to_16(wto, GIT_WIN_PATH, to); + return MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) ? 0 : -1; } int p_recv(GIT_SOCKET socket, void *buffer, size_t length, int flags) diff --git a/src/win32/utf-conv.c b/src/win32/utf-conv.c index 0a705c0ad..88a84141e 100644 --- a/src/win32/utf-conv.c +++ b/src/win32/utf-conv.c @@ -7,86 +7,75 @@ #include "common.h" #include "utf-conv.h" -#include "git2/windows.h" -/* - * Default codepage value - */ -static int _active_codepage = CP_UTF8; +#define U16_LEAD(c) (wchar_t)(((c)>>10)+0xd7c0) +#define U16_TRAIL(c) (wchar_t)(((c)&0x3ff)|0xdc00) -void gitwin_set_codepage(unsigned int codepage) +#if 0 +void git__utf8_to_16(wchar_t *dest, size_t length, const char *src) { - _active_codepage = codepage; -} + wchar_t *pDest = dest; + uint32_t ch; + const uint8_t* pSrc = (uint8_t*) src; -unsigned int gitwin_get_codepage(void) -{ - return _active_codepage; -} + assert(dest && src && length); -void gitwin_set_utf8(void) -{ - _active_codepage = CP_UTF8; -} + length--; -wchar_t* gitwin_to_utf16(const char* str) -{ - wchar_t* ret; - int cb; + while(*pSrc && length > 0) { + ch = *pSrc++; + length--; - if (!str) - return NULL; + if(ch < 0xc0) { + /* + * ASCII, or a trail byte in lead position which is treated like + * a single-byte sequence for better character boundary + * resynchronization after illegal sequences. + */ + *pDest++ = (wchar_t)ch; + continue; + } else if(ch < 0xe0) { /* U+0080..U+07FF */ + if (pSrc[0]) { + /* 0x3080 = (0xc0 << 6) + 0x80 */ + *pDest++ = (wchar_t)((ch << 6) + *pSrc++ - 0x3080); + continue; + } + } else if(ch < 0xf0) { /* U+0800..U+FFFF */ + if (pSrc[0] && pSrc[1]) { + /* no need for (ch & 0xf) because the upper bits are truncated after <<12 in the cast to (UChar) */ + /* 0x2080 = (0x80 << 6) + 0x80 */ + ch = (ch << 12) + (*pSrc++ << 6); + *pDest++ = (wchar_t)(ch + *pSrc++ - 0x2080); + continue; + } + } else /* f0..f4 */ { /* U+10000..U+10FFFF */ + if (length >= 1 && pSrc[0] && pSrc[1] && pSrc[2]) { + /* 0x3c82080 = (0xf0 << 18) + (0x80 << 12) + (0x80 << 6) + 0x80 */ + ch = (ch << 18) + (*pSrc++ << 12); + ch += *pSrc++ << 6; + ch += *pSrc++ - 0x3c82080; + *(pDest++) = U16_LEAD(ch); + *(pDest++) = U16_TRAIL(ch); + length--; /* two bytes for this character */ + continue; + } + } - cb = MultiByteToWideChar(_active_codepage, 0, str, -1, NULL, 0); - if (cb == 0) - return (wchar_t *)git__calloc(1, sizeof(wchar_t)); - - ret = (wchar_t *)git__malloc(cb * sizeof(wchar_t)); - if (!ret) - return NULL; - - if (MultiByteToWideChar(_active_codepage, 0, str, -1, ret, (int)cb) == 0) { - giterr_set(GITERR_OS, "Could not convert string to UTF-16"); - git__free(ret); - ret = NULL; + /* truncated character at the end */ + *pDest++ = 0xfffd; + break; } - return ret; + *pDest++ = 0x0; } +#endif -int gitwin_append_utf16(wchar_t *buffer, const char *str, size_t len) +void git__utf8_to_16(wchar_t *dest, size_t length, const char *src) { - int result = MultiByteToWideChar( - _active_codepage, 0, str, -1, buffer, (int)len); - if (result == 0) - giterr_set(GITERR_OS, "Could not convert string to UTF-16"); - return result; + MultiByteToWideChar(CP_UTF8, 0, src, -1, dest, length); } -char* gitwin_from_utf16(const wchar_t* str) +void git__utf16_to_8(char *out, const wchar_t *input) { - char* ret; - int cb; - - if (!str) - return NULL; - - cb = WideCharToMultiByte(_active_codepage, 0, str, -1, NULL, 0, NULL, NULL); - if (cb == 0) - return (char *)git__calloc(1, sizeof(char)); - - ret = (char*)git__malloc(cb); - if (!ret) - return NULL; - - if (WideCharToMultiByte( - _active_codepage, 0, str, -1, ret, (int)cb, NULL, NULL) == 0) - { - giterr_set(GITERR_OS, "Could not convert string to UTF-8"); - git__free(ret); - ret = NULL; - } - - return ret; - + WideCharToMultiByte(CP_UTF8, 0, input, -1, out, GIT_WIN_PATH, NULL, NULL); } diff --git a/src/win32/utf-conv.h b/src/win32/utf-conv.h index ae9f29f6c..3bd1549bc 100644 --- a/src/win32/utf-conv.h +++ b/src/win32/utf-conv.h @@ -10,9 +10,10 @@ #ifndef INCLUDE_git_utfconv_h__ #define INCLUDE_git_utfconv_h__ -wchar_t* gitwin_to_utf16(const char* str); -int gitwin_append_utf16(wchar_t *buffer, const char *str, size_t len); -char* gitwin_from_utf16(const wchar_t* str); +#define GIT_WIN_PATH (260 + 1) + +void git__utf8_to_16(wchar_t *dest, size_t length, const char *src); +void git__utf16_to_8(char *dest, const wchar_t *src); #endif diff --git a/tests-clar/clar_helpers.c b/tests-clar/clar_helpers.c index 80d0e3ae9..8d6a7024b 100644 --- a/tests-clar/clar_helpers.c +++ b/tests-clar/clar_helpers.c @@ -56,22 +56,23 @@ void cl_git_rewritefile(const char *filename, const char *new_content) char *cl_getenv(const char *name) { - wchar_t *name_utf16 = gitwin_to_utf16(name); - DWORD value_len, alloc_len; + wchar_t name_utf16[GIT_WIN_PATH]; + DWORD alloc_len; wchar_t *value_utf16; char *value_utf8; - cl_assert(name_utf16); + git__utf8_to_16(name_utf16, GIT_WIN_PATH, name); alloc_len = GetEnvironmentVariableW(name_utf16, NULL, 0); if (alloc_len <= 0) return NULL; + alloc_len = GIT_WIN_PATH; cl_assert(value_utf16 = git__calloc(alloc_len, sizeof(wchar_t))); - value_len = GetEnvironmentVariableW(name_utf16, value_utf16, alloc_len); - cl_assert_equal_i(value_len, alloc_len - 1); + GetEnvironmentVariableW(name_utf16, value_utf16, alloc_len); - cl_assert(value_utf8 = gitwin_from_utf16(value_utf16)); + cl_assert(value_utf8 = git__malloc(alloc_len)); + git__utf16_to_8(value_utf8, value_utf16); git__free(value_utf16); @@ -80,17 +81,16 @@ char *cl_getenv(const char *name) int cl_setenv(const char *name, const char *value) { - wchar_t *name_utf16 = gitwin_to_utf16(name); - wchar_t *value_utf16 = value ? gitwin_to_utf16(value) : NULL; + wchar_t name_utf16[GIT_WIN_PATH]; + wchar_t value_utf16[GIT_WIN_PATH]; - cl_assert(name_utf16); - cl_assert(SetEnvironmentVariableW(name_utf16, value_utf16)); + git__utf8_to_16(name_utf16, GIT_WIN_PATH, name); - git__free(name_utf16); - git__free(value_utf16); + if (value != NULL) + git__utf8_to_16(value_utf16, GIT_WIN_PATH, value); + cl_assert(SetEnvironmentVariableW(name_utf16, value ? value_utf16 : NULL)); return 0; - } #else