summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--file.c88
-rw-r--r--sample/test.rb8
3 files changed, 59 insertions, 46 deletions
diff --git a/ChangeLog b/ChangeLog
index acbcf0b7ea..e0902dcdfe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/file.c b/file.c
index 165e6eeec2..cb7c2c8814 100644
--- a/file.c
+++ b/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;
}
@@ -1570,36 +1578,10 @@ file_expand_path(fname, dname, result)
}
}
#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;
diff --git a/sample/test.rb b/sample/test.rb
index 7194e072b1..d0a364f17c 100644
--- a/sample/test.rb
+++ b/sample/test.rb
@@ -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")