mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
dir.c: normalize CIFS too
* dir.c (need_normalization): not only HFS+, CIFS (SMB) is also decomposed. [Bug #10704] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49168 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
b04c628792
commit
376c4e8100
2 changed files with 50 additions and 29 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
Wed Jan 7 18:52:50 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* dir.c (need_normalization): not only HFS+, CIFS (SMB) is also
|
||||||
|
decomposed. [Bug #10704]
|
||||||
|
|
||||||
|
* dir.c (NORMALIZE_UTF8PATH): Unicode decomposition seems to
|
||||||
|
perform in an upper layer than file systems on OSX, as all path
|
||||||
|
names are always decomposed regardless of file system types.
|
||||||
|
|
||||||
Tue Jan 6 21:41:04 2015 Tanaka Akira <akr@fsij.org>
|
Tue Jan 6 21:41:04 2015 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* time.c (timelocalw): Set tm_isdst field -1 if vtm->isdst is
|
* time.c (timelocalw): Set tm_isdst field -1 if vtm->isdst is
|
||||||
|
|
70
dir.c
70
dir.c
|
@ -79,26 +79,38 @@ char *strchr(char*,char);
|
||||||
|
|
||||||
#ifdef HAVE_GETATTRLIST
|
#ifdef HAVE_GETATTRLIST
|
||||||
# define USE_NAME_ON_FS 1
|
# define USE_NAME_ON_FS 1
|
||||||
|
# define RUP32(size) ((size)+3/4)
|
||||||
|
# define SIZEUP32(type) RUP32(sizeof(type))
|
||||||
|
# define NEXT(var) var = (void *)((ptr += SIZEUP32(var)) - SIZEUP32(var))
|
||||||
#else
|
#else
|
||||||
# define USE_NAME_ON_FS 0
|
# define USE_NAME_ON_FS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
# define HAVE_HFS 1
|
# define NORMALIZE_UTF8PATH 1
|
||||||
#else
|
#else
|
||||||
# define HAVE_HFS 0
|
# define NORMALIZE_UTF8PATH 0
|
||||||
#endif
|
#endif
|
||||||
#if HAVE_HFS
|
#if NORMALIZE_UTF8PATH
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
|
#include <sys/vnode.h>
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
is_hfs(DIR *dirp)
|
need_normalization(DIR *dirp)
|
||||||
{
|
{
|
||||||
struct statfs buf;
|
# ifdef HAVE_GETATTRLIST
|
||||||
if (fstatfs(dirfd(dirp), &buf) == 0) {
|
u_int32_t attrbuf[SIZEUP32(fsobj_tag_t)];
|
||||||
return buf.f_type == 17; /* HFS on darwin */
|
struct attrlist al = {ATTR_BIT_MAP_COUNT, 0, ATTR_CMN_OBJTAG,};
|
||||||
|
if (!fgetattrlist(dirfd(dirp), &al, attrbuf, sizeof(attrbuf), 0)) {
|
||||||
|
const fsobj_tag_t *tag = (void *)(attrbuf+1);
|
||||||
|
switch (*tag) {
|
||||||
|
case VT_HFS:
|
||||||
|
case VT_CIFS:
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,9 +125,9 @@ has_nonascii(const char *ptr, size_t len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
# define IF_HAVE_HFS(something) something
|
# define IF_NORMALIZE_UTF8PATH(something) something
|
||||||
#else
|
#else
|
||||||
# define IF_HAVE_HFS(something) /* nothing */
|
# define IF_NORMALIZE_UTF8PATH(something) /* nothing */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FNM_NOESCAPE 0x01
|
#define FNM_NOESCAPE 0x01
|
||||||
|
@ -658,18 +670,18 @@ dir_each(VALUE dir)
|
||||||
{
|
{
|
||||||
struct dir_data *dirp;
|
struct dir_data *dirp;
|
||||||
struct dirent *dp;
|
struct dirent *dp;
|
||||||
IF_HAVE_HFS(int hfs_p);
|
IF_NORMALIZE_UTF8PATH(int norm_p);
|
||||||
|
|
||||||
RETURN_ENUMERATOR(dir, 0, 0);
|
RETURN_ENUMERATOR(dir, 0, 0);
|
||||||
GetDIR(dir, dirp);
|
GetDIR(dir, dirp);
|
||||||
rewinddir(dirp->dir);
|
rewinddir(dirp->dir);
|
||||||
IF_HAVE_HFS(hfs_p = is_hfs(dirp->dir));
|
IF_NORMALIZE_UTF8PATH(norm_p = need_normalization(dirp->dir));
|
||||||
while ((dp = READDIR(dirp->dir, dirp->enc)) != NULL) {
|
while ((dp = READDIR(dirp->dir, dirp->enc)) != NULL) {
|
||||||
const char *name = dp->d_name;
|
const char *name = dp->d_name;
|
||||||
size_t namlen = NAMLEN(dp);
|
size_t namlen = NAMLEN(dp);
|
||||||
VALUE path;
|
VALUE path;
|
||||||
#if HAVE_HFS
|
#if NORMALIZE_UTF8PATH
|
||||||
if (hfs_p && has_nonascii(name, namlen) &&
|
if (norm_p && has_nonascii(name, namlen) &&
|
||||||
!NIL_P(path = rb_str_normalize_ospath(name, namlen))) {
|
!NIL_P(path = rb_str_normalize_ospath(name, namlen))) {
|
||||||
path = rb_external_str_with_enc(path, dirp->enc);
|
path = rb_external_str_with_enc(path, dirp->enc);
|
||||||
}
|
}
|
||||||
|
@ -1328,7 +1340,7 @@ join_path(const char *path, long len, int dirsep, const char *name, size_t namle
|
||||||
|
|
||||||
#ifdef HAVE_GETATTRLIST
|
#ifdef HAVE_GETATTRLIST
|
||||||
static char *
|
static char *
|
||||||
replace_real_basename(char *path, long base, int hfs_p)
|
replace_real_basename(char *path, long base, int norm_p)
|
||||||
{
|
{
|
||||||
u_int32_t attrbuf[(sizeof(attrreference_t) + MAXPATHLEN * 3 + sizeof(u_int32_t) - 1) / sizeof(u_int32_t) + 1];
|
u_int32_t attrbuf[(sizeof(attrreference_t) + MAXPATHLEN * 3 + sizeof(u_int32_t) - 1) / sizeof(u_int32_t) + 1];
|
||||||
struct attrlist al = {ATTR_BIT_MAP_COUNT, 0, ATTR_CMN_NAME};
|
struct attrlist al = {ATTR_BIT_MAP_COUNT, 0, ATTR_CMN_NAME};
|
||||||
|
@ -1336,7 +1348,7 @@ replace_real_basename(char *path, long base, int hfs_p)
|
||||||
const char *name;
|
const char *name;
|
||||||
long len;
|
long len;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
IF_HAVE_HFS(VALUE utf8str = Qnil);
|
IF_NORMALIZE_UTF8PATH(VALUE utf8str = Qnil);
|
||||||
|
|
||||||
if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), FSOPT_NOFOLLOW))
|
if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), FSOPT_NOFOLLOW))
|
||||||
return path;
|
return path;
|
||||||
|
@ -1346,8 +1358,8 @@ replace_real_basename(char *path, long base, int hfs_p)
|
||||||
if (name + len > (char *)attrbuf + sizeof(attrbuf))
|
if (name + len > (char *)attrbuf + sizeof(attrbuf))
|
||||||
return path;
|
return path;
|
||||||
|
|
||||||
# if HAVE_HFS
|
# if NORMALIZE_UTF8PATH
|
||||||
if (hfs_p && has_nonascii(name, len)) {
|
if (norm_p && has_nonascii(name, len)) {
|
||||||
if (!NIL_P(utf8str = rb_str_normalize_ospath(name, len))) {
|
if (!NIL_P(utf8str = rb_str_normalize_ospath(name, len))) {
|
||||||
RSTRING_GETMEM(utf8str, name, len);
|
RSTRING_GETMEM(utf8str, name, len);
|
||||||
}
|
}
|
||||||
|
@ -1360,7 +1372,7 @@ replace_real_basename(char *path, long base, int hfs_p)
|
||||||
memcpy(path + base, name, len);
|
memcpy(path + base, name, len);
|
||||||
path[base + len] = '\0';
|
path[base + len] = '\0';
|
||||||
}
|
}
|
||||||
IF_HAVE_HFS(if (!NIL_P(utf8str)) rb_str_resize(utf8str, 0));
|
IF_NORMALIZE_UTF8PATH(if (!NIL_P(utf8str)) rb_str_resize(utf8str, 0));
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1491,7 +1503,7 @@ glob_helper(
|
||||||
# ifdef DOSISH
|
# ifdef DOSISH
|
||||||
char *plainname = 0;
|
char *plainname = 0;
|
||||||
# endif
|
# endif
|
||||||
IF_HAVE_HFS(int hfs_p);
|
IF_NORMALIZE_UTF8PATH(int norm_p);
|
||||||
# ifdef DOSISH
|
# ifdef DOSISH
|
||||||
if (cur + 1 == end && (*cur)->type <= ALPHA) {
|
if (cur + 1 == end && (*cur)->type <= ALPHA) {
|
||||||
plainname = join_path(path, pathlen, dirsep, (*cur)->str, strlen((*cur)->str));
|
plainname = join_path(path, pathlen, dirsep, (*cur)->str, strlen((*cur)->str));
|
||||||
|
@ -1503,7 +1515,7 @@ glob_helper(
|
||||||
# endif
|
# endif
|
||||||
dirp = do_opendir(*path ? path : ".", flags, enc);
|
dirp = do_opendir(*path ? path : ".", flags, enc);
|
||||||
if (dirp == NULL) {
|
if (dirp == NULL) {
|
||||||
# if FNM_SYSCASE || HAVE_HFS
|
# if FNM_SYSCASE || NORMALIZE_UTF8PATH
|
||||||
if ((magical < 2) && !recursive && (errno == EACCES)) {
|
if ((magical < 2) && !recursive && (errno == EACCES)) {
|
||||||
/* no read permission, fallback */
|
/* no read permission, fallback */
|
||||||
goto literally;
|
goto literally;
|
||||||
|
@ -1511,10 +1523,10 @@ glob_helper(
|
||||||
# endif
|
# endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
IF_HAVE_HFS(hfs_p = is_hfs(dirp));
|
IF_NORMALIZE_UTF8PATH(norm_p = need_normalization(dirp));
|
||||||
|
|
||||||
# if HAVE_HFS
|
# if NORMALIZE_UTF8PATH
|
||||||
if (!(hfs_p || magical || recursive)) {
|
if (!(norm_p || magical || recursive)) {
|
||||||
closedir(dirp);
|
closedir(dirp);
|
||||||
goto literally;
|
goto literally;
|
||||||
}
|
}
|
||||||
|
@ -1526,7 +1538,7 @@ glob_helper(
|
||||||
const char *name;
|
const char *name;
|
||||||
size_t namlen;
|
size_t namlen;
|
||||||
int dotfile = 0;
|
int dotfile = 0;
|
||||||
IF_HAVE_HFS(VALUE utf8str = Qnil);
|
IF_NORMALIZE_UTF8PATH(VALUE utf8str = Qnil);
|
||||||
|
|
||||||
if (recursive && dp->d_name[0] == '.') {
|
if (recursive && dp->d_name[0] == '.') {
|
||||||
++dotfile;
|
++dotfile;
|
||||||
|
@ -1543,15 +1555,15 @@ glob_helper(
|
||||||
|
|
||||||
name = dp->d_name;
|
name = dp->d_name;
|
||||||
namlen = NAMLEN(dp);
|
namlen = NAMLEN(dp);
|
||||||
# if HAVE_HFS
|
# if NORMALIZE_UTF8PATH
|
||||||
if (hfs_p && has_nonascii(name, namlen)) {
|
if (norm_p && has_nonascii(name, namlen)) {
|
||||||
if (!NIL_P(utf8str = rb_str_normalize_ospath(name, namlen))) {
|
if (!NIL_P(utf8str = rb_str_normalize_ospath(name, namlen))) {
|
||||||
RSTRING_GETMEM(utf8str, name, namlen);
|
RSTRING_GETMEM(utf8str, name, namlen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
buf = join_path(path, pathlen, dirsep, name, namlen);
|
buf = join_path(path, pathlen, dirsep, name, namlen);
|
||||||
IF_HAVE_HFS(if (!NIL_P(utf8str)) rb_str_resize(utf8str, 0));
|
IF_NORMALIZE_UTF8PATH(if (!NIL_P(utf8str)) rb_str_resize(utf8str, 0));
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
status = -1;
|
status = -1;
|
||||||
break;
|
break;
|
||||||
|
@ -1612,7 +1624,7 @@ glob_helper(
|
||||||
else if (plain) {
|
else if (plain) {
|
||||||
struct glob_pattern **copy_beg, **copy_end, **cur2;
|
struct glob_pattern **copy_beg, **copy_end, **cur2;
|
||||||
|
|
||||||
# if FNM_SYSCASE || HAVE_HFS
|
# if FNM_SYSCASE || NORMALIZE_UTF8PATH
|
||||||
literally:
|
literally:
|
||||||
# endif
|
# endif
|
||||||
copy_beg = copy_end = GLOB_ALLOC_N(struct glob_pattern *, end - beg);
|
copy_beg = copy_end = GLOB_ALLOC_N(struct glob_pattern *, end - beg);
|
||||||
|
@ -1658,7 +1670,7 @@ glob_helper(
|
||||||
#ifdef HAVE_GETATTRLIST
|
#ifdef HAVE_GETATTRLIST
|
||||||
if ((*cur)->type == ALPHA) {
|
if ((*cur)->type == ALPHA) {
|
||||||
long base = pathlen + (dirsep != 0);
|
long base = pathlen + (dirsep != 0);
|
||||||
buf = replace_real_basename(buf, base, IF_HAVE_HFS(1)+0);
|
buf = replace_real_basename(buf, base, IF_NORMALIZE_UTF8PATH(1)+0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
status = glob_helper(buf, 1, UNKNOWN, UNKNOWN, new_beg,
|
status = glob_helper(buf, 1, UNKNOWN, UNKNOWN, new_beg,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue