Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVicent Martí <vicent@github.com>2013-08-13 22:36:24 +0400
committerVicent Martí <vicent@github.com>2013-08-13 22:36:24 +0400
commit40948998badd892754a55197ef1b6b47b107afed (patch)
treeb0cbb27af13b6dda5abff644979afe193a2d7aa8 /src
parent14da618260be02c63b4f08dca8e6ab479f7449d7 (diff)
parent0228a514294bcb9d23bf24c61199a1a3e34d4772 (diff)
Merge pull request #1767 from libgit2/win32-bigger-utf8-buffer
Bigger buffer for utf-8 parsing in win32
Diffstat (limited to 'src')
-rw-r--r--src/fileops.c4
-rw-r--r--src/path.c7
-rw-r--r--src/transports/winhttp.c6
-rw-r--r--src/win32/dir.c38
-rw-r--r--src/win32/dir.h4
-rw-r--r--src/win32/findfile.c14
-rw-r--r--src/win32/posix.h6
-rw-r--r--src/win32/posix_w32.c71
-rw-r--r--src/win32/utf-conv.c8
-rw-r--r--src/win32/utf-conv.h31
10 files changed, 103 insertions, 86 deletions
diff --git a/src/fileops.c b/src/fileops.c
index 7f8418d7a..aea8075d5 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -58,9 +58,9 @@ int git_futils_creat_locked(const char *path, const mode_t mode)
int fd;
#ifdef GIT_WIN32
- wchar_t buf[GIT_WIN_PATH];
+ git_win32_path buf;
- git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ git_win32_path_from_c(buf, path);
fd = _wopen(buf, O_WRONLY | O_CREAT | O_TRUNC |
O_EXCL | O_BINARY | O_CLOEXEC, mode);
#else
diff --git a/src/path.c b/src/path.c
index b81675b49..a753a734d 100644
--- a/src/path.c
+++ b/src/path.c
@@ -8,7 +8,6 @@
#include "path.h"
#include "posix.h"
#ifdef GIT_WIN32
-#include "win32/dir.h"
#include "win32/posix.h"
#else
#include <dirent.h>
@@ -486,24 +485,26 @@ bool git_path_is_empty_dir(const char *path)
{
git_buf pathbuf = GIT_BUF_INIT;
HANDLE hFind = INVALID_HANDLE_VALUE;
- wchar_t wbuf[GIT_WIN_PATH];
+ git_win32_path wbuf;
WIN32_FIND_DATAW ffd;
bool retval = true;
if (!git_path_isdir(path)) return false;
git_buf_printf(&pathbuf, "%s\\*", path);
- git__utf8_to_16(wbuf, GIT_WIN_PATH, git_buf_cstr(&pathbuf));
+ git_win32_path_from_c(wbuf, git_buf_cstr(&pathbuf));
hFind = FindFirstFileW(wbuf, &ffd);
if (INVALID_HANDLE_VALUE == hFind) {
giterr_set(GITERR_OS, "Couldn't open '%s'", path);
+ git_buf_free(&pathbuf);
return false;
}
do {
if (!git_path_is_dot_or_dotdotW(ffd.cFileName)) {
retval = false;
+ break;
}
} while (FindNextFileW(hFind, &ffd) != 0);
diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c
index 95e422dc0..8decd8d51 100644
--- a/src/transports/winhttp.c
+++ b/src/transports/winhttp.c
@@ -893,7 +893,7 @@ static int winhttp_connect(
const char *url)
{
wchar_t *ua = L"git/1.0 (libgit2 " WIDEN(LIBGIT2_VERSION) L")";
- wchar_t host[GIT_WIN_PATH];
+ git_win32_path host;
int32_t port;
const char *default_port = "80";
int ret;
@@ -920,7 +920,7 @@ static int winhttp_connect(
return -1;
/* Prepare host */
- git__utf8_to_16(host, GIT_WIN_PATH, t->host);
+ git_win32_path_from_c(host, t->host);
/* Establish session */
t->session = WinHttpOpen(
@@ -934,7 +934,7 @@ static int winhttp_connect(
giterr_set(GITERR_OS, "Failed to init WinHTTP");
return -1;
}
-
+
/* Establish connection */
t->connection = WinHttpConnect(
t->session,
diff --git a/src/win32/dir.c b/src/win32/dir.c
index 8c51d8378..f7859b73f 100644
--- a/src/win32/dir.c
+++ b/src/win32/dir.c
@@ -5,8 +5,7 @@
* a Linking Exception. For full terms see the included COPYING file.
*/
#define GIT__WIN32_NO_WRAP_DIR
-#include "dir.h"
-#include "utf-conv.h"
+#include "posix.h"
static int init_filter(char *filter, size_t n, const char *dir)
{
@@ -25,36 +24,32 @@ static int init_filter(char *filter, size_t n, const char *dir)
git__DIR *git__opendir(const char *dir)
{
- char filter[GIT_WIN_PATH];
- wchar_t filter_w[GIT_WIN_PATH];
+ git_win32_path_as_utf8 filter;
+ git_win32_path filter_w;
git__DIR *new = NULL;
+ size_t dirlen;
if (!dir || !init_filter(filter, sizeof(filter), dir))
return NULL;
- new = git__calloc(1, sizeof(*new));
+ dirlen = strlen(dir);
+
+ new = git__calloc(sizeof(*new) + dirlen + 1, 1);
if (!new)
return NULL;
+ memcpy(new->dir, dir, dirlen);
- new->dir = git__strdup(dir);
- if (!new->dir)
- goto fail;
-
- git__utf8_to_16(filter_w, GIT_WIN_PATH, filter);
+ git_win32_path_from_c(filter_w, filter);
new->h = FindFirstFileW(filter_w, &new->f);
if (new->h == INVALID_HANDLE_VALUE) {
giterr_set(GITERR_OS, "Could not open directory '%s'", dir);
- goto fail;
+ git__free(new);
+ return NULL;
}
new->first = 1;
return new;
-
-fail:
- git__free(new->dir);
- git__free(new);
- return NULL;
}
int git__readdir_ext(
@@ -80,7 +75,7 @@ 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);
+ git_win32_path_to_c(entry->d_name, d->f.cFileName);
entry->d_ino = 0;
*result = entry;
@@ -101,8 +96,8 @@ struct git__dirent *git__readdir(git__DIR *d)
void git__rewinddir(git__DIR *d)
{
- char filter[GIT_WIN_PATH];
- wchar_t filter_w[GIT_WIN_PATH];
+ git_win32_path_as_utf8 filter;
+ git_win32_path filter_w;
if (!d)
return;
@@ -116,7 +111,7 @@ void git__rewinddir(git__DIR *d)
if (!init_filter(filter, sizeof(filter), d->dir))
return;
- git__utf8_to_16(filter_w, GIT_WIN_PATH, filter);
+ git_win32_path_from_c(filter_w, filter);
d->h = FindFirstFileW(filter_w, &d->f);
if (d->h == INVALID_HANDLE_VALUE)
@@ -134,8 +129,7 @@ int git__closedir(git__DIR *d)
FindClose(d->h);
d->h = INVALID_HANDLE_VALUE;
}
- git__free(d->dir);
- d->dir = NULL;
+
git__free(d);
return 0;
}
diff --git a/src/win32/dir.h b/src/win32/dir.h
index 7696d468e..24d48f6ba 100644
--- a/src/win32/dir.h
+++ b/src/win32/dir.h
@@ -11,15 +11,15 @@
struct git__dirent {
int d_ino;
- char d_name[261];
+ git_win32_path_as_utf8 d_name;
};
typedef struct {
HANDLE h;
WIN32_FIND_DATAW f;
struct git__dirent entry;
- char *dir;
int first;
+ char dir[GIT_FLEX_ARRAY];
} git__DIR;
extern git__DIR *git__opendir(const char *);
diff --git a/src/win32/findfile.c b/src/win32/findfile.c
index 9d9051bff..a1c11fcfb 100644
--- a/src/win32/findfile.c
+++ b/src/win32/findfile.c
@@ -23,11 +23,11 @@ int git_win32__expand_path(struct git_win32__path *s_root, const wchar_t *templ)
return s_root->len ? 0 : -1;
}
-static int win32_path_utf16_to_8(git_buf *path_utf8, const wchar_t *path_utf16)
+static int win32_path_to_8(git_buf *path_utf8, const wchar_t *path)
{
char temp_utf8[GIT_PATH_MAX];
- git__utf16_to_8(temp_utf8, path_utf16);
+ git__utf16_to_8(temp_utf8, GIT_PATH_MAX, path);
git_path_mkposix(temp_utf8);
return git_buf_sets(path_utf8, temp_utf8);
@@ -53,7 +53,7 @@ int git_win32__find_file(
if (*filename == '/' || *filename == '\\')
filename++;
- git__utf8_to_16(file_utf16 + root->len - 1, alloc_len, filename);
+ git__utf8_to_16(file_utf16 + root->len - 1, alloc_len - root->len, filename);
/* check access */
if (_waccess(file_utf16, F_OK) < 0) {
@@ -61,7 +61,7 @@ int git_win32__find_file(
return GIT_ENOTFOUND;
}
- win32_path_utf16_to_8(path, file_utf16);
+ win32_path_to_8(path, file_utf16);
git__free(file_utf16);
return 0;
@@ -113,7 +113,7 @@ static int win32_find_git_in_path(git_buf *buf, const wchar_t *gitexe)
/* replace "bin\\" or "cmd\\" with "etc\\" */
wcscpy(&root.path[root.len - 4], L"etc\\");
- win32_path_utf16_to_8(buf, root.path);
+ win32_path_to_8(buf, root.path);
return 0;
}
}
@@ -146,7 +146,7 @@ static int win32_find_git_in_registry(
wcscat(path16.path, L"etc\\");
path16.len += 4;
- win32_path_utf16_to_8(buf, path16.path);
+ win32_path_to_8(buf, path16.path);
}
RegCloseKey(hKey);
@@ -168,7 +168,7 @@ static int win32_find_existing_dirs(
path16.path[0] != L'%' &&
!_waccess(path16.path, F_OK))
{
- win32_path_utf16_to_8(&buf, path16.path);
+ win32_path_to_8(&buf, path16.path);
if (buf.size)
git_buf_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr);
diff --git a/src/win32/posix.h b/src/win32/posix.h
index c49c2175c..5f924a026 100644
--- a/src/win32/posix.h
+++ b/src/win32/posix.h
@@ -8,7 +8,9 @@
#define INCLUDE_posix__w32_h__
#include "common.h"
+#include "../posix.h"
#include "utf-conv.h"
+#include "dir.h"
GIT_INLINE(int) p_link(const char *old, const char *new)
{
@@ -20,9 +22,9 @@ 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[GIT_WIN_PATH];
+ git_win32_path buf;
GIT_UNUSED(mode);
- git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ git_win32_path_from_c(buf, path);
return _wmkdir(buf);
}
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index 036632e2a..9d5b8d877 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -16,8 +16,8 @@
int p_unlink(const char *path)
{
- wchar_t buf[GIT_WIN_PATH];
- git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ git_win32_path buf;
+ git_win32_path_from_c(buf, path);
_wchmod(buf, 0666);
return _wunlink(buf);
}
@@ -59,10 +59,11 @@ static int do_lstat(
const char *file_name, struct stat *buf, int posix_enotdir)
{
WIN32_FILE_ATTRIBUTE_DATA fdata;
- wchar_t fbuf[GIT_WIN_PATH], lastch;
+ git_win32_path fbuf;
+ wchar_t lastch;
int flen;
- flen = git__utf8_to_16(fbuf, GIT_WIN_PATH, file_name);
+ flen = git_win32_path_from_c(fbuf, file_name);
/* truncate trailing slashes */
for (; flen > 0; --flen) {
@@ -108,10 +109,10 @@ static int do_lstat(
* the length of the path pointed to, which we expect everywhere else
*/
if (S_ISLNK(fMode)) {
- char target[GIT_WIN_PATH];
+ git_win32_path_as_utf8 target;
int readlink_result;
- readlink_result = p_readlink(file_name, target, GIT_WIN_PATH);
+ readlink_result = p_readlink(file_name, target, sizeof(target));
if (readlink_result == -1)
return -1;
@@ -165,7 +166,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[GIT_WIN_PATH];
+ git_win32_path link_w;
wchar_t* target_w;
int error = 0;
@@ -188,7 +189,7 @@ int p_readlink(const char *link, char *target, size_t target_len)
}
}
- git__utf8_to_16(link_w, GIT_WIN_PATH, link);
+ git_win32_path_from_c(link_w, link);
hFile = CreateFileW(link_w, // file to open
GENERIC_READ, // open for reading
@@ -254,10 +255,10 @@ int p_symlink(const char *old, const char *new)
int p_open(const char *path, int flags, ...)
{
- wchar_t buf[GIT_WIN_PATH];
+ git_win32_path buf;
mode_t mode = 0;
- git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ git_win32_path_from_c(buf, path);
if (flags & O_CREAT) {
va_list arg_list;
@@ -272,8 +273,8 @@ int p_open(const char *path, int flags, ...)
int p_creat(const char *path, mode_t mode)
{
- wchar_t buf[GIT_WIN_PATH];
- git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ git_win32_path buf;
+ git_win32_path_from_c(buf, path);
return _wopen(buf, _O_WRONLY | _O_CREAT | _O_TRUNC | _O_BINARY, mode);
}
@@ -299,7 +300,7 @@ int p_getcwd(char *buffer_out, size_t size)
int p_stat(const char* path, struct stat* buf)
{
- char target[GIT_WIN_PATH];
+ git_win32_path_as_utf8 target;
int error = 0;
error = do_lstat(path, buf, 0);
@@ -307,7 +308,7 @@ int p_stat(const char* path, struct stat* buf)
/* We need not do this in a loop to unwind chains of symlinks since
* p_readlink calls GetFinalPathNameByHandle which does it for us. */
if (error >= 0 && S_ISLNK(buf->st_mode) &&
- (error = p_readlink(path, target, GIT_WIN_PATH)) >= 0)
+ (error = p_readlink(path, target, sizeof(target))) >= 0)
error = do_lstat(target, buf, 0);
return error;
@@ -315,23 +316,23 @@ int p_stat(const char* path, struct stat* buf)
int p_chdir(const char* path)
{
- wchar_t buf[GIT_WIN_PATH];
- git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ git_win32_path buf;
+ git_win32_path_from_c(buf, path);
return _wchdir(buf);
}
int p_chmod(const char* path, mode_t mode)
{
- wchar_t buf[GIT_WIN_PATH];
- git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ git_win32_path buf;
+ git_win32_path_from_c(buf, path);
return _wchmod(buf, mode);
}
int p_rmdir(const char* path)
{
int error;
- wchar_t buf[GIT_WIN_PATH];
- git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ git_win32_path buf;
+ git_win32_path_from_c(buf, path);
error = _wrmdir(buf);
@@ -347,24 +348,24 @@ int p_rmdir(const char* path)
int p_hide_directory__w32(const char *path)
{
- wchar_t buf[GIT_WIN_PATH];
- git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ git_win32_path buf;
+ git_win32_path_from_c(buf, path);
return (SetFileAttributesW(buf, FILE_ATTRIBUTE_HIDDEN) != 0) ? 0 : -1;
}
char *p_realpath(const char *orig_path, char *buffer)
{
int ret;
- wchar_t orig_path_w[GIT_WIN_PATH];
- wchar_t buffer_w[GIT_WIN_PATH];
+ git_win32_path orig_path_w;
+ git_win32_path buffer_w;
- git__utf8_to_16(orig_path_w, GIT_WIN_PATH, orig_path);
+ git_win32_path_from_c(orig_path_w, orig_path);
/* Implicitly use GetCurrentDirectory which can be a threading issue */
- ret = GetFullPathNameW(orig_path_w, GIT_WIN_PATH, buffer_w, NULL);
+ ret = GetFullPathNameW(orig_path_w, GIT_WIN_PATH_UTF16, buffer_w, NULL);
/* According to MSDN, a return value equals to zero means a failure. */
- if (ret == 0 || ret > GIT_WIN_PATH)
+ if (ret == 0 || ret > GIT_WIN_PATH_UTF16)
buffer = NULL;
else if (GetFileAttributesW(buffer_w) == INVALID_FILE_ATTRIBUTES) {
@@ -448,18 +449,18 @@ int p_setenv(const char* name, const char* value, int overwrite)
int p_access(const char* path, mode_t mode)
{
- wchar_t buf[GIT_WIN_PATH];
- git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ git_win32_path buf;
+ git_win32_path_from_c(buf, path);
return _waccess(buf, mode);
}
int p_rename(const char *from, const char *to)
{
- wchar_t wfrom[GIT_WIN_PATH];
- wchar_t wto[GIT_WIN_PATH];
+ git_win32_path wfrom;
+ git_win32_path wto;
- git__utf8_to_16(wfrom, GIT_WIN_PATH, from);
- git__utf8_to_16(wto, GIT_WIN_PATH, to);
+ git_win32_path_from_c(wfrom, from);
+ git_win32_path_from_c(wto, to);
return MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) ? 0 : -1;
}
@@ -513,10 +514,10 @@ p_gmtime_r (const time_t *timer, struct tm *result)
#else
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
#endif
-
+
#ifndef _TIMEZONE_DEFINED
#define _TIMEZONE_DEFINED
-struct timezone
+struct timezone
{
int tz_minuteswest; /* minutes W of Greenwich */
int tz_dsttime; /* type of dst correction */
diff --git a/src/win32/utf-conv.c b/src/win32/utf-conv.c
index c06f3a8c2..d4dbfbab9 100644
--- a/src/win32/utf-conv.c
+++ b/src/win32/utf-conv.c
@@ -70,12 +70,12 @@ void git__utf8_to_16(wchar_t *dest, size_t length, const char *src)
}
#endif
-int git__utf8_to_16(wchar_t *dest, size_t length, const char *src)
+int git__utf8_to_16(wchar_t * dest, size_t dest_size, const char *src)
{
- return MultiByteToWideChar(CP_UTF8, 0, src, -1, dest, (int)length);
+ return MultiByteToWideChar(CP_UTF8, 0, src, -1, dest, (int)dest_size);
}
-int git__utf16_to_8(char *out, const wchar_t *input)
+int git__utf16_to_8(char *dest, size_t dest_size, const wchar_t *src)
{
- return WideCharToMultiByte(CP_UTF8, 0, input, -1, out, GIT_WIN_PATH, NULL, NULL);
+ return WideCharToMultiByte(CP_UTF8, 0, src, -1, dest, (int)dest_size, NULL, NULL);
}
diff --git a/src/win32/utf-conv.h b/src/win32/utf-conv.h
index 6cc9205f7..3af77580e 100644
--- a/src/win32/utf-conv.h
+++ b/src/win32/utf-conv.h
@@ -4,16 +4,35 @@
* 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_utfconv_h__
+#define INCLUDE_git_utfconv_h__
#include <wchar.h>
+#include "common.h"
-#ifndef INCLUDE_git_utfconv_h__
-#define INCLUDE_git_utfconv_h__
+/* Maximum characters in a Windows path plus one for NUL byte */
+#define GIT_WIN_PATH_UTF16 (260 + 1)
-#define GIT_WIN_PATH (260 + 1)
+/* Maximum bytes necessary to convert a full-length UTF16 path to UTF8 */
+#define GIT_WIN_PATH_UTF8 (260 * 4 + 1)
-int git__utf8_to_16(wchar_t *dest, size_t length, const char *src);
-int git__utf16_to_8(char *dest, const wchar_t *src);
+typedef wchar_t git_win32_path[GIT_WIN_PATH_UTF16];
-#endif
+typedef char git_win32_path_as_utf8[GIT_WIN_PATH_UTF8];
+/* dest_size is the size of dest in wchar_t's */
+int git__utf8_to_16(wchar_t * dest, size_t dest_size, const char *src);
+/* dest_size is the size of dest in char's */
+int git__utf16_to_8(char *dest, size_t dest_size, const wchar_t *src);
+
+GIT_INLINE(int) git_win32_path_from_c(git_win32_path dest, const char *src)
+{
+ return git__utf8_to_16(dest, GIT_WIN_PATH_UTF16, src);
+}
+
+GIT_INLINE(int) git_win32_path_to_c(git_win32_path_as_utf8 dest, const wchar_t *src)
+{
+ return git__utf16_to_8(dest, GIT_WIN_PATH_UTF8, src);
+}
+
+#endif