1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* 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
This commit is contained in:
matz 2002-02-04 08:09:14 +00:00
parent c2269d5b4f
commit 43f68272c7
6 changed files with 52 additions and 33 deletions

View file

@ -1,3 +1,9 @@
Mon Feb 4 15:38:29 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
* 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 <nobu.nakada@nifty.ne.jp> Fri Feb 1 19:10:04 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* intern.h: prototypes for new functions; rb_cstr_to_inum(), * intern.h: prototypes for new functions; rb_cstr_to_inum(),

5
eval.c
View file

@ -1803,7 +1803,7 @@ is_defined(self, node, buf)
case NODE_VCALL: case NODE_VCALL:
case NODE_FCALL: case NODE_FCALL:
val = CLASS_OF(self); val = self;
goto check_bound; goto check_bound;
case NODE_CALL: case NODE_CALL:
@ -1811,7 +1811,6 @@ is_defined(self, node, buf)
PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) { if ((state = EXEC_TAG()) == 0) {
val = rb_eval(self, node->nd_recv); val = rb_eval(self, node->nd_recv);
val = CLASS_OF(val);
} }
POP_TAG(); POP_TAG();
if (state) { if (state) {
@ -1821,6 +1820,8 @@ is_defined(self, node, buf)
check_bound: check_bound:
{ {
int call = nd_type(node)== NODE_CALL; int call = nd_type(node)== NODE_CALL;
val = CLASS_OF(val);
if (call) { if (call) {
int noex; int noex;
ID id = node->nd_mid; ID id = node->nd_mid;

59
file.c
View file

@ -1377,22 +1377,33 @@ strrdirsep(path)
return last; 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 VALUE
rb_file_s_expand_path(argc, argv) rb_file_s_expand_path(argc, argv)
int argc; int argc;
VALUE *argv; VALUE *argv;
{ {
VALUE fname, dname; VALUE fname, dname, result;
char *s, *p, *b; char *s, *buf, *b, *p, *pend;
char buf[MAXPATHLEN+2]; long buflen = MAXPATHLEN;
char *bend = buf + sizeof(buf) - 2;
int tainted; int tainted;
rb_scan_args(argc, argv, "11", &fname, &dname); rb_scan_args(argc, argv, "11", &fname, &dname);
result = rb_str_new(0, buflen + 2);
tainted = OBJ_TAINTED(fname);
s = StringValuePtr(fname); s = StringValuePtr(fname);
p = buf; p = buf = RSTRING(result)->ptr;
pend = p + buflen;
tainted = OBJ_TAINTED(fname);
if (s[0] == '~') { if (s[0] == '~') {
if (isdirsep(s[1]) || s[1] == '\0') { if (isdirsep(s[1]) || s[1] == '\0') {
char *dir = getenv("HOME"); char *dir = getenv("HOME");
@ -1400,9 +1411,9 @@ rb_file_s_expand_path(argc, argv)
if (!dir) { if (!dir) {
rb_raise(rb_eArgError, "couldn't find HOME environment -- expanding `%s'", s); 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); strcpy(buf, dir);
p = &buf[strlen(buf)]; p = buf + strlen(dir);
s++; s++;
tainted = 1; tainted = 1;
} }
@ -1415,7 +1426,7 @@ rb_file_s_expand_path(argc, argv)
while (*s && !isdirsep(*s)) { while (*s && !isdirsep(*s)) {
s = CharNext(s); s = CharNext(s);
} }
if (p + (s-b) >= bend) goto toolong; BUFCHECK (p + (s-b) >= pend);
memcpy(p, b, s-b); memcpy(p, b, s-b);
p += s-b; p += s-b;
*p = '\0'; *p = '\0';
@ -1425,9 +1436,9 @@ rb_file_s_expand_path(argc, argv)
endpwent(); endpwent();
rb_raise(rb_eArgError, "user %s doesn't exist", buf); 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); strcpy(buf, pwPtr->pw_dir);
p = &buf[strlen(buf)]; p = buf + strlen(pwPtr->pw_dir);
endpwent(); endpwent();
#endif #endif
} }
@ -1439,7 +1450,7 @@ rb_file_s_expand_path(argc, argv)
while (*s && !isdirsep(*s)) { while (*s && !isdirsep(*s)) {
s = CharNext(s); s = CharNext(s);
} }
if (p + (s-b) >= bend) goto toolong; BUFCHECK (p + (s-b) >= pend);
memcpy(p, b, s-b); memcpy(p, b, s-b);
p += s-b; p += s-b;
} }
@ -1448,12 +1459,15 @@ rb_file_s_expand_path(argc, argv)
if (!NIL_P(dname)) { if (!NIL_P(dname)) {
dname = rb_file_s_expand_path(1, &dname); dname = rb_file_s_expand_path(1, &dname);
if (OBJ_TAINTED(dname)) tainted = 1; 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); strcpy(buf, RSTRING(dname)->ptr);
} }
else { else {
char *dir = my_getcwd();
tainted = 1; tainted = 1;
getcwd(buf, MAXPATHLEN); BUFCHECK (strlen(dir) > buflen);
strcpy(buf, dir);
} }
p = &buf[strlen(buf)]; p = &buf[strlen(buf)];
while (p > buf && *(p - 1) == '/') p--; while (p > buf && *(p - 1) == '/') p--;
@ -1461,7 +1475,7 @@ rb_file_s_expand_path(argc, argv)
else { else {
while (*s && isdirsep(*s)) { while (*s && isdirsep(*s)) {
*p++ = '/'; *p++ = '/';
if (p >= bend) goto toolong; BUFCHECK (p >= pend);
s++; s++;
} }
if (p > buf && *s) p--; if (p > buf && *s) p--;
@ -1507,7 +1521,7 @@ rb_file_s_expand_path(argc, argv)
case '\\': case '\\':
#endif #endif
if (s > b) { if (s > b) {
if (p + (s-b+1) >= bend) goto toolong; BUFCHECK (p + (s-b+1) >= pend);
memcpy(++p, b, s-b); memcpy(++p, b, s-b);
p += s-b; p += s-b;
*p = '/'; *p = '/';
@ -1521,7 +1535,7 @@ rb_file_s_expand_path(argc, argv)
} }
if (s > b) { if (s > b) {
if (p + (s-b) >= bend) goto toolong; BUFCHECK (p + (s-b) >= pend);
memcpy(++p, b, s-b); memcpy(++p, b, s-b);
p += s-b; p += s-b;
} }
@ -1539,13 +1553,9 @@ rb_file_s_expand_path(argc, argv)
} }
#endif #endif
fname = rb_str_new(buf, p - buf); if (tainted) OBJ_TAINT(result);
if (tainted) OBJ_TAINT(fname); RSTRING(result)->len = p - buf;
return fname; return result;
toolong:
rb_raise(rb_eArgError, "argument too long (size=%d)", RSTRING(fname)->len);
return Qnil; /* not reached */
} }
static int static int
@ -2297,6 +2307,7 @@ path_check_1(path)
for (;;) { for (;;) {
if (stat(p0, &st) == 0 && (st.st_mode & 002)) { if (stat(p0, &st) == 0 && (st.st_mode & 002)) {
if (p) *p = '/'; if (p) *p = '/';
rb_warn("Bad mode 0%o on %s", st.st_mode, p0);
return 0; return 0;
} }
s = strrdirsep(p0); s = strrdirsep(p0);

View file

@ -450,7 +450,7 @@ class DEBUGGER__
stdout.print "At toplevel\n" stdout.print "At toplevel\n"
end end
binding, binding_file, binding_line = @frames[frame_pos] 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+))?$/ when /^\s*down(?:\s+(\d+))?$/
previous_line = nil previous_line = nil
@ -465,7 +465,7 @@ class DEBUGGER__
stdout.print "At stack bottom\n" stdout.print "At stack bottom\n"
end end
binding, binding_file, binding_line = @frames[frame_pos] 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)?$/ when /^\s*fin(?:ish)?$/
if frame_pos == @frames.size if frame_pos == @frames.size

View file

@ -75,9 +75,6 @@ VALUE
rb_class_real(cl) rb_class_real(cl)
VALUE cl; VALUE cl;
{ {
if (TYPE(cl) == T_ICLASS) {
cl = RBASIC(cl)->klass;
}
while (FL_TEST(cl, FL_SINGLETON) || TYPE(cl) == T_ICLASS) { while (FL_TEST(cl, FL_SINGLETON) || TYPE(cl) == T_ICLASS) {
cl = RCLASS(cl)->super; cl = RCLASS(cl)->super;
} }

View file

@ -145,6 +145,10 @@ classname(klass)
VALUE path = Qnil; VALUE path = Qnil;
ID classpath = rb_intern("__classpath__"); 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 (!klass) klass = rb_cObject;
if (ROBJECT(klass)->iv_tbl && if (ROBJECT(klass)->iv_tbl &&
!st_lookup(ROBJECT(klass)->iv_tbl, classpath, &path)) { !st_lookup(ROBJECT(klass)->iv_tbl, classpath, &path)) {
@ -172,7 +176,7 @@ VALUE
rb_mod_name(mod) rb_mod_name(mod)
VALUE mod; VALUE mod;
{ {
VALUE path = classname(rb_class_real(mod)); VALUE path = classname(mod);
if (path) return rb_str_dup(path); if (path) return rb_str_dup(path);
return rb_str_new(0,0); return rb_str_new(0,0);
@ -182,7 +186,7 @@ VALUE
rb_class_path(klass) rb_class_path(klass)
VALUE klass; VALUE klass;
{ {
VALUE path = classname(rb_class_real(klass)); VALUE path = classname(klass);
if (path) return path; if (path) return path;
else { else {