* file.c (file_expand_path): buffer might be reallocated while

expanding default directory.

* file.c (file_expand_path): default directory was being
  ignored if path was full path with no drive letter, under
  DOSISH.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3497 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2003-02-16 10:22:36 +00:00
Родитель 2f7275db77
Коммит d0d70d648d
3 изменённых файлов: 59 добавлений и 46 удалений

Просмотреть файл

@ -1,3 +1,12 @@
Sun Feb 16 19:22:31 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* file.c (file_expand_path): buffer might be reallocated while
expanding default directory.
* file.c (file_expand_path): default directory was being
ignored if path was full path with no drive letter, under
DOSISH.
Sun Feb 16 03:14:33 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* io.c (prep_stdio, Init_io): always set binmode on Cygwin.

88
file.c
Просмотреть файл

@ -1424,6 +1424,16 @@ skiproot(path)
return (char *)path;
}
static inline char *
nextdirsep(s)
const char *s;
{
while (*s && !isdirsep(*s)) {
s = CharNext(s);
}
return (char *)s;
}
static char *
strrdirsep(path)
const char *path;
@ -1469,6 +1479,11 @@ chompdirsep(path)
pend = buf + buflen;\
}
#define BUFINIT() (\
p = buf = RSTRING(result)->ptr,\
buflen = RSTRING(result)->len,\
pend = p + buflen)
#if !defined(TOLOWER)
#define TOLOWER(c) (ISUPPER(c) ? tolower(c) : (c))
#endif
@ -1484,9 +1499,7 @@ file_expand_path(fname, dname, result)
int tainted;
s = StringValuePtr(fname);
p = buf = RSTRING(result)->ptr;
buflen = RSTRING(result)->len - 2;
pend = p + buflen;
BUFINIT();
tainted = OBJ_TAINTED(fname);
if (s[0] == '~') {
@ -1515,10 +1528,7 @@ file_expand_path(fname, dname, result)
struct passwd *pwPtr;
s++;
#endif
b = s;
while (*s && !isdirsep(*s)) {
s = CharNext(s);
}
s = nextdirsep(b = s);
BUFCHECK(p + (s-b) >= pend);
memcpy(p, b, s-b);
p += s-b;
@ -1542,26 +1552,24 @@ file_expand_path(fname, dname, result)
if (isdirsep(s[2])) {
/* specified drive letter, and full path */
/* skip drive letter */
b = s;
while (*s && !isdirsep(*s)) {
s = CharNext(s);
}
BUFCHECK(p + (s-b) >= pend);
memcpy(p, b, s-b);
p += s-b;
BUFCHECK(p + 2 >= pend);
memcpy(p, s, 2);
p += 2;
s += 2;
}
else {
/* specified drive, but not full path */
int same = 0;
if (!NIL_P(dname)) {
dname = file_expand_path(dname, Qnil, result);
if (has_drive_letter(RSTRING(dname)->ptr) &&
TOLOWER(*RSTRING(dname)->ptr) == TOLOWER(s[0])) {
file_expand_path(dname, Qnil, result);
BUFINIT();
if (has_drive_letter(p) && TOLOWER(p[0]) == TOLOWER(s[0])) {
/* ok, same drive */
same = 1;
}
}
if (!same) {
BUFCHECK(buflen < MAXPATHLEN);
getcwdofdrv(*s, buf, MAXPATHLEN);
tainted = 1;
}
@ -1569,37 +1577,11 @@ file_expand_path(fname, dname, result)
s += 2;
}
}
#endif
#ifdef DOSISH
else if (isdirsep(*s) && !is_absolute_path(s)) {
/* specified full path, but not drive letter */
/* we need to get the drive letter */
tainted = 1;
getcwd(buf, MAXPATHLEN);
p = &buf[2];
if (!isdirsep(*p)) {
while (*p && !isdirsep(*p)) {
p = CharNext(p);
}
if (*p) {
p++;
while (*p && !isdirsep(*p)) {
p = CharNext(p);
}
}
}
b = s;
while (*s && !isdirsep(*s)) {
s = CharNext(s);
}
BUFCHECK(p + (s-b) >= pend);
memcpy(p, b, s-b);
p += s-b;
}
#endif
else if (!is_absolute_path(s)) {
if (!NIL_P(dname)) {
file_expand_path(dname, Qnil, result);
BUFINIT();
}
else {
char *dir = my_getcwd();
@ -1610,9 +1592,23 @@ file_expand_path(fname, dname, result)
free(dir);
}
p = skiproot(buf);
#ifdef DOSISH
if (isdirsep(*s)) {
/* specified full path, but not drive letter nor UNC */
if (has_drive_letter(buf)) {
/* we need to get the drive letter */
p = &buf[2];
}
else if (isdirsep(buf[0]) && isdirsep(buf[1])) {
/* or UNC share name */
if (*(p = nextdirsep(p))) p = nextdirsep(p + 1);
}
}
else
#endif
if (*p)
p = chompdirsep(p);
else
else if (p > buf)
--p;
}
else {
@ -2541,7 +2537,7 @@ is_absolute_path(path)
const char *path;
{
#ifdef DOSISH_DRIVE_LETTER
if (ISALPHA(path[0]) && path[1] == ':' && isdirsep(path[2])) return 1;
if (has_drive_letter(path) && isdirsep(path[2])) return 1;
#endif
#ifdef DOSISH_UNC
if (isdirsep(path[0]) && isdirsep(path[1])) return 1;

Просмотреть файл

@ -1675,13 +1675,21 @@ case Dir.pwd
when %r'\A\w:'
test_ok(/\A\w:\/\z/ =~ File.expand_path(".", "/"))
test_ok(/\A\w:\/a\z/ =~ File.expand_path("a", "/"))
dosish = true
when %r'\A//'
test_ok(%r'\A//[^/]+/[^/]+\z' =~ File.expand_path(".", "/"))
test_ok(%r'\A//[^/]+/[^/]+/a\z' =~ File.expand_path(".", "/"))
dosish = true
else
test_ok(File.expand_path(".", "/") == "/")
test_ok(File.expand_path("sub", "/") == "/sub")
end
if dosish
test_ok(File.expand_path("/", "//machine/share/sub") == "//machine/share")
test_ok(File.expand_path("/dir", "//machine/share/sub") == "//machine/share/dir")
test_ok(File.expand_path("/", "z:/sub") == "z:/")
test_ok(File.expand_path("/dir", "z:/sub") == "z:/dir")
end
test_ok(File.expand_path(".", "//") == "//")
test_ok(File.expand_path("sub", "//") == "//sub")