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

* 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
This commit is contained in:
matz 2001-11-13 08:19:52 +00:00
parent 948ff2456b
commit 7422ccdd9e
14 changed files with 328 additions and 270 deletions

View file

@ -5,6 +5,11 @@ Tue Nov 13 16:49:16 2001 Usaku Nakamura <usa@ruby-lang.org>
* win32/win32.c (do_spawn): ditto.
Tue Nov 13 14:39:11 2001 WATANABE Tetsuya <tetsu@jpn.hp.com>
* signal.c (sighandle): should not re-register sighandler if
POSIX_SIGNAL is defined.
Tue Nov 13 12:55:59 2001 Usaku Nakamura <usa@ruby-lang.org>
* win32/win32.c (do_spawn): use CreateChild() instead of calling
@ -70,6 +75,45 @@ Tue Nov 13 12:38:12 2001 Usaku Nakamura <usa@ruby-lang.org>
* win32/win32.c, win32/win32.h (win32_free_environ): free environment
variables list. [new]
Mon Nov 12 16:48:48 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (error_print): errat array may be empty.
Mon Nov 12 01:30:37 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* 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 <sheepman@tcn.zaq.ne.jp>
* gc.c: do not use static stack until system stack overflows.
Sat Nov 10 03:57:09 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* 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 <matz@ruby-lang.org>
* 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 <usa@ruby-lang.org>
* win32/config.status.in: make CFLAGS same as Makefile's one.
@ -82,6 +126,22 @@ Thu Nov 8 20:20:37 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* eval.c (rb_call0): adjust caller source file/line while
evaluating optional arguments.
Thu Nov 8 18:41:58 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* 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 <matz@ruby-lang.org>
* file.c (path_check_1): forgot to initialize 'p'.

18
array.c
View file

@ -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

View file

@ -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

10
enum.c
View file

@ -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;

View file

@ -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;
}

18
eval.c
View file

@ -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);
}

3
file.c
View file

@ -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);
}

417
gc.c
View file

@ -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;
}

View file

@ -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));

View file

@ -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

View file

@ -3404,6 +3404,7 @@ yylex()
break;
case '.':
if (seen_uc) goto trailing_uc;
if (seen_point || seen_e) {
goto decode_num;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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 void
cvar_override_check(id, a, b)
VALUE a, b;
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)
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;
}