diff --git a/ChangeLog b/ChangeLog index 68db002dd4..ea0421fe62 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,18 @@ Fri Dec 21 16:18:17 2001 Nobuyoshi Nakada * dln.h, ruby.h, util.h: enable prototypes in C++. +Fri Dec 21 15:12:41 2001 Yukihiro Matsumoto + + * time.c (time_plus): result should not be negative unless + NEGATIVE_TIME_T is defined. + + * time.c (time_new_internal): should check tv_sec overflow too. + + * time.c (time_timeval): should check time_t range when time is + initialized from float. + + * time.c (time_plus): uses modf(3). + Fri Dec 21 03:15:52 2001 Nobuyoshi Nakada * eval.c (rb_mod_define_method): must not convert Method to Proc. @@ -18,6 +30,18 @@ Thu Dec 20 14:08:20 2001 Minero Aoki * lib/net/protocol.rb: rename Net::Socket to Net::BufferedSocket +Thu Dec 20 13:51:52 2001 K.Kosako + + * variable.c (rb_cvar_set): add frozen class/module check. + + * variable.c (rb_cvar_declare): add frozen class/module check. + +Thu Dec 20 01:01:50 2001 takuma ozawa + + * re.c (match_to_a): should propagate taint. + + * re.c (rb_reg_s_quote): ditto. + Wed Dec 19 16:58:29 2001 Shugo Maeda * ext/readline/readline.c: new methods diff --git a/doc/NEWS b/doc/NEWS index 1a5634d64b..26dff87e3d 100644 --- a/doc/NEWS +++ b/doc/NEWS @@ -1,3 +1,11 @@ +: TCPServer#listen, UNIXServer#listen + + Added. + +: String#match + + Added. + : Syslog module Imported. diff --git a/io.c b/io.c index 4c16918938..b99580f0a3 100644 --- a/io.c +++ b/io.c @@ -522,7 +522,7 @@ io_fread(ptr, len, f) #endif return len - n; } - rb_sys_fail(0); + return 0; } *ptr = '\0'; break; diff --git a/lib/tracer.rb b/lib/tracer.rb index dbe18eacc2..817f68484e 100644 --- a/lib/tracer.rb +++ b/lib/tracer.rb @@ -87,16 +87,16 @@ class Tracer return p.call line end - unless list = LINES__[file] + unless list = SCRIPT_LINES__[file] begin f = open(file) begin - LINES__[file] = list = f.readlines + SCRIPT_LINES__[file] = list = f.readlines ensure f.close end rescue - LINES__[file] = list = [] + SCRIPT_LINES__[file] = list = [] end end if l = list[line - 1] diff --git a/misc/ruby-mode.el b/misc/ruby-mode.el index 437999dfdc..09df43dff0 100644 --- a/misc/ruby-mode.el +++ b/misc/ruby-mode.el @@ -522,9 +522,10 @@ The variable ruby-indent-level controls the amount of indentation. (re-search-backward "#" (save-excursion (beginning-of-line) (point)) t) - (save-excursion - (forward-char -1) - (not (looking-at "\\?"))) + (if (not (= (point) (point-min))) + (save-excursion + (forward-char -1) + (not (looking-at "\\?")))) (skip-chars-backward " \t") (if (save-excursion (forward-char -1) diff --git a/re.c b/re.c index 176c3bc8ec..d6f860b86f 100644 --- a/re.c +++ b/re.c @@ -781,11 +781,16 @@ match_to_a(match) VALUE ary = rb_ary_new2(regs->num_regs); char *ptr = RSTRING(RMATCH(match)->str)->ptr; int i; - + int taint = OBJ_TAINTED(match); + for (i=0; inum_regs; i++) { - if (regs->beg[i] == -1) rb_ary_push(ary, Qnil); - else rb_ary_push(ary, rb_str_new(ptr+regs->beg[i], - regs->end[i]-regs->beg[i])); + if (regs->beg[i] == -1) { + rb_ary_push(ary, Qnil); + } else { + VALUE str = rb_str_new(ptr+regs->beg[i], regs->end[i]-regs->beg[i]); + if (taint) OBJ_TAINT(str); + rb_ary_push(ary, str); + } } return ary; } @@ -1122,7 +1127,7 @@ rb_reg_s_quote(argc, argv) } kcode_reset_option(); rb_str_resize(tmp, t - RSTRING(tmp)->ptr); - + OBJ_INFECT(tmp, str); return tmp; } diff --git a/time.c b/time.c index 19ee8c1656..36db68fa88 100644 --- a/time.c +++ b/time.c @@ -29,6 +29,7 @@ struct timeval { #ifdef HAVE_UNISTD_H #include #endif +#include VALUE rb_cTime; @@ -69,15 +70,24 @@ time_new_internal(klass, sec, usec) time_t sec, usec; { VALUE obj; + time_t tmp; struct time_object *tobj; if (usec >= 1000000) { /* usec positive overflow */ - sec += usec / 1000000; + tmp = sec + usec / 1000000; usec %= 1000000; + if (sec > 0 && tmp < 0) { + rb_raise(rb_eRangeError, "out of Time range"); + } + sec = tmp; } if (usec < 0) { /* usec negative overflow */ - sec += NDIV(usec,1000000); /* negative div */ - usec = NMOD(usec,1000000); /* negative mod */ + tmp = sec + NDIV(usec,1000000); /* negative div */ + usec = NMOD(usec,1000000); /* negative mod */ + if (sec < 0 && tmp > 0) { + rb_raise(rb_eRangeError, "out of Time range"); + } + sec = tmp; } #ifndef NEGATIVE_TIME_T if (sec < 0 || (sec == 0 && usec < 0)) @@ -122,8 +132,16 @@ time_timeval(time, interval) case T_FLOAT: if (interval && RFLOAT(time)->value < 0.0) rb_raise(rb_eArgError, "%s must be positive", tstr); - t.tv_sec = (time_t)RFLOAT(time)->value; - t.tv_usec = (time_t)((RFLOAT(time)->value - (double)t.tv_sec)*1e6); + else { + double f, d; + + d = modf(RFLOAT(time)->value, &f); + t.tv_sec = (time_t)f; + if (f != t.tv_sec) { + rb_raise(rb_eRangeError, "%f out of Time range", RFLOAT(time)->value); + } + t.tv_usec = (time_t)d*1e6; + } break; case T_BIGNUM: @@ -925,26 +943,30 @@ time_plus(time1, time2) { struct time_object *tobj; time_t sec, usec; - double f, d; + double f, d, v; GetTimeval(time1, tobj); if (rb_obj_is_kind_of(time2, rb_cTime)) { rb_raise(rb_eTypeError, "time + time?"); } - f = NUM2DBL(time2); - sec = (time_t)f; - d = f - (double)sec; - if (d >= 1.0 || d <= -1.0) { - rb_raise(rb_eRangeError, "time + %f out of Time range", f); + v = NUM2DBL(time2); + d = modf(v, &f); + if (f != (double)sec || d >= 1.0 || d <= -1.0) { + rb_raise(rb_eRangeError, "time + %f out of Time range", v); } - usec = tobj->tv.tv_usec + (time_t)(d*1e6); - sec = tobj->tv.tv_sec + sec; +#ifndef NEGATIVE_TIME_T + if (f < 0 && -f >= tobj->tv.tv_sec) { + rb_raise(rb_eArgError, "time must be positive"); + } +#endif + usec = tobj->tv.tv_usec + (time_t)d*1e6; + sec = tobj->tv.tv_sec + (time_t)f; #ifdef NEGATIVE_TIME_T if ((tobj->tv.tv_sec >= 0 && f >= 0 && sec < 0) || (tobj->tv.tv_sec <= 0 && f <= 0 && sec > 0)) { - rb_raise(rb_eRangeError, "time + %f out of Time range", f); + rb_raise(rb_eRangeError, "time + %f out of Time range", v); } #endif time2 = rb_time_new(sec, usec); @@ -961,7 +983,7 @@ time_minus(time1, time2) { struct time_object *tobj; time_t sec, usec; - double f, d; + double f, d, v; GetTimeval(time1, tobj); if (rb_obj_is_kind_of(time2, rb_cTime)) { @@ -970,21 +992,26 @@ time_minus(time1, time2) GetTimeval(time2, tobj2); f = (double)tobj->tv.tv_sec - (double)tobj2->tv.tv_sec; f += ((double)tobj->tv.tv_usec - (double)tobj2->tv.tv_usec)*1e-6; + /* XXX: should check float overflow on 64bit time_t platforms */ return rb_float_new(f); } - f = NUM2DBL(time2); - sec = (time_t)f; - d = f - (double)sec; - if (d >= 1.0 || d <= -1.0) { - rb_raise(rb_eRangeError, "time - %f out of Time range", f); + v = NUM2DBL(time2); + d = modf(v, &f); + if (f != (double)sec || d >= 1.0 || d <= -1.0) { + rb_raise(rb_eRangeError, "time - %f out of Time range", v); } +#ifndef NEGATIVE_TIME_T + if (f > 0 && f >= tobj->tv.tv_sec) { + rb_raise(rb_eArgError, "time must be positive"); + } +#endif usec = tobj->tv.tv_usec - (time_t)(d*1e6); - sec = tobj->tv.tv_sec - sec; + sec = tobj->tv.tv_sec - (time_t)f; #ifdef NEGATIVE_TIME_T if ((tobj->tv.tv_sec <= 0 && f >= 0 && sec > 0) || (tobj->tv.tv_sec >= 0 && f <= 0 && sec < 0)) { - rb_raise(rb_eRangeError, "time - %f out of Time range", f); + rb_raise(rb_eRangeError, "time - %f out of Time range", v); } #endif diff --git a/variable.c b/variable.c index ce8180f02f..8b9dfaa1d5 100644 --- a/variable.c +++ b/variable.c @@ -1459,16 +1459,15 @@ rb_cvar_set(klass, id, val) tmp = klass; while (tmp) { - if (RCLASS(tmp)->iv_tbl) { - if (st_lookup(RCLASS(tmp)->iv_tbl,id,0)) { - if (!OBJ_TAINTED(tmp) && rb_safe_level() >= 4) - rb_raise(rb_eSecurityError, "Insecure: can't modify class variable"); - st_insert(RCLASS(tmp)->iv_tbl,id,val); - if (ruby_verbose) { - cvar_override_check(id, tmp); - } - return; + if (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,0)) { + if (OBJ_FROZEN(tmp)) rb_error_frozen("class/module"); + if (!OBJ_TAINTED(tmp) && rb_safe_level() >= 4) + rb_raise(rb_eSecurityError, "Insecure: can't modify class variable"); + st_insert(RCLASS(tmp)->iv_tbl,id,val); + if (ruby_verbose) { + cvar_override_check(id, tmp); } + return; } tmp = RCLASS(tmp)->super; } @@ -1488,6 +1487,7 @@ rb_cvar_declare(klass, id, val) tmp = klass; while (tmp) { if (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,0)) { + if (OBJ_FROZEN(tmp)) rb_error_frozen("class/module"); if (!OBJ_TAINTED(tmp) && rb_safe_level() >= 4) rb_raise(rb_eSecurityError, "Insecure: can't modify class variable"); if (ruby_verbose && klass != tmp) {