From 43f68272c7fc50ba33c58f7e22923bac6fc204ac Mon Sep 17 00:00:00 2001 From: matz Date: Mon, 4 Feb 2002 08:09:14 +0000 Subject: * object.c (rb_class_real): should not follow ICLASS link * variable.c (classname): should follow ICLASS link explicitly. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2042 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 6 ++++++ eval.c | 5 +++-- file.c | 59 +++++++++++++++++++++++++++++++++++------------------------ lib/debug.rb | 4 ++-- object.c | 3 --- variable.c | 8 ++++++-- 6 files changed, 52 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index b138cdc72b..8a0ca19505 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Mon Feb 4 15:38:29 2002 Yukihiro Matsumoto + + * object.c (rb_class_real): should not follow ICLASS link + + * variable.c (classname): should follow ICLASS link explicitly. + Fri Feb 1 19:10:04 2002 Nobuyoshi Nakada * intern.h: prototypes for new functions; rb_cstr_to_inum(), diff --git a/eval.c b/eval.c index 576b98b529..a9b79403b5 100644 --- a/eval.c +++ b/eval.c @@ -1803,7 +1803,7 @@ is_defined(self, node, buf) case NODE_VCALL: case NODE_FCALL: - val = CLASS_OF(self); + val = self; goto check_bound; case NODE_CALL: @@ -1811,7 +1811,6 @@ is_defined(self, node, buf) PUSH_TAG(PROT_NONE); if ((state = EXEC_TAG()) == 0) { val = rb_eval(self, node->nd_recv); - val = CLASS_OF(val); } POP_TAG(); if (state) { @@ -1821,6 +1820,8 @@ is_defined(self, node, buf) check_bound: { int call = nd_type(node)== NODE_CALL; + + val = CLASS_OF(val); if (call) { int noex; ID id = node->nd_mid; diff --git a/file.c b/file.c index ddd282c6c9..b358c526b4 100644 --- a/file.c +++ b/file.c @@ -1377,22 +1377,33 @@ strrdirsep(path) return last; } +#define BUFCHECK(cond) while (cond) {\ + long bdiff = p - buf;\ + buflen *= 2;\ + rb_str_resize(result, buflen);\ + buf = RSTRING(result)->ptr;\ + p = buf + bdiff;\ + pend = buf + buflen;\ +} + VALUE rb_file_s_expand_path(argc, argv) int argc; VALUE *argv; { - VALUE fname, dname; - char *s, *p, *b; - char buf[MAXPATHLEN+2]; - char *bend = buf + sizeof(buf) - 2; + VALUE fname, dname, result; + char *s, *buf, *b, *p, *pend; + long buflen = MAXPATHLEN; int tainted; rb_scan_args(argc, argv, "11", &fname, &dname); + result = rb_str_new(0, buflen + 2); - tainted = OBJ_TAINTED(fname); s = StringValuePtr(fname); - p = buf; + p = buf = RSTRING(result)->ptr; + pend = p + buflen; + tainted = OBJ_TAINTED(fname); + if (s[0] == '~') { if (isdirsep(s[1]) || s[1] == '\0') { char *dir = getenv("HOME"); @@ -1400,9 +1411,9 @@ rb_file_s_expand_path(argc, argv) if (!dir) { rb_raise(rb_eArgError, "couldn't find HOME environment -- expanding `%s'", s); } - if (strlen(dir) > MAXPATHLEN) goto toolong; + BUFCHECK (strlen(dir) > buflen); strcpy(buf, dir); - p = &buf[strlen(buf)]; + p = buf + strlen(dir); s++; tainted = 1; } @@ -1415,7 +1426,7 @@ rb_file_s_expand_path(argc, argv) while (*s && !isdirsep(*s)) { s = CharNext(s); } - if (p + (s-b) >= bend) goto toolong; + BUFCHECK (p + (s-b) >= pend); memcpy(p, b, s-b); p += s-b; *p = '\0'; @@ -1425,9 +1436,9 @@ rb_file_s_expand_path(argc, argv) endpwent(); rb_raise(rb_eArgError, "user %s doesn't exist", buf); } - if (strlen(pwPtr->pw_dir) > MAXPATHLEN) goto toolong; + BUFCHECK (strlen(pwPtr->pw_dir) > buflen); strcpy(buf, pwPtr->pw_dir); - p = &buf[strlen(buf)]; + p = buf + strlen(pwPtr->pw_dir); endpwent(); #endif } @@ -1439,7 +1450,7 @@ rb_file_s_expand_path(argc, argv) while (*s && !isdirsep(*s)) { s = CharNext(s); } - if (p + (s-b) >= bend) goto toolong; + BUFCHECK (p + (s-b) >= pend); memcpy(p, b, s-b); p += s-b; } @@ -1448,12 +1459,15 @@ rb_file_s_expand_path(argc, argv) if (!NIL_P(dname)) { dname = rb_file_s_expand_path(1, &dname); if (OBJ_TAINTED(dname)) tainted = 1; - if (strlen(RSTRING(dname)->ptr) > MAXPATHLEN) goto toolong; + BUFCHECK (strlen(RSTRING(dname)->ptr) > buflen); strcpy(buf, RSTRING(dname)->ptr); } else { + char *dir = my_getcwd(); + tainted = 1; - getcwd(buf, MAXPATHLEN); + BUFCHECK (strlen(dir) > buflen); + strcpy(buf, dir); } p = &buf[strlen(buf)]; while (p > buf && *(p - 1) == '/') p--; @@ -1461,7 +1475,7 @@ rb_file_s_expand_path(argc, argv) else { while (*s && isdirsep(*s)) { *p++ = '/'; - if (p >= bend) goto toolong; + BUFCHECK (p >= pend); s++; } if (p > buf && *s) p--; @@ -1507,7 +1521,7 @@ rb_file_s_expand_path(argc, argv) case '\\': #endif if (s > b) { - if (p + (s-b+1) >= bend) goto toolong; + BUFCHECK (p + (s-b+1) >= pend); memcpy(++p, b, s-b); p += s-b; *p = '/'; @@ -1521,7 +1535,7 @@ rb_file_s_expand_path(argc, argv) } if (s > b) { - if (p + (s-b) >= bend) goto toolong; + BUFCHECK (p + (s-b) >= pend); memcpy(++p, b, s-b); p += s-b; } @@ -1539,13 +1553,9 @@ rb_file_s_expand_path(argc, argv) } #endif - fname = rb_str_new(buf, p - buf); - if (tainted) OBJ_TAINT(fname); - return fname; - - toolong: - rb_raise(rb_eArgError, "argument too long (size=%d)", RSTRING(fname)->len); - return Qnil; /* not reached */ + if (tainted) OBJ_TAINT(result); + RSTRING(result)->len = p - buf; + return result; } static int @@ -2297,6 +2307,7 @@ path_check_1(path) for (;;) { if (stat(p0, &st) == 0 && (st.st_mode & 002)) { if (p) *p = '/'; + rb_warn("Bad mode 0%o on %s", st.st_mode, p0); return 0; } s = strrdirsep(p0); diff --git a/lib/debug.rb b/lib/debug.rb index 6c4d80e5a7..b9703ed7de 100644 --- a/lib/debug.rb +++ b/lib/debug.rb @@ -450,7 +450,7 @@ class DEBUGGER__ stdout.print "At toplevel\n" end binding, binding_file, binding_line = @frames[frame_pos] - stdout.printf "#%d %s:%s\n", frame_pos, binding_file, binding_line + stdout.printf "#%d %s:%s\n", frame_pos+1, binding_file, binding_line when /^\s*down(?:\s+(\d+))?$/ previous_line = nil @@ -465,7 +465,7 @@ class DEBUGGER__ stdout.print "At stack bottom\n" end binding, binding_file, binding_line = @frames[frame_pos] - stdout.printf "#%d %s:%s\n", frame_pos, binding_file, binding_line + stdout.printf "#%d %s:%s\n", frame_pos+1, binding_file, binding_line when /^\s*fin(?:ish)?$/ if frame_pos == @frames.size diff --git a/object.c b/object.c index 35517e963a..240a51c3f9 100644 --- a/object.c +++ b/object.c @@ -75,9 +75,6 @@ VALUE rb_class_real(cl) VALUE cl; { - if (TYPE(cl) == T_ICLASS) { - cl = RBASIC(cl)->klass; - } while (FL_TEST(cl, FL_SINGLETON) || TYPE(cl) == T_ICLASS) { cl = RCLASS(cl)->super; } diff --git a/variable.c b/variable.c index b44ea009ed..1c7a2601e0 100644 --- a/variable.c +++ b/variable.c @@ -145,6 +145,10 @@ classname(klass) VALUE path = Qnil; ID classpath = rb_intern("__classpath__"); + if (TYPE(klass) == T_ICLASS) { + klass = RBASIC(klass)->klass; + } + klass = rb_class_real(klass); if (!klass) klass = rb_cObject; if (ROBJECT(klass)->iv_tbl && !st_lookup(ROBJECT(klass)->iv_tbl, classpath, &path)) { @@ -172,7 +176,7 @@ VALUE rb_mod_name(mod) VALUE mod; { - VALUE path = classname(rb_class_real(mod)); + VALUE path = classname(mod); if (path) return rb_str_dup(path); return rb_str_new(0,0); @@ -182,7 +186,7 @@ VALUE rb_class_path(klass) VALUE klass; { - VALUE path = classname(rb_class_real(klass)); + VALUE path = classname(klass); if (path) return path; else { -- cgit v1.2.3