From 80a71ef0c37cb9852382d4662f470d833c57bcf4 Mon Sep 17 00:00:00 2001 From: matz Date: Tue, 18 Dec 2001 08:47:06 +0000 Subject: [PATCH] * string.c (rb_str_replace): swap arguments of OBJ_INFECT. * eval.c (rb_thread_schedule): should not select a thread which is not yet initialized. * time.c (time_plus): wrong boundary check. * time.c (time_minus): ditto. git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@1918 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 34 ++++++++++++++++++ ToDo | 1 + class.c | 16 +++++++-- eval.c | 2 +- ext/Win32API/Win32API.c | 12 +++---- ext/etc/etc.c | 4 +-- ext/socket/socket.c | 29 ++++++++------- ext/syslog/syslog.c | 2 +- file.c | 2 +- misc/ruby-mode.el | 8 ++--- string.c | 79 ++++++++++++++++++++++------------------- time.c | 16 +++++---- variable.c | 3 ++ version.h | 4 +-- 14 files changed, 135 insertions(+), 77 deletions(-) diff --git a/ChangeLog b/ChangeLog index 304913172..8b3ac1bd5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Mon Dec 17 18:53:49 2001 K.Kosako + + * string.c (rb_str_replace): swap arguments of OBJ_INFECT. + +Tue Dec 18 01:02:13 2001 Yukihiro Matsumoto + + * eval.c (rb_thread_schedule): should not select a thread which is + not yet initialized. + Mon Dec 17 16:52:20 2001 Nobuyoshi Nakada * intern.h: add prototypes. @@ -22,6 +31,12 @@ Mon Dec 17 16:52:20 2001 Nobuyoshi Nakada * ruby.c (require_libraries): ditto. +Mon Dec 17 15:41:24 2001 Yukihiro Matsumoto + + * time.c (time_plus): wrong boundary check. + + * time.c (time_minus): ditto. + Mon Dec 17 15:19:32 2001 Tanaka Akira * time.c: new method `gmtoff', `gmt_offset' and `utc_offset'. @@ -49,8 +64,16 @@ Mon Dec 17 15:19:32 2001 Tanaka Akira * missing/strftime.c: fix overflow by tm_year + 1900. +Mon Dec 17 00:02:04 2001 Guy Decoux + +<<<<<<< ChangeLog + * variable.c (find_class_path): should initialize iv_tbl if it's + NULL. + +======= * lib/time.rb: use Time#utc_offset. +>>>>>>> 1.655 Fri Dec 14 04:23:36 2001 Minero Aoki * lib/net/pop.rb: new method Net::POP3.APOP @@ -66,6 +89,17 @@ Fri Dec 14 04:23:36 2001 Minero Aoki * lib/net/http.rb: ditto. +Fri Dec 14 00:16:06 2001 Yukihiro Matsumoto + + * class.c (rb_define_class): should return the existing class if + the class is already defined and its superclass is ideintical to + the specified superclass. + + * class.c (rb_define_class_under): ditto. + + * class.c (rb_define_module): should return the existing module if + the module is already defined. + Thu Dec 13 09:52:59 2001 Yukihiro Matsumoto * time.c (time_new_internal): avoid loop to calculate negative diff --git a/ToDo b/ToDo index 0f9b3f1b0..2a66723a8 100644 --- a/ToDo +++ b/ToDo @@ -98,6 +98,7 @@ Standard Libraries * remove dependency on MAXPATHLEN. * pointer share mechanism similar to one in String for Array. * deprecate Array#indexes, and Array#indices. +* require "1.6" etc. by /usr/lib/ruby/1.6/1.6.rb ;-) Extension Libraries diff --git a/class.c b/class.c index 48577a79e..edfc9dd09 100644 --- a/class.c +++ b/class.c @@ -170,7 +170,13 @@ rb_define_class(name, super) id = rb_intern(name); if (rb_const_defined(rb_cObject, id)) { klass = rb_const_get(rb_cObject, id); - rb_name_error(id, "%s is already defined", name); + if (TYPE(klass) != T_CLASS) { + rb_raise(rb_eTypeError, "%s is not a class", name); + } + if (rb_class_real(RCLASS(klass)->super) != super) { + rb_name_error(id, "%s is already defined", name); + } + return klass; } klass = rb_define_class_id(id, super); st_add_direct(rb_class_tbl, id, klass); @@ -190,7 +196,13 @@ rb_define_class_under(outer, name, super) id = rb_intern(name); if (rb_const_defined_at(outer, id)) { klass = rb_const_get(outer, id); - rb_name_error(id, "%s is already defined", name); + if (TYPE(klass) != T_CLASS) { + rb_raise(rb_eTypeError, "%s is not a class", name); + } + if (rb_class_real(RCLASS(klass)->super) != super) { + rb_name_error(id, "%s is already defined", name); + } + return klass; } klass = rb_define_class_id(id, super); rb_const_set(outer, id, klass); diff --git a/eval.c b/eval.c index d7073c733..e1b33c2f1 100644 --- a/eval.c +++ b/eval.c @@ -7732,7 +7732,7 @@ rb_thread_schedule() next = th; break; } - if (th->status == THREAD_RUNNABLE) { + if (th->status == THREAD_RUNNABLE && th->stk_ptr) { if (!next || next->priority < th->priority) next = th; } diff --git a/ext/Win32API/Win32API.c b/ext/Win32API/Win32API.c index 0ee28f05a..65b6a558c 100644 --- a/ext/Win32API/Win32API.c +++ b/ext/Win32API/Win32API.c @@ -64,8 +64,8 @@ Win32API_initialize(self, dllname, proc, import, export) int len; int ex; - Check_SafeStr(dllname); - Check_SafeStr(proc); + SafeStringValue(dllname); + SafeStringValue(proc); hdll = LoadLibrary(RSTRING(dllname)->ptr); if (!hdll) rb_raise(rb_eRuntimeError, "LoadLibrary: %s\n", RSTRING(dllname)->ptr); @@ -90,7 +90,7 @@ Win32API_initialize(self, dllname, proc, import, export) case T_ARRAY: ptr = RARRAY(import)->ptr; for (i = 0, len = RARRAY(import)->len; i < len; i++) { - Check_SafeStr(ptr[i]); + SafeStringValue(ptr[i]); switch (*(char *)RSTRING(ptr[i])->ptr) { case 'N': case 'n': case 'L': case 'l': rb_ary_push(a_import, INT2FIX(_T_NUMBER)); @@ -105,7 +105,7 @@ Win32API_initialize(self, dllname, proc, import, export) } break; default: - Check_SafeStr(import); + SafeStringValue(import); s = RSTRING(import)->ptr; for (i = 0, len = RSTRING(import)->len; i < len; i++) { switch (*s++) { @@ -127,7 +127,7 @@ Win32API_initialize(self, dllname, proc, import, export) if (NIL_P(export)) { ex = _T_VOID; } else { - Check_SafeStr(export); + SafeStringValue(export); switch (*RSTRING(export)->ptr) { case 'V': case 'v': ex = _T_VOID; @@ -228,7 +228,7 @@ Win32API_Call(argc, argv, obj) } else if (FIXNUM_P(str)){ pParam = (char *)NUM2ULONG(str); } else { - Check_Type(str, T_STRING); + StringValue(str); rb_str_modify(str); pParam = RSTRING(str)->ptr; } diff --git a/ext/etc/etc.c b/ext/etc/etc.c index ee0cd529e..5c54237b7 100644 --- a/ext/etc/etc.c +++ b/ext/etc/etc.c @@ -117,7 +117,7 @@ etc_getpwnam(obj, nam) #ifdef HAVE_GETPWENT struct passwd *pwd; - Check_Type(nam, T_STRING); + StringValue(nam); pwd = getpwnam(RSTRING(nam)->ptr); if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %s", RSTRING(nam)->ptr); return setup_passwd(pwd); @@ -194,7 +194,7 @@ etc_getgrnam(obj, nam) #ifdef HAVE_GETGRENT struct group *grp; - Check_Type(nam, T_STRING); + StringValue(nam); grp = getgrnam(RSTRING(nam)->ptr); if (grp == 0) rb_raise(rb_eArgError, "can't find group for %s", RSTRING(nam)->ptr); return setup_group(grp); diff --git a/ext/socket/socket.c b/ext/socket/socket.c index e1f84376a..48058a32f 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -561,7 +561,7 @@ ip_addrsetup(host, port) else { char *name; - Check_SafeStr(host); + SafeStringValue(host); name = RSTRING(host)->ptr; if (*name == 0) { mkinetaddr(INADDR_ANY, hbuf, sizeof(hbuf)); @@ -793,7 +793,7 @@ load_addr_info(h, serv, type, res) int error; if (!NIL_P(h)) { - Check_SafeStr(h); + SafeStringValue(h); host = RSTRING(h)->ptr; } else { @@ -804,7 +804,7 @@ load_addr_info(h, serv, type, res) portp = pbuf; } else { - Check_SafeStr(serv); + SafeStringValue(serv); if (RSTRING(serv)->len >= sizeof(pbuf)) rb_raise(rb_eArgError, "servicename too long (%d)", RSTRING(serv)->len); strcpy(pbuf, RSTRING(serv)->ptr); @@ -918,10 +918,9 @@ tcp_s_open(argc, argv, class) &remote_host, &remote_serv, &local_host, &local_serv); - Check_SafeStr(remote_host); - + SafeStringValue(remote_host); if (!NIL_P(local_host)) { - Check_SafeStr(local_host); + SafeStringValue(local_host); } return open_inet(class, remote_host, remote_serv, @@ -940,7 +939,7 @@ socks_s_open(class, host, serv) init = 1; } - Check_SafeStr(host); + SafeStringValue(host); return open_inet(class, host, serv, Qnil, Qnil, INET_SOCKS); } @@ -1150,7 +1149,7 @@ tcp_accept(sock) static VALUE open_unix(class, path, server) VALUE class; - struct RString *path; + VALUE path; int server; { struct sockaddr_un sockaddr; @@ -1158,7 +1157,7 @@ open_unix(class, path, server) VALUE sock; OpenFile *fptr; - Check_SafeStr(path); + SafeStringValue(path); fd = ruby_socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) { rb_sys_fail("socket(2)"); @@ -1166,7 +1165,7 @@ open_unix(class, path, server) MEMZERO(&sockaddr, struct sockaddr_un, 1); sockaddr.sun_family = AF_UNIX; - strncpy(sockaddr.sun_path, path->ptr, sizeof(sockaddr.sun_path)-1); + strncpy(sockaddr.sun_path, RSTRING(path)->ptr, sizeof(sockaddr.sun_path)-1); sockaddr.sun_path[sizeof(sockaddr.sun_path)-1] = '\0'; if (server) { @@ -1189,7 +1188,7 @@ open_unix(class, path, server) sock = sock_new(class, fd); GetOpenFile(sock, fptr); - fptr->path = strdup(path->ptr); + fptr->path = strdup(RSTRING(path)->ptr); return sock; } @@ -1466,7 +1465,7 @@ setup_domain_and_type(domain, dv, type, tv) char *ptr; if (TYPE(domain) == T_STRING) { - Check_SafeStr(domain); + SafeStringValue(domain); ptr = RSTRING(domain)->ptr; if (strcmp(ptr, "AF_INET") == 0) *dv = AF_INET; @@ -1515,7 +1514,7 @@ setup_domain_and_type(domain, dv, type, tv) *dv = NUM2INT(domain); } if (TYPE(type) == T_STRING) { - Check_SafeStr(type); + SafeStringValue(type); ptr = RSTRING(type)->ptr; if (strcmp(ptr, "SOCK_STREAM") == 0) *tv = SOCK_STREAM; @@ -1597,7 +1596,7 @@ sock_connect(sock, addr) OpenFile *fptr; int fd; - Check_Type(addr, T_STRING); + StringValue(addr); rb_str_modify(addr); GetOpenFile(sock, fptr); @@ -1615,7 +1614,7 @@ sock_bind(sock, addr) { OpenFile *fptr; - Check_Type(addr, T_STRING); + StringValue(addr); rb_str_modify(addr); GetOpenFile(sock, fptr); diff --git a/ext/syslog/syslog.c b/ext/syslog/syslog.c index 5bd577caa..43392a3ce 100644 --- a/ext/syslog/syslog.c +++ b/ext/syslog/syslog.c @@ -62,7 +62,7 @@ static VALUE cSyslog_open(int argc, VALUE *argv, VALUE self) fac = INT2NUM(LOG_USER); } - Check_SafeStr(ident); + SafeStringValue(ident); syslog_ident = ident; syslog_options = opt; syslog_facility = fac; diff --git a/file.c b/file.c index 17bbdb158..424e753a3 100644 --- a/file.c +++ b/file.c @@ -1908,7 +1908,7 @@ rb_stat_init(obj, fname) { struct stat st, *nst; - Check_SafeStr(fname); + SafeStringValue(fname); if (stat(RSTRING(fname)->ptr, &st) == -1) { rb_sys_fail(RSTRING(fname)->ptr); diff --git a/misc/ruby-mode.el b/misc/ruby-mode.el index efd61254f..437999dfd 100644 --- a/misc/ruby-mode.el +++ b/misc/ruby-mode.el @@ -680,22 +680,22 @@ An end of a defun is found by moving forward from the beginning of one." ("\\(#\\)[{$@]" 1 (1 . nil)) ;; the last $' in the string ,'...$' is not variable ;; the last ?' in the string ,'...?' is not ascii code - ("\\(^\\|[[\\s <+(,=]\\)\\('\\)[^'\n\\\\]*\\(\\\\.[^'\n\\\\]*\\)*[\\?\\$]\\('\\)" + ("\\(^\\|[[\\s <+(,=]\\)\\('\\)[^'\n\\\\]*\\(\\\\.[^'\n\\\\]*\\)*[?$]\\('\\)" (2 (7 . nil)) (4 (7 . nil))) ;; the last $` in the string ,`...$` is not variable ;; the last ?` in the string ,`...?` is not ascii code - ("\\(^\\|[[\\s <+(,=]\\)\\(`\\)[^`\n\\\\]*\\(\\\\.[^`\n\\\\]*\\)*[\\?\\$]\\(`\\)" + ("\\(^\\|[[\\s <+(,=]\\)\\(`\\)[^`\n\\\\]*\\(\\\\.[^`\n\\\\]*\\)*[?$]\\(`\\)" (2 (7 . nil)) (4 (7 . nil))) ;; the last $" in the string ,"...$" is not variable ;; the last ?" in the string ,"...?" is not ascii code - ("\\(^\\|[[\\s <+(,=]\\)\\(\"\\)[^\"\n\\\\]*\\(\\\\.[^\"\n\\\\]*\\)*[\\?\\$]\\(\"\\)" + ("\\(^\\|[[\\s <+(,=]\\)\\(\"\\)[^\"\n\\\\]*\\(\\\\.[^\"\n\\\\]*\\)*[?$]\\(\"\\)" (2 (7 . nil)) (4 (7 . nil))) ;; $' $" $` .... are variables ;; ?' ?" ?` are ascii codes - ("[\\?\\$][#\"'`]" 0 (1 . nil)) + ("[?$][#\"'`]" 0 (1 . nil)) ;; regexps ("\\(^\\|[=(,~?:;]\\|\\(^\\|\\s \\)\\(if\\|elsif\\|unless\\|while\\|until\\|when\\|and\\|or\\|&&\\|||\\)\\|g?sub!?\\|scan\\|split!?\\)\\s *\\(/\\)[^/\n\\\\]*\\(\\\\.[^/\n\\\\]*\\)*\\(/\\)" (4 (7 . ?/)) diff --git a/string.c b/string.c index 640cf7f6d..59f977629 100644 --- a/string.c +++ b/string.c @@ -195,13 +195,6 @@ rb_str_to_str(str) return rb_convert_type(str, T_STRING, "String", "to_str"); } -VALUE -rb_string_value(ptr) - volatile VALUE *ptr; -{ - return *ptr = rb_str_to_str(*ptr); -} - static void rb_str_become(str, str2) VALUE str, str2; @@ -428,6 +421,48 @@ rb_str_format(str, arg) return rb_f_sprintf(2, argv); } +static int +str_independent(str) + VALUE str; +{ + if (OBJ_FROZEN(str)) rb_error_frozen("string"); + if (!OBJ_TAINTED(str) && rb_safe_level() >= 4) + rb_raise(rb_eSecurityError, "Insecure: can't modify string"); + if (!FL_TEST(str, ELTS_SHARED)) return 1; + return 0; +} + +static void +str_make_independent(str) + VALUE str; +{ + char *ptr; + + ptr = ALLOC_N(char, RSTRING(str)->len+1); + if (RSTRING(str)->ptr) { + memcpy(ptr, RSTRING(str)->ptr, RSTRING(str)->len); + } + ptr[RSTRING(str)->len] = 0; + RSTRING(str)->ptr = ptr; + RSTRING(str)->aux.capa = RSTRING(str)->len; + FL_UNSET(str, ELTS_SHARED|STR_ASSOC); +} + +void +rb_str_modify(str) + VALUE str; +{ + if (str_independent(str)) return; + str_make_independent(str); +} + +VALUE +rb_string_value(ptr) + volatile VALUE *ptr; +{ + return *ptr = rb_str_to_str(*ptr); +} + VALUE rb_str_substr(str, beg, len) VALUE str; @@ -455,34 +490,6 @@ rb_str_substr(str, beg, len) return str2; } -static int -str_independent(str) - VALUE str; -{ - if (OBJ_FROZEN(str)) rb_error_frozen("string"); - if (!OBJ_TAINTED(str) && rb_safe_level() >= 4) - rb_raise(rb_eSecurityError, "Insecure: can't modify string"); - if (!FL_TEST(str, ELTS_SHARED)) return 1; - return 0; -} - -void -rb_str_modify(str) - VALUE str; -{ - char *ptr; - - if (str_independent(str)) return; - ptr = ALLOC_N(char, RSTRING(str)->len+1); - if (RSTRING(str)->ptr) { - memcpy(ptr, RSTRING(str)->ptr, RSTRING(str)->len); - } - ptr[RSTRING(str)->len] = 0; - RSTRING(str)->ptr = ptr; - RSTRING(str)->aux.capa = RSTRING(str)->len; - FL_UNSET(str, ELTS_SHARED|STR_ASSOC); -} - VALUE rb_str_freeze(str) VALUE str; @@ -1610,7 +1617,7 @@ rb_str_replace(str, str2) memcpy(RSTRING(str)->ptr, RSTRING(str2)->ptr, RSTRING(str2)->len); } - OBJ_INFECT(str2, str); + OBJ_INFECT(str, str2); return str; } diff --git a/time.c b/time.c index 4d8114b5c..19ee8c165 100644 --- a/time.c +++ b/time.c @@ -174,7 +174,7 @@ time_s_at(argc, argv, klass) if (rb_scan_args(argc, argv, "11", &time, &t) == 2) { tv.tv_sec = NUM2LONG(time); - tv.tv_usec = NUM2INT(t); + tv.tv_usec = NUM2LONG(t); } else { tv = rb_time_timeval(time); @@ -925,7 +925,7 @@ time_plus(time1, time2) { struct time_object *tobj; time_t sec, usec; - double f; + double f, d; GetTimeval(time1, tobj); @@ -934,10 +934,11 @@ time_plus(time1, time2) } f = NUM2DBL(time2); sec = (time_t)f; - if (f != (double)sec) { + d = f - (double)sec; + if (d >= 1.0 || d <= -1.0) { rb_raise(rb_eRangeError, "time + %f out of Time range", f); } - usec = tobj->tv.tv_usec + (time_t)((f - (double)sec)*1e6); + usec = tobj->tv.tv_usec + (time_t)(d*1e6); sec = tobj->tv.tv_sec + sec; #ifdef NEGATIVE_TIME_T @@ -960,7 +961,7 @@ time_minus(time1, time2) { struct time_object *tobj; time_t sec, usec; - double f; + double f, d; GetTimeval(time1, tobj); if (rb_obj_is_kind_of(time2, rb_cTime)) { @@ -974,10 +975,11 @@ time_minus(time1, time2) } f = NUM2DBL(time2); sec = (time_t)f; - if (f != (double)sec) { + d = f - (double)sec; + if (d >= 1.0 || d <= -1.0) { rb_raise(rb_eRangeError, "time - %f out of Time range", f); } - usec = tobj->tv.tv_usec - (time_t)((f - (double)sec)*1e6); + usec = tobj->tv.tv_usec - (time_t)(d*1e6); sec = tobj->tv.tv_sec - sec; #ifdef NEGATIVE_TIME_T if ((tobj->tv.tv_sec <= 0 && f >= 0 && sec > 0) || diff --git a/variable.c b/variable.c index 7c010a378..ce8180f02 100644 --- a/variable.c +++ b/variable.c @@ -129,6 +129,9 @@ find_class_path(klass) st_foreach(rb_class_tbl, fc_i, &arg); } if (arg.path) { + if (!ROBJECT(klass)->iv_tbl) { + ROBJECT(klass)->iv_tbl = st_init_numtable(); + } st_insert(ROBJECT(klass)->iv_tbl,rb_intern("__classpath__"),arg.path); return arg.path; } diff --git a/version.h b/version.h index 70e97d9db..cee36c01a 100644 --- a/version.h +++ b/version.h @@ -1,4 +1,4 @@ #define RUBY_VERSION "1.7.2" -#define RUBY_RELEASE_DATE "2001-12-17" +#define RUBY_RELEASE_DATE "2001-12-18" #define RUBY_VERSION_CODE 172 -#define RUBY_RELEASE_CODE 20011217 +#define RUBY_RELEASE_CODE 20011218