Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
Merge pull request #86 from vangdfang/master
Browse files Browse the repository at this point in the history
Canonicalize paths into xutftowcs_path
  • Loading branch information
dscho committed Dec 30, 2013
2 parents ac03519 + cdff545 commit bac2422
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 16 deletions.
31 changes: 16 additions & 15 deletions compat/mingw.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ int mingw_unlink(const char *pathname)
{
int ret, tries = 0;
wchar_t wpathname[MAX_PATH];
if (xutftowcs_path(wpathname, pathname) < 0)
if (xutftowcs_canonical_path(wpathname, pathname) < 0)
return -1;

/* read-only files cannot be removed */
Expand Down Expand Up @@ -256,7 +256,7 @@ int mingw_rmdir(const char *pathname)
{
int ret, tries = 0;
wchar_t wpathname[MAX_PATH];
if (xutftowcs_path(wpathname, pathname) < 0)
if (xutftowcs_canonical_path(wpathname, pathname) < 0)
return -1;

while ((ret = _wrmdir(wpathname)) == -1 && tries < ARRAY_SIZE(delay)) {
Expand Down Expand Up @@ -298,7 +298,7 @@ void mingw_mark_as_git_dir(const char *dir)
{
wchar_t wdir[MAX_PATH];
if (hide_dotfiles != HIDE_DOTFILES_FALSE && !is_bare_repository())
if (xutftowcs_path(wdir, dir) < 0 || make_hidden(wdir))
if (xutftowcs_canonical_path(wdir, dir) < 0 || make_hidden(wdir))
warning("Failed to make '%s' hidden", dir);
git_config_set("core.hideDotFiles",
hide_dotfiles == HIDE_DOTFILES_FALSE ? "false" :
Expand All @@ -310,7 +310,7 @@ int mingw_mkdir(const char *path, int mode)
{
int ret;
wchar_t wpath[MAX_PATH];
if (xutftowcs_path(wpath, path) < 0)
if (xutftowcs_canonical_path(wpath, path) < 0)
return -1;
ret = _wmkdir(wpath);
if (!ret && hide_dotfiles == HIDE_DOTFILES_TRUE) {
Expand Down Expand Up @@ -340,7 +340,7 @@ int mingw_open (const char *filename, int oflags, ...)
if (filename && !strcmp(filename, "/dev/null"))
filename = "nul";

if (xutftowcs_path(wfilename, filename) < 0)
if (xutftowcs_canonical_path(wfilename, filename) < 0)
return -1;
fd = _wopen(wfilename, oflags, mode);

Expand Down Expand Up @@ -416,7 +416,7 @@ FILE *mingw_fopen (const char *filename, const char *otype)
hide = access(filename, F_OK);
if (filename && !strcmp(filename, "/dev/null"))
filename = "nul";
if (xutftowcs_path(wfilename, filename) < 0 ||
if (xutftowcs_canonical_path(wfilename, filename) < 0 ||
xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0)
return NULL;
file = _wfopen(wfilename, wotype);
Expand All @@ -435,7 +435,7 @@ FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream)
hide = access(filename, F_OK);
if (filename && !strcmp(filename, "/dev/null"))
filename = "nul";
if (xutftowcs_path(wfilename, filename) < 0 ||
if (xutftowcs_canonical_path(wfilename, filename) < 0 ||
xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0)
return NULL;
file = _wfreopen(wfilename, wotype, stream);
Expand Down Expand Up @@ -469,7 +469,7 @@ int mingw_fflush(FILE *stream)
int mingw_access(const char *filename, int mode)
{
wchar_t wfilename[MAX_PATH];
if (xutftowcs_path(wfilename, filename) < 0)
if (xutftowcs_canonical_path(wfilename, filename) < 0)
return -1;
/* X_OK is not supported by the MSVCRT version */
return _waccess(wfilename, mode & ~X_OK);
Expand All @@ -478,15 +478,15 @@ int mingw_access(const char *filename, int mode)
int mingw_chdir(const char *dirname)
{
wchar_t wdirname[MAX_PATH];
if (xutftowcs_path(wdirname, dirname) < 0)
if (xutftowcs_canonical_path(wdirname, dirname) < 0)
return -1;
return _wchdir(wdirname);
}

int mingw_chmod(const char *filename, int mode)
{
wchar_t wfilename[MAX_PATH];
if (xutftowcs_path(wfilename, filename) < 0)
if (xutftowcs_canonical_path(wfilename, filename) < 0)
return -1;
return _wchmod(wfilename, mode);
}
Expand All @@ -502,7 +502,7 @@ static int do_lstat(int follow, const char *file_name, struct stat *buf)
{
WIN32_FILE_ATTRIBUTE_DATA fdata;
wchar_t wfilename[MAX_PATH];
if (xutftowcs_path(wfilename, file_name) < 0)
if (xutftowcs_canonical_path(wfilename, file_name) < 0)
return -1;

if (GetFileAttributesExW(wfilename, GetFileExInfoStandard, &fdata)) {
Expand Down Expand Up @@ -646,7 +646,7 @@ int mingw_utime (const char *file_name, const struct utimbuf *times)
int fh, rc;
DWORD attrs;
wchar_t wfilename[MAX_PATH];
if (xutftowcs_path(wfilename, file_name) < 0)
if (xutftowcs_canonical_path(wfilename, file_name) < 0)
return -1;

/* must have write permission */
Expand Down Expand Up @@ -1629,7 +1629,8 @@ int mingw_rename(const char *pold, const char *pnew)
DWORD attrs, gle;
int tries = 0;
wchar_t wpold[MAX_PATH], wpnew[MAX_PATH];
if (xutftowcs_path(wpold, pold) < 0 || xutftowcs_path(wpnew, pnew) < 0)
if (xutftowcs_canonical_path(wpold, pold) < 0 ||
xutftowcs_canonical_path(wpnew, pnew) < 0)
return -1;

/*
Expand Down Expand Up @@ -1906,8 +1907,8 @@ int link(const char *oldpath, const char *newpath)
typedef BOOL (WINAPI *T)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
static T create_hard_link = NULL;
wchar_t woldpath[MAX_PATH], wnewpath[MAX_PATH];
if (xutftowcs_path(woldpath, oldpath) < 0 ||
xutftowcs_path(wnewpath, newpath) < 0)
if (xutftowcs_canonical_path(woldpath, oldpath) < 0 ||
xutftowcs_canonical_path(wnewpath, newpath) < 0)
return -1;

if (!create_hard_link) {
Expand Down
30 changes: 30 additions & 0 deletions compat/mingw.h
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,36 @@ static inline int xutftowcs_path(wchar_t *wcs, const char *utf)
return result;
}

/**
* Simplified file system specific variant of xutftowcsn, assumes output
* buffer size is MAX_PATH wide chars and input string is \0-terminated,
* fails with ENAMETOOLONG if input string is too long. This version
* also canonicalizes the path before returning.
*/
static inline int xutftowcs_canonical_path(wchar_t *wcs, const char *utf)
{
wchar_t tmp[SHRT_MAX];
int result;
result = xutftowcsn(tmp, utf, SHRT_MAX, -1);
if (result < 0 && errno == ERANGE)
errno = ENAMETOOLONG;
else if (wcsncmp(tmp, L"nul", 4) == 0 )
wcsncpy(wcs, tmp, 4);
else {
wchar_t tmp2[SHRT_MAX];
GetFullPathNameW(tmp, SHRT_MAX, tmp2, NULL);
if (wcslen(tmp2) < MAX_PATH)
wcsncpy(wcs, tmp2, MAX_PATH - 1);
else {
result = -1;
errno = ENAMETOOLONG;
}
}
if (result != -1)
result = wcslen(wcs);
return result;
}

/**
* Converts UTF-16LE encoded string to UTF-8.
*
Expand Down
2 changes: 1 addition & 1 deletion compat/win32/dirent.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ DIR *dirent_opendir(const char *name)
dirent_DIR *dir;

/* convert name to UTF-16 and check length < MAX_PATH */
if ((len = xutftowcs_path(pattern, name)) < 0)
if ((len = xutftowcs_canonical_path(pattern, name)) < 0)
return NULL;

/* append optional '/' and wildcard '*' */
Expand Down

0 comments on commit bac2422

Please sign in to comment.