From 7422ccdd9e2fb2b28844879d5117d8fdc000c944 Mon Sep 17 00:00:00 2001 From: matz Date: Tue, 13 Nov 2001 08:19:52 +0000 Subject: * signal.c (sighandle): should not re-register sighandler if POSIX_SIGNAL is defined. * eval.c (error_print): errat array may be empty. * eval.c (rb_eval_cmd): should not upgrade safe level unless explicitly specified by argument newly added. * signal.c (sig_trap): should not allow tainted trap closure. * variable.c (rb_f_trace_var): should not allow trace_var on safe level higher than 3. * variable.c (rb_f_trace_var): should not allow tainted trace closure. * gc.c: do not use static stack until system stack overflows. * eval.c (eval): should call Exception#exception instead of calling rb_exc_new3() directly. * error.c (exc_exception): set "mesg" directly to the clone. it might be better to set mesg via some method for flexibility. * variable.c (cvar_override_check): should print original module name, if 'a' is T_ICLASS. * parse.y (yylex): float '1_.0' should not be allowed. * variable.c (var_getter): should care about var as Qfalse (ruby-bugs#PR199). * array.c (cmpint): <=> or block for {min,max} may return bignum. * array.c (sort_1): use rb_compint. * array.c (sort_2): ditto. * enum.c (min_ii): ditto. * enum.c (min_ii): ditto. * enum.c (max_i): ditto. * enum.c (max_ii): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1827 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 60 +++++++++ array.c | 18 ++- configure.in | 4 +- enum.c | 10 +- error.c | 2 +- eval.c | 18 ++- file.c | 3 +- gc.c | 417 +++++++++++++++++++++++++++-------------------------------- intern.h | 3 +- mkconfig.rb | 4 +- parse.y | 1 + signal.c | 7 +- string.c | 12 +- variable.c | 37 ++++-- 14 files changed, 327 insertions(+), 269 deletions(-) diff --git a/ChangeLog b/ChangeLog index c2977eea27..37652f567f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,11 @@ Tue Nov 13 16:49:16 2001 Usaku Nakamura * win32/win32.c (do_spawn): ditto. +Tue Nov 13 14:39:11 2001 WATANABE Tetsuya + + * signal.c (sighandle): should not re-register sighandler if + POSIX_SIGNAL is defined. + Tue Nov 13 12:55:59 2001 Usaku Nakamura * win32/win32.c (do_spawn): use CreateChild() instead of calling @@ -70,6 +75,45 @@ Tue Nov 13 12:38:12 2001 Usaku Nakamura * win32/win32.c, win32/win32.h (win32_free_environ): free environment variables list. [new] +Mon Nov 12 16:48:48 2001 Yukihiro Matsumoto + + * eval.c (error_print): errat array may be empty. + +Mon Nov 12 01:30:37 2001 Yukihiro Matsumoto + + * eval.c (rb_eval_cmd): should not upgrade safe level unless + explicitly specified by argument newly added. + + * signal.c (sig_trap): should not allow tainted trap closure. + + * variable.c (rb_f_trace_var): should not allow trace_var on safe + level higher than 3. + + * variable.c (rb_f_trace_var): should not allow tainted trace + closure. + +Sun Nov 11 00:12:23 2001 TAMURA Takashi + + * gc.c: do not use static stack until system stack overflows. + +Sat Nov 10 03:57:09 2001 Yukihiro Matsumoto + + * eval.c (eval): should call Exception#exception instead of + calling rb_exc_new3() directly. + + * error.c (exc_exception): set "mesg" directly to the clone. it + might be better to set mesg via some method for flexibility. + +Sat Nov 10 00:14:24 2001 Yukihiro Matsumoto + + * variable.c (cvar_override_check): should print original module + name, if 'a' is T_ICLASS. + + * parse.y (yylex): float '1_.0' should not be allowed. + + * variable.c (var_getter): should care about var as Qfalse + (ruby-bugs#PR199). + Fri Nov 9 13:50:06 2001 Usaku Nakamura * win32/config.status.in: make CFLAGS same as Makefile's one. @@ -82,6 +126,22 @@ Thu Nov 8 20:20:37 2001 Nobuyoshi Nakada * eval.c (rb_call0): adjust caller source file/line while evaluating optional arguments. +Thu Nov 8 18:41:58 2001 Yukihiro Matsumoto + + * array.c (cmpint): <=> or block for {min,max} may return bignum. + + * array.c (sort_1): use rb_compint. + + * array.c (sort_2): ditto. + + * enum.c (min_ii): ditto. + + * enum.c (min_ii): ditto. + + * enum.c (max_i): ditto. + + * enum.c (max_ii): ditto. + Thu Nov 8 18:21:02 2001 Yukihiro Matsumoto * file.c (path_check_1): forgot to initialize 'p'. diff --git a/array.c b/array.c index 79131901e3..0dfa3aef40 100644 --- a/array.c +++ b/array.c @@ -1004,12 +1004,26 @@ rb_ary_reverse_m(ary) return rb_ary_reverse(rb_ary_dup(ary)); } +int +rb_cmpint(cmp) + VALUE cmp; +{ + if (FIXNUM_P(cmp)) return NUM2LONG(cmp); + if (TYPE(cmp) == T_BIGNUM) { + if (RBIGNUM(cmp)->sign) return 1; + return -1; + } + if (rb_funcall(cmp, '>', 1, INT2FIX(0))) return 1; + if (rb_funcall(cmp, '<', 1, INT2FIX(0))) return -1; + return 0; +} + static int sort_1(a, b) VALUE *a, *b; { VALUE retval = rb_yield(rb_assoc_new(*a, *b)); - return NUM2INT(retval); + return rb_cmpint(retval); } static int @@ -1026,7 +1040,7 @@ sort_2(a, b) } retval = rb_funcall(*a, cmp, 1, *b); - return NUM2INT(retval); + return rb_cmpint(retval); } static VALUE diff --git a/configure.in b/configure.in index b752a81ab7..390daf410a 100644 --- a/configure.in +++ b/configure.in @@ -17,7 +17,9 @@ AC_ARG_WITH(gcc, [--without-gcc never use gcc], [ without_gcc=no;; *) CC=$withval without_gcc=$withval;; - esac], [without_gcc=no]) + esac], [ + CC=gcc + without_gcc=no]) dnl If the user switches compilers, we can't believe the cache if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC" then diff --git a/enum.c b/enum.c index dfa846c05f..af01645220 100644 --- a/enum.c +++ b/enum.c @@ -89,7 +89,7 @@ enum_find(argc, argv, obj) } rb_gc_force_recycle((VALUE)memo); if (!NIL_P(if_none)) { - rb_eval_cmd(if_none, rb_ary_new2(0)); + rb_eval_cmd(if_none, rb_ary_new2(0), 0); } return Qnil; } @@ -299,7 +299,7 @@ min_i(i, memo) memo->u1.value = i; else { cmp = rb_funcall(i, id_cmp, 1, memo->u1.value); - if (NUM2LONG(cmp) < 0) + if (rb_cmpint(cmp) < 0) memo->u1.value = i; } return Qnil; @@ -316,7 +316,7 @@ min_ii(i, memo) memo->u1.value = i; else { cmp = rb_yield(rb_assoc_new(i, memo->u1.value)); - if (NUM2LONG(cmp) < 0) + if (rb_cmpint(cmp) < 0) memo->u1.value = i; } return Qnil; @@ -344,7 +344,7 @@ max_i(i, memo) memo->u1.value = i; else { cmp = rb_funcall(i, id_cmp, 1, memo->u1.value); - if (NUM2LONG(cmp) > 0) + if (rb_cmpint(cmp) > 0) memo->u1.value = i; } return Qnil; @@ -361,7 +361,7 @@ max_ii(i, memo) memo->u1.value = i; else { cmp = rb_yield(rb_assoc_new(i, memo->u1.value)); - if (NUM2LONG(cmp) > 0) + if (rb_cmpint(cmp) > 0) memo->u1.value = i; } return Qnil; diff --git a/error.c b/error.c index 06efcb83a2..4d56f80e70 100644 --- a/error.c +++ b/error.c @@ -324,7 +324,7 @@ exc_exception(argc, argv, self) if (argc == 0) return self; if (argc == 1 && self == argv[0]) return self; exc = rb_obj_clone(self); - rb_obj_call_init(exc, argc, argv); + exc_initialize(argc, argv, exc); return exc; } diff --git a/eval.c b/eval.c index 8774d1da84..01be68249b 100644 --- a/eval.c +++ b/eval.c @@ -924,12 +924,15 @@ error_print() errat = Qnil; } POP_TAG(); - if (NIL_P(errat)) { + if (NIL_P(errat)){ if (ruby_sourcefile) fprintf(stderr, "%s:%d", ruby_sourcefile, ruby_sourceline); else fprintf(stderr, "%d", ruby_sourceline); } + else if (RARRAY(errat)->len == 0) { + error_pos(); + } else { VALUE mesg = RARRAY(errat)->ptr[0]; @@ -1342,8 +1345,9 @@ jump_tag_but_local_jump(state) } VALUE -rb_eval_cmd(cmd, arg) +rb_eval_cmd(cmd, arg, tcheck) VALUE cmd, arg; + int tcheck; { int state; VALUE val; /* OK */ @@ -1365,7 +1369,7 @@ rb_eval_cmd(cmd, arg) ruby_frame->self = ruby_top_self; ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,ruby_wrapper,0,0); - if (OBJ_TAINTED(cmd)) { + if (tcheck && OBJ_TAINTED(cmd)) { ruby_safe_level = 4; } @@ -1396,7 +1400,7 @@ rb_trap_eval(cmd, sig) PUSH_TAG(PROT_NONE); PUSH_ITER(ITER_NOT); if ((state = EXEC_TAG()) == 0) { - val = rb_eval_cmd(cmd, rb_ary_new3(1, INT2FIX(sig))); + val = rb_eval_cmd(cmd, rb_ary_new3(1, INT2FIX(sig)), 0); } POP_ITER(); POP_TAG(); @@ -1430,7 +1434,7 @@ superclass(self, node) rb_raise(rb_eTypeError, "undefined superclass `%s'", rb_id2name(node->nd_vid)); default: - rb_raise(rb_eTypeError, "superclass undefined"); + break; } JUMP_TAG(state); } @@ -4257,7 +4261,7 @@ static unsigned int STACK_LEVEL_MAX = 65535; #ifdef __human68k__ extern unsigned int _stacksize; # define STACK_LEVEL_MAX (_stacksize - 4096) -#undef HAVE_GETRLIMIT +# undef HAVE_GETRLIMIT #else #ifdef HAVE_GETRLIMIT static unsigned int STACK_LEVEL_MAX = 655300; @@ -5037,7 +5041,7 @@ eval(self, src, scope, file, line) err = rb_str_dup(ruby_errinfo); } errat = Qnil; - rb_exc_raise(rb_exc_new3(CLASS_OF(ruby_errinfo), err)); + rb_exc_raise(rb_funcall(ruby_errinfo, rb_intern("exception"), 1, err)); } rb_exc_raise(ruby_errinfo); } diff --git a/file.c b/file.c index bcce2008a5..628c3e9b8a 100644 --- a/file.c +++ b/file.c @@ -2325,8 +2325,7 @@ rb_find_file_ext(filep, ext) int i, j; if (f[0] == '~') { - fname = *filep; - fname = rb_file_s_expand_path(1, &fname); + fname = rb_file_s_expand_path(1, filep); if (rb_safe_level() >= 2 && OBJ_TAINTED(fname)) { rb_raise(rb_eSecurityError, "loading from unsafe file %s", f); } diff --git a/gc.c b/gc.c index 0f489659e5..17858f0270 100644 --- a/gc.c +++ b/gc.c @@ -345,6 +345,96 @@ rb_data_object_alloc(klass, datap, dmark, dfree) extern st_table *rb_class_tbl; VALUE *rb_gc_stack_start = 0; + +#define MARK_STACK_MAX 1024 +static VALUE mark_stack[MARK_STACK_MAX]; +static VALUE *mark_stack_ptr; +static int mark_stack_overflow; + +static void +init_mark_stack() +{ + mark_stack_overflow = 0; + mark_stack_ptr = mark_stack; + memset(mark_stack, 0, MARK_STACK_MAX); +} + +#define MARK_STACK_EMPTY (mark_stack_ptr == mark_stack) + +static int mark_all; + +static void rb_gc_mark_children(VALUE ptr); +static void +gc_mark_all() +{ + RVALUE *p, *pend; + int i; + mark_all = 0; + while(!mark_all){ + mark_all = 1; + for (i = 0; i < heaps_used; i++) { + p = heaps[i]; pend = p + heaps_limits[i]; + while (p < pend) { + if (!(rb_special_const_p((VALUE)p)) + && p->as.basic.flags&FL_MARK) { + rb_gc_mark_children((VALUE)p); + } + p++; + } + } + } +} + +static void +gc_mark_rest() +{ + VALUE tmp_arry[MARK_STACK_MAX]; + VALUE *p; + + p = (mark_stack_ptr - mark_stack) + tmp_arry; + memcpy(tmp_arry, mark_stack, MARK_STACK_MAX); + + init_mark_stack(); + + while(p != tmp_arry){ + p--; + rb_gc_mark(*p); + } +} + +#if defined(DJGPP) +# define STACK_LEVEL_MAX 65535; +#elif defined(__human68k__) +extern unsigned int _stacksize; +# define STACK_LEVEL_MAX (_stacksize - 4096) +#else +# define STACK_LEVEL_MAX 655300 +#endif + +#ifdef C_ALLOCA +# define SET_STACK_END VALUE stack_end; alloca(0); +# define STACK_END (&stack_end) +#else +# if defined(__GNUC__) && defined(USE_BUILTIN_FRAME_ADDRESS) +# define SET_STACK_END VALUE *stack_end = __builtin_frame_address(0); +# else +# define SET_STACK_END VALUE *stack_end = alloca(1); +# endif +# define STACK_END (stack_end) +#endif +#ifdef __sparc__ +# define STACK_LENGTH (rb_gc_stack_start - STACK_END + 0x80) +#else +# define STACK_LENGTH ((STACK_END < rb_gc_stack_start) ? rb_gc_stack_start - STACK_END\ + : STACK_END - rb_gc_stack_start) +#endif + +#define CHECK_STACK(ret) do {\ + SET_STACK_END;\ + ret = (STACK_LENGTH > STACK_LEVEL_MAX);\ +} while (0)\ + + static inline int is_pointer_to_heap(ptr) void *ptr; @@ -365,73 +455,6 @@ is_pointer_to_heap(ptr) return Qfalse; } -#define MARK_STACK_SIZE 4096 -static VALUE mark_stack_base[MARK_STACK_SIZE]; -static VALUE *mark_stack; -static int mark_stack_overflow = 0; - -#define PUSH_MARK(obj) do {\ - if (mark_stack_overflow) {\ - FL_SET((obj),FL_MARK);\ - }\ - else {\ - if (mark_stack - mark_stack_base >= MARK_STACK_SIZE) {\ - mark_stack_overflow = 1;\ - }\ - else {\ - if ( rb_special_const_p(obj) /* special const not marked */\ - || FL_TEST((obj),FL_MARK)) /* already marked */ {\ - }\ - else {\ - *mark_stack++ = (obj);\ - }\ - }\ - }\ -} while (0) - -#define POP_MARK() (*--mark_stack) - -#define MARK_EMPTY() (mark_stack == mark_stack_base) - -#ifdef NO_REGION - -#define PUSH_MARK_REGION(a,b) do {\ - VALUE *tmp_beg_ptr = (a);\ - while (tmp_beg_ptr < (b)) {\ - PUSH_MARK(*tmp_beg_ptr);\ - tmp_beg_ptr++;\ - }\ -} while (0) - -#else - -#define MARK_REGION_STACK_SIZE 1024 -static VALUE *mark_region_stack_base[MARK_REGION_STACK_SIZE]; -static VALUE **mark_region_stack; - -#define PUSH_MARK_REGION(a,b) do {\ - if (mark_region_stack - mark_region_stack_base >= MARK_REGION_STACK_SIZE || (b) - (a) < 3) {\ - VALUE *tmp_beg_ptr = (a);\ - while (tmp_beg_ptr < (b)) {\ - PUSH_MARK(*tmp_beg_ptr);\ - tmp_beg_ptr++;\ - }\ - }\ - else {\ - *mark_region_stack++ = (a);\ - *mark_region_stack++ = (b);\ - }\ -} while (0) - -#define POP_MARK_REGION(a,b) do {\ - (b) = (*--mark_region_stack);\ - (a) = (*--mark_region_stack);\ -} while (0) - -#define MARK_REGION_EMPTY() (mark_region_stack == mark_region_stack_base) - -#endif - static void mark_locations_array(x, n) register VALUE *x; @@ -478,23 +501,6 @@ rb_mark_tbl(tbl) st_foreach(tbl, mark_entry, 0); } -static int -push_entry(key, value) - ID key; - VALUE value; -{ - PUSH_MARK(value); - return ST_CONTINUE; -} - -static void -push_mark_tbl(tbl) - st_table *tbl; -{ - if (!tbl) return; - st_foreach(tbl, push_entry, 0); -} - static int mark_hashentry(key, value) VALUE key; @@ -513,24 +519,6 @@ rb_mark_hash(tbl) st_foreach(tbl, mark_hashentry, 0); } -static int -push_hashentry(key, value) - VALUE key; - VALUE value; -{ - PUSH_MARK(key); - PUSH_MARK(value); - return ST_CONTINUE; -} - -static void -push_mark_hash(tbl) - st_table *tbl; -{ - if (!tbl) return; - st_foreach(tbl, push_hashentry, 0); -} - void rb_gc_mark_maybe(obj) VALUE obj; @@ -540,14 +528,47 @@ rb_gc_mark_maybe(obj) } } -static void -gc_mark_children(ptr) +void +rb_gc_mark(ptr) VALUE ptr; { register RVALUE *obj = RANY(ptr); - Top: + if (!mark_stack_overflow){ + int ret; + CHECK_STACK(ret); + if (ret) { + if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) { + *mark_stack_ptr = ptr; + mark_stack_ptr++; + return; + }else{ + mark_stack_overflow = 1; + printf("mark_stack_overflow\n"); + } + } + } + + if (rb_special_const_p((VALUE)obj)) return; /* special const not marked */ + if (obj->as.basic.flags == 0) return; /* free cell */ + if (obj->as.basic.flags & FL_MARK) return; /* already marked */ + obj->as.basic.flags |= FL_MARK; + + if (mark_stack_overflow){ + mark_all &= 0; + return; + }else{ + rb_gc_mark_children(ptr); + } +} + +void +rb_gc_mark_children(ptr) + VALUE ptr; +{ + register RVALUE *obj = RANY(ptr); + if (FL_TEST(obj, FL_EXIVAR)) { rb_mark_generic_ivar((VALUE)obj); } @@ -568,7 +589,7 @@ gc_mark_children(ptr) case NODE_MASGN: case NODE_RESCUE: case NODE_RESBODY: - PUSH_MARK((VALUE)obj->as.node.u2.node); + rb_gc_mark((VALUE)obj->as.node.u2.node); /* fall through */ case NODE_BLOCK: /* 1,3 */ case NODE_ARRAY: @@ -582,14 +603,14 @@ gc_mark_children(ptr) case NODE_CALL: case NODE_DEFS: case NODE_OP_ASGN1: - PUSH_MARK((VALUE)obj->as.node.u1.node); + rb_gc_mark((VALUE)obj->as.node.u1.node); /* fall through */ case NODE_SUPER: /* 3 */ case NODE_FCALL: case NODE_DEFN: case NODE_NEWLINE: - obj = RANY(obj->as.node.u3.node); - goto Again; + rb_gc_mark((VALUE)obj->as.node.u3.node); + break; case NODE_WHILE: /* 1,2 */ case NODE_UNTIL: @@ -605,7 +626,7 @@ gc_mark_children(ptr) case NODE_MATCH3: case NODE_OP_ASGN_OR: case NODE_OP_ASGN_AND: - PUSH_MARK((VALUE)obj->as.node.u1.node); + rb_gc_mark((VALUE)obj->as.node.u1.node); /* fall through */ case NODE_METHOD: /* 2 */ case NODE_NOT: @@ -620,8 +641,8 @@ gc_mark_children(ptr) case NODE_MODULE: case NODE_COLON3: case NODE_OPT_N: - obj = RANY(obj->as.node.u2.node); - goto Again; + rb_gc_mark((VALUE)obj->as.node.u2.node); + break; case NODE_HASH: /* 1 */ case NODE_LIT: @@ -635,15 +656,15 @@ gc_mark_children(ptr) case NODE_YIELD: case NODE_COLON2: case NODE_ARGS: - obj = RANY(obj->as.node.u1.node); - goto Again; + rb_gc_mark((VALUE)obj->as.node.u1.node); + break; case NODE_SCOPE: /* 2,3 */ case NODE_CLASS: case NODE_BLOCK_PASS: - PUSH_MARK((VALUE)obj->as.node.u3.node); - obj = RANY(obj->as.node.u2.node); - goto Again; + rb_gc_mark((VALUE)obj->as.node.u3.node); + rb_gc_mark((VALUE)obj->as.node.u2.node); + break; case NODE_ZARRAY: /* - */ case NODE_ZSUPER: @@ -674,52 +695,53 @@ gc_mark_children(ptr) case NODE_ALLOCA: mark_locations_array((VALUE*)obj->as.node.u1.value, obj->as.node.u3.cnt); - obj = RANY(obj->as.node.u2.node); - goto Again; + rb_gc_mark((VALUE)obj->as.node.u2.node); + break; #endif default: if (is_pointer_to_heap(obj->as.node.u1.node)) { - PUSH_MARK((VALUE)obj->as.node.u1.node); + rb_gc_mark((VALUE)obj->as.node.u1.node); } if (is_pointer_to_heap(obj->as.node.u2.node)) { - PUSH_MARK((VALUE)obj->as.node.u2.node); + rb_gc_mark((VALUE)obj->as.node.u2.node); } if (is_pointer_to_heap(obj->as.node.u3.node)) { - obj = RANY(obj->as.node.u3.node); - goto Again; + rb_gc_mark((VALUE)obj->as.node.u3.node); } } return; /* no need to mark class. */ } - PUSH_MARK(obj->as.basic.klass); + rb_gc_mark(obj->as.basic.klass); switch (obj->as.basic.flags & T_MASK) { case T_ICLASS: case T_CLASS: case T_MODULE: - PUSH_MARK(obj->as.klass.super); - push_mark_tbl(obj->as.klass.m_tbl); - push_mark_tbl(obj->as.klass.iv_tbl); + rb_gc_mark(obj->as.klass.super); + rb_mark_tbl(obj->as.klass.m_tbl); + rb_mark_tbl(obj->as.klass.iv_tbl); break; case T_ARRAY: - { - int i, len = obj->as.array.len; - VALUE *ptr = obj->as.array.ptr; + { + int i, len = obj->as.array.len; + VALUE *ptr = obj->as.array.ptr; - PUSH_MARK_REGION(ptr,ptr+len); - } - break; + for (i=0; i < len; i++) + rb_gc_mark(*ptr++); + } + break; case T_HASH: - push_mark_hash(obj->as.hash.tbl); - obj = RANY(obj->as.hash.ifnone); - goto Again; + rb_mark_hash(obj->as.hash.tbl); + rb_gc_mark(obj->as.hash.ifnone); + break; case T_STRING: - obj = RANY(obj->as.string.orig); - goto Again; + if (obj->as.string.orig) { + rb_gc_mark((VALUE)obj->as.string.orig); + } break; case T_DATA: @@ -727,7 +749,7 @@ gc_mark_children(ptr) break; case T_OBJECT: - push_mark_tbl(obj->as.object.iv_tbl); + rb_mark_tbl(obj->as.object.iv_tbl); break; case T_FILE: @@ -739,79 +761,42 @@ gc_mark_children(ptr) case T_MATCH: if (obj->as.match.str) { - obj = RANY(obj->as.match.str); - goto Again; + rb_gc_mark((VALUE)obj->as.match.str); } break; case T_VARMAP: - PUSH_MARK(obj->as.varmap.val); - obj = RANY(obj->as.varmap.next); - goto Again; + rb_gc_mark(obj->as.varmap.val); + rb_gc_mark((VALUE)obj->as.varmap.next); + break; case T_SCOPE: if (obj->as.scope.local_vars && (obj->as.scope.flags & SCOPE_MALLOC)) { int n = obj->as.scope.local_tbl[0]+1; VALUE *vars = &obj->as.scope.local_vars[-1]; - - PUSH_MARK_REGION(vars,vars+n); + while (n--) { + rb_gc_mark(*vars); + vars++; + } } break; case T_STRUCT: - { - int i, len = obj->as.rstruct.len; - VALUE *ptr = obj->as.rstruct.ptr; + { + int i, len = obj->as.rstruct.len; + VALUE *ptr = obj->as.rstruct.ptr; - PUSH_MARK_REGION(ptr,ptr+len); - } - break; + for (i=0; i < len; i++) + rb_gc_mark(*ptr++); + } + break; default: rb_bug("rb_gc_mark(): unknown data type 0x%x(0x%x) %s", obj->as.basic.flags & T_MASK, obj, is_pointer_to_heap(obj)?"corrupted object":"non object"); } - return; - - Again: - if (rb_special_const_p(obj)) return; /* special const not marked */ - if (RBASIC(obj)->flags == 0) return; /* free cell */ - if (FL_TEST((obj),FL_MARK)) return; /* already marked */ - goto Top; -} - -void -rb_gc_mark(ptr) - VALUE ptr; -{ - if (rb_special_const_p(ptr)) return; /* special const not marked */ - if (RBASIC(ptr)->flags == 0) return; /* free cell */ - if (RBASIC(ptr)->flags & FL_MARK) return; /* already marked */ - gc_mark_children(ptr); -} - -static void -gc_mark() -{ - while (!MARK_EMPTY()) { - rb_gc_mark(POP_MARK()); -#ifndef NO_REGION - while (!MARK_REGION_EMPTY()) { - VALUE *p, *pend; - - POP_MARK_REGION(p, pend); - while (p < pend) { - rb_gc_mark(*p); - p++; - } - while (!MARK_EMPTY()) { - rb_gc_mark(POP_MARK()); - } - } -#endif - } } static void obj_free _((VALUE)); @@ -821,31 +806,24 @@ gc_sweep() { RVALUE *p, *pend, *final_list; int freed = 0; - int i; + int i, used = heaps_used; if (ruby_in_compile) { - int marked = 0; - /* should not reclaim nodes during compilation */ - for (i = 0; i < heaps_used; i++) { + for (i = 0; i < used; i++) { p = heaps[i]; pend = p + heaps_limits[i]; while (p < pend) { - if (!(p->as.basic.flags&FL_MARK) && BUILTIN_TYPE(p) == T_NODE) { + if (!(p->as.basic.flags&FL_MARK) && BUILTIN_TYPE(p) == T_NODE) rb_gc_mark((VALUE)p); - marked = 1; - } p++; } } - if (marked) { - gc_mark(); - } } freelist = 0; final_list = deferred_final_list; deferred_final_list = 0; - for (i = 0; i < heaps_used; i++) { + for (i = 0; i < used; i++) { int n = 0; p = heaps[i]; pend = p + heaps_limits[i]; @@ -905,7 +883,6 @@ void rb_gc_force_recycle(p) VALUE p; { - RANY(p)->type = BUILTIN_TYPE(p); RANY(p)->as.free.flags = 0; RANY(p)->as.free.next = freelist; freelist = RANY(p); @@ -1118,11 +1095,8 @@ rb_gc() if (during_gc) return; during_gc++; - mark_stack_overflow = 0; - mark_stack = mark_stack_base; -#ifndef NO_REGION - mark_region_stack = mark_region_stack_base; -#endif + init_mark_stack(); + /* mark frame stack */ for (frame = ruby_frame; frame; frame = frame->prev) { rb_gc_mark_frame(frame); @@ -1164,25 +1138,16 @@ rb_gc() /* mark generic instance variables for special constants */ rb_mark_generic_ivar_tbl(); - - gc_mark(); - while (mark_stack_overflow) { - RVALUE *p, *pend; - int i; - - mark_stack_overflow = 0; - for (i = 0; i < heaps_used; i++) { - p = heaps[i]; pend = p + heaps_limits[i]; - while (p < pend) { - if (p->as.basic.flags&FL_MARK) { - gc_mark_children((VALUE)p); - } - p++; - } + + /* gc_mark objects whose marking are not completed*/ + while (!MARK_STACK_EMPTY){ + if (mark_stack_overflow){ + gc_mark_all(); + break; + }else{ + gc_mark_rest(); } - gc_mark(); } - gc_sweep(); } @@ -1385,7 +1350,7 @@ static VALUE run_single_final(args) VALUE *args; { - rb_eval_cmd(args[0], args[1]); + rb_eval_cmd(args[0], args[1], 0); return Qnil; } diff --git a/intern.h b/intern.h index 8337de4585..35d913e71d 100644 --- a/intern.h +++ b/intern.h @@ -40,6 +40,7 @@ VALUE rb_ary_join _((VALUE, VALUE)); VALUE rb_ary_print_on _((VALUE, VALUE)); VALUE rb_ary_reverse _((VALUE)); VALUE rb_ary_sort _((VALUE)); +int rb_cmpint _((VALUE)); VALUE rb_ary_sort_bang _((VALUE)); VALUE rb_ary_delete _((VALUE, VALUE)); VALUE rb_ary_delete_at _((VALUE, long)); @@ -135,7 +136,7 @@ VALUE rb_dvar_ref _((ID)); void rb_dvar_asgn _((ID, VALUE)); void rb_dvar_push _((ID, VALUE)); VALUE *rb_svar _((int)); -VALUE rb_eval_cmd _((VALUE, VALUE)); +VALUE rb_eval_cmd _((VALUE, VALUE, int)); int rb_respond_to _((VALUE, ID)); void rb_interrupt _((void)); VALUE rb_apply _((VALUE, ID, VALUE)); diff --git a/mkconfig.rb b/mkconfig.rb index 05b5916997..473c592c5b 100644 --- a/mkconfig.rb +++ b/mkconfig.rb @@ -39,9 +39,7 @@ File.foreach "config.status" do |line| next if $install_name and /^RUBY_INSTALL_NAME$/ =~ name next if $so_name and /^RUBY_SO_NAME$/ =~ name v = " CONFIG[\"" + name + "\"] = " + - val.sub(/^\s*(.*)\s*$/, '\1').gsub(/\$\{?(\w+)\}?/) { - "$(#{$1})" - }.dump + "\n" + val.strip.gsub(/\$\{?(\w+)\}?/) {"$(#{$1})"}.dump + "\n" if fast[name] v_fast << v else diff --git a/parse.y b/parse.y index 89c63ab34c..54bccbad3e 100644 --- a/parse.y +++ b/parse.y @@ -3404,6 +3404,7 @@ yylex() break; case '.': + if (seen_uc) goto trailing_uc; if (seen_point || seen_e) { goto decode_num; } diff --git a/signal.c b/signal.c index 57e70024de..d20e5dcf75 100644 --- a/signal.c +++ b/signal.c @@ -355,7 +355,7 @@ sighandle(sig) rb_bug("trap_handler: Bad signal %d", sig); } -#if !defined(BSD_SIGNAL) +#if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL) ruby_signal(sig, sighandle); #endif @@ -407,7 +407,7 @@ rb_trap_exit() VALUE trap_exit = trap_list[0]; trap_list[0] = 0; - rb_eval_cmd(trap_exit, rb_ary_new3(1, INT2FIX(0))); + rb_eval_cmd(trap_exit, rb_ary_new3(1, INT2FIX(0)), 0); } #endif } @@ -628,6 +628,9 @@ sig_trap(argc, argv) arg.cmd = argv[1]; } + if (OBJ_TAINTED(arg.cmd)) { + rb_raise(rb_eSecurityError, "Insecure: tainted signal trap"); + } #if !defined(NT) /* disable interrupt */ # ifdef HAVE_SIGPROCMASK diff --git a/string.c b/string.c index 183db6a7fe..01ee1b5e92 100644 --- a/string.c +++ b/string.c @@ -103,7 +103,7 @@ VALUE rb_str_new3(str) VALUE str; { - VALUE str2 = rb_obj_alloc(rb_cString); + VALUE str2 = rb_obj_alloc(rb_obj_class(str)); RSTRING(str2)->len = RSTRING(str)->len; RSTRING(str2)->ptr = RSTRING(str)->ptr; @@ -124,13 +124,13 @@ rb_str_new4(orig) VALUE str; if (FL_TEST(orig, STR_NO_ORIG)) { - str = rb_str_new(RSTRING(orig)->ptr, RSTRING(orig)->len); + str = rb_str_new0(klass, RSTRING(orig)->ptr, RSTRING(orig)->len); } else { str = rb_str_new3(RSTRING(orig)->orig); + RBASIC(str)->klass = klass; } OBJ_FREEZE(str); - RBASIC(str)->klass = klass; return str; } else { @@ -139,7 +139,6 @@ rb_str_new4(orig) RSTRING(str)->len = RSTRING(orig)->len; RSTRING(str)->ptr = RSTRING(orig)->ptr; RSTRING(orig)->orig = str; - RSTRING(str)->orig = 0; OBJ_INFECT(str, orig); OBJ_FREEZE(str); @@ -287,10 +286,11 @@ rb_str_dup(str) if (OBJ_FROZEN(str)) str2 = rb_str_new3(str); else if (FL_TEST(str, STR_NO_ORIG)) { - str2 = rb_str_new(RSTRING(str)->ptr, RSTRING(str)->len); + str2 = rb_str_new0(klass, RSTRING(str)->ptr, RSTRING(str)->len); } else if (RSTRING(str)->orig) { str2 = rb_str_new3(RSTRING(str)->orig); + RBASIC(str2)->klass = klass; FL_UNSET(str2, FL_TAINT); OBJ_INFECT(str2, str); } @@ -300,7 +300,6 @@ rb_str_dup(str) if (FL_TEST(str, FL_EXIVAR)) rb_copy_generic_ivar(str2, str); OBJ_INFECT(str2, str); - RBASIC(str2)->klass = klass; return str2; } @@ -448,6 +447,7 @@ str_independent(str) if (!OBJ_TAINTED(str) && rb_safe_level() >= 4) rb_raise(rb_eSecurityError, "Insecure: can't modify string"); if (!RSTRING(str)->orig || FL_TEST(str, STR_NO_ORIG)) return 1; + if (RBASIC(str)->flags == 0) abort(); if (TYPE(RSTRING(str)->orig) != T_STRING) rb_bug("non string str->orig"); return 0; } diff --git a/variable.c b/variable.c index fc02f749f7..1f8f2fb7ff 100644 --- a/variable.c +++ b/variable.c @@ -402,7 +402,7 @@ var_getter(id, var) ID id; VALUE *var; { - if (!var || !*var) return Qnil; + if (!var) return Qnil; return *var; } @@ -518,7 +518,7 @@ static void rb_trace_eval(cmd, val) VALUE cmd, val; { - rb_eval_cmd(cmd, rb_ary_new3(1, val)); + rb_eval_cmd(cmd, rb_ary_new3(1, val), 0); } VALUE @@ -527,19 +527,19 @@ rb_f_trace_var(argc, argv) VALUE *argv; { VALUE var, cmd; - ID id; struct global_entry *entry; struct trace_var *trace; + rb_secure(4); if (rb_scan_args(argc, argv, "11", &var, &cmd) == 1) { cmd = rb_f_lambda(); } if (NIL_P(cmd)) { return rb_f_untrace_var(argc, argv); } - id = rb_to_id(var); - if (!st_lookup(rb_global_tbl, id, &entry)) { - rb_name_error(id, "undefined global variable %s", rb_id2name(id)); + entry = rb_global_entry(rb_to_id(var)); + if (OBJ_TAINTED(cmd)) { + rb_raise(rb_eSecurityError, "Insecure: tainted variable trace"); } trace = ALLOC(struct trace_var); trace->next = entry->var->trace; @@ -1419,17 +1419,28 @@ rb_cvar_singleton(obj) return CLASS_OF(obj); } +static VALUE +original_module(c) + VALUE c; +{ + if (TYPE(c) == T_ICLASS) + return RBASIC(c)->klass; + return c; +} + static void -cvar_override_check(id, a, b) - VALUE a, b; +cvar_override_check(id, a) + VALUE a; { + VALUE base = original_module(a); + a = RCLASS(a)->super; while (a) { if (RCLASS(a)->iv_tbl) { if (st_lookup(RCLASS(a)->iv_tbl,id,0)) { rb_warning("class variable %s of %s is overridden by %s", - rb_id2name(id), rb_class2name(a), - rb_class2name(b)); + rb_id2name(id), rb_class2name(original_module(a)), + rb_class2name(base)); } } a = RCLASS(a)->super; @@ -1452,7 +1463,7 @@ rb_cvar_set(klass, id, val) 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, klass); + cvar_override_check(id, tmp); } return; } @@ -1482,7 +1493,7 @@ rb_cvar_declare(klass, id, val) } st_insert(RCLASS(tmp)->iv_tbl,id,val); if (ruby_verbose) { - cvar_override_check(id, tmp, klass); + cvar_override_check(id, tmp); } return; } @@ -1505,7 +1516,7 @@ rb_cvar_get(klass, id) if (RCLASS(tmp)->iv_tbl) { if (st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) { if (ruby_verbose) { - cvar_override_check(id, tmp, klass); + cvar_override_check(id, tmp); } return value; } -- cgit v1.2.3