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

Commit bac2422

Browse files
committed
Merge pull request #86 from vangdfang/master
Canonicalize paths into xutftowcs_path
2 parents ac03519 + cdff545 commit bac2422

File tree

3 files changed

+47
-16
lines changed

3 files changed

+47
-16
lines changed

compat/mingw.c

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ int mingw_unlink(const char *pathname)
205205
{
206206
int ret, tries = 0;
207207
wchar_t wpathname[MAX_PATH];
208-
if (xutftowcs_path(wpathname, pathname) < 0)
208+
if (xutftowcs_canonical_path(wpathname, pathname) < 0)
209209
return -1;
210210

211211
/* read-only files cannot be removed */
@@ -256,7 +256,7 @@ int mingw_rmdir(const char *pathname)
256256
{
257257
int ret, tries = 0;
258258
wchar_t wpathname[MAX_PATH];
259-
if (xutftowcs_path(wpathname, pathname) < 0)
259+
if (xutftowcs_canonical_path(wpathname, pathname) < 0)
260260
return -1;
261261

262262
while ((ret = _wrmdir(wpathname)) == -1 && tries < ARRAY_SIZE(delay)) {
@@ -298,7 +298,7 @@ void mingw_mark_as_git_dir(const char *dir)
298298
{
299299
wchar_t wdir[MAX_PATH];
300300
if (hide_dotfiles != HIDE_DOTFILES_FALSE && !is_bare_repository())
301-
if (xutftowcs_path(wdir, dir) < 0 || make_hidden(wdir))
301+
if (xutftowcs_canonical_path(wdir, dir) < 0 || make_hidden(wdir))
302302
warning("Failed to make '%s' hidden", dir);
303303
git_config_set("core.hideDotFiles",
304304
hide_dotfiles == HIDE_DOTFILES_FALSE ? "false" :
@@ -310,7 +310,7 @@ int mingw_mkdir(const char *path, int mode)
310310
{
311311
int ret;
312312
wchar_t wpath[MAX_PATH];
313-
if (xutftowcs_path(wpath, path) < 0)
313+
if (xutftowcs_canonical_path(wpath, path) < 0)
314314
return -1;
315315
ret = _wmkdir(wpath);
316316
if (!ret && hide_dotfiles == HIDE_DOTFILES_TRUE) {
@@ -340,7 +340,7 @@ int mingw_open (const char *filename, int oflags, ...)
340340
if (filename && !strcmp(filename, "/dev/null"))
341341
filename = "nul";
342342

343-
if (xutftowcs_path(wfilename, filename) < 0)
343+
if (xutftowcs_canonical_path(wfilename, filename) < 0)
344344
return -1;
345345
fd = _wopen(wfilename, oflags, mode);
346346

@@ -416,7 +416,7 @@ FILE *mingw_fopen (const char *filename, const char *otype)
416416
hide = access(filename, F_OK);
417417
if (filename && !strcmp(filename, "/dev/null"))
418418
filename = "nul";
419-
if (xutftowcs_path(wfilename, filename) < 0 ||
419+
if (xutftowcs_canonical_path(wfilename, filename) < 0 ||
420420
xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0)
421421
return NULL;
422422
file = _wfopen(wfilename, wotype);
@@ -435,7 +435,7 @@ FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream)
435435
hide = access(filename, F_OK);
436436
if (filename && !strcmp(filename, "/dev/null"))
437437
filename = "nul";
438-
if (xutftowcs_path(wfilename, filename) < 0 ||
438+
if (xutftowcs_canonical_path(wfilename, filename) < 0 ||
439439
xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0)
440440
return NULL;
441441
file = _wfreopen(wfilename, wotype, stream);
@@ -469,7 +469,7 @@ int mingw_fflush(FILE *stream)
469469
int mingw_access(const char *filename, int mode)
470470
{
471471
wchar_t wfilename[MAX_PATH];
472-
if (xutftowcs_path(wfilename, filename) < 0)
472+
if (xutftowcs_canonical_path(wfilename, filename) < 0)
473473
return -1;
474474
/* X_OK is not supported by the MSVCRT version */
475475
return _waccess(wfilename, mode & ~X_OK);
@@ -478,15 +478,15 @@ int mingw_access(const char *filename, int mode)
478478
int mingw_chdir(const char *dirname)
479479
{
480480
wchar_t wdirname[MAX_PATH];
481-
if (xutftowcs_path(wdirname, dirname) < 0)
481+
if (xutftowcs_canonical_path(wdirname, dirname) < 0)
482482
return -1;
483483
return _wchdir(wdirname);
484484
}
485485

486486
int mingw_chmod(const char *filename, int mode)
487487
{
488488
wchar_t wfilename[MAX_PATH];
489-
if (xutftowcs_path(wfilename, filename) < 0)
489+
if (xutftowcs_canonical_path(wfilename, filename) < 0)
490490
return -1;
491491
return _wchmod(wfilename, mode);
492492
}
@@ -502,7 +502,7 @@ static int do_lstat(int follow, const char *file_name, struct stat *buf)
502502
{
503503
WIN32_FILE_ATTRIBUTE_DATA fdata;
504504
wchar_t wfilename[MAX_PATH];
505-
if (xutftowcs_path(wfilename, file_name) < 0)
505+
if (xutftowcs_canonical_path(wfilename, file_name) < 0)
506506
return -1;
507507

508508
if (GetFileAttributesExW(wfilename, GetFileExInfoStandard, &fdata)) {
@@ -646,7 +646,7 @@ int mingw_utime (const char *file_name, const struct utimbuf *times)
646646
int fh, rc;
647647
DWORD attrs;
648648
wchar_t wfilename[MAX_PATH];
649-
if (xutftowcs_path(wfilename, file_name) < 0)
649+
if (xutftowcs_canonical_path(wfilename, file_name) < 0)
650650
return -1;
651651

652652
/* must have write permission */
@@ -1629,7 +1629,8 @@ int mingw_rename(const char *pold, const char *pnew)
16291629
DWORD attrs, gle;
16301630
int tries = 0;
16311631
wchar_t wpold[MAX_PATH], wpnew[MAX_PATH];
1632-
if (xutftowcs_path(wpold, pold) < 0 || xutftowcs_path(wpnew, pnew) < 0)
1632+
if (xutftowcs_canonical_path(wpold, pold) < 0 ||
1633+
xutftowcs_canonical_path(wpnew, pnew) < 0)
16331634
return -1;
16341635

16351636
/*
@@ -1906,8 +1907,8 @@ int link(const char *oldpath, const char *newpath)
19061907
typedef BOOL (WINAPI *T)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
19071908
static T create_hard_link = NULL;
19081909
wchar_t woldpath[MAX_PATH], wnewpath[MAX_PATH];
1909-
if (xutftowcs_path(woldpath, oldpath) < 0 ||
1910-
xutftowcs_path(wnewpath, newpath) < 0)
1910+
if (xutftowcs_canonical_path(woldpath, oldpath) < 0 ||
1911+
xutftowcs_canonical_path(wnewpath, newpath) < 0)
19111912
return -1;
19121913

19131914
if (!create_hard_link) {

compat/mingw.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,36 @@ static inline int xutftowcs_path(wchar_t *wcs, const char *utf)
449449
return result;
450450
}
451451

452+
/**
453+
* Simplified file system specific variant of xutftowcsn, assumes output
454+
* buffer size is MAX_PATH wide chars and input string is \0-terminated,
455+
* fails with ENAMETOOLONG if input string is too long. This version
456+
* also canonicalizes the path before returning.
457+
*/
458+
static inline int xutftowcs_canonical_path(wchar_t *wcs, const char *utf)
459+
{
460+
wchar_t tmp[SHRT_MAX];
461+
int result;
462+
result = xutftowcsn(tmp, utf, SHRT_MAX, -1);
463+
if (result < 0 && errno == ERANGE)
464+
errno = ENAMETOOLONG;
465+
else if (wcsncmp(tmp, L"nul", 4) == 0 )
466+
wcsncpy(wcs, tmp, 4);
467+
else {
468+
wchar_t tmp2[SHRT_MAX];
469+
GetFullPathNameW(tmp, SHRT_MAX, tmp2, NULL);
470+
if (wcslen(tmp2) < MAX_PATH)
471+
wcsncpy(wcs, tmp2, MAX_PATH - 1);
472+
else {
473+
result = -1;
474+
errno = ENAMETOOLONG;
475+
}
476+
}
477+
if (result != -1)
478+
result = wcslen(wcs);
479+
return result;
480+
}
481+
452482
/**
453483
* Converts UTF-16LE encoded string to UTF-8.
454484
*

compat/win32/dirent.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ DIR *dirent_opendir(const char *name)
7070
dirent_DIR *dir;
7171

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

7676
/* append optional '/' and wildcard '*' */

0 commit comments

Comments
 (0)