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

* string.c (rb_str_sum): check was done with false pointer.

[ruby-dev:24383]

* string.c (rb_str_sum): string may be altered.  [ruby-dev:24381]

* eval.c (rb_f_eval): defer pointer retrieval to prevent unsafe
  sourcefile string modification.  [ruby-dev:24373]

* io.c (io_read): block string buffer modification during
  rb_io_fread() by freezing it temporarily. [ruby-dev:24366]

* io.c (rb_io_s_popen): mode argument may be altered.
  [ruby-dev:24375]

* file.c (rb_file_s_basename): ext argument may be altered.
  [ruby-dev:24377]

* enum.c (enum_sort_by): use NODE instead of 2 element arrays.
  [ruby-dev:24378]

* string.c (rb_str_chomp_bang): StringValue() may change the
  receiver.  [ruby-dev:24371]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@6979 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2004-10-02 03:50:53 +00:00
parent d57bbd48f8
commit 6f9dcadf6e
16 changed files with 328 additions and 160 deletions

View file

@ -1,3 +1,30 @@
Sat Oct 2 00:42:20 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* string.c (rb_str_sum): check was done with false pointer.
[ruby-dev:24383]
* string.c (rb_str_sum): string may be altered. [ruby-dev:24381]
Fri Oct 1 11:40:14 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (rb_f_eval): defer pointer retrieval to prevent unsafe
sourcefile string modification. [ruby-dev:24373]
* io.c (io_read): block string buffer modification during
rb_io_fread() by freezing it temporarily. [ruby-dev:24366]
* io.c (rb_io_s_popen): mode argument may be altered.
[ruby-dev:24375]
* file.c (rb_file_s_basename): ext argument may be altered.
[ruby-dev:24377]
* enum.c (enum_sort_by): use NODE instead of 2 element arrays.
[ruby-dev:24378]
* string.c (rb_str_chomp_bang): StringValue() may change the
receiver. [ruby-dev:24371]
Fri Oct 1 11:25:20 2004 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk/grid.rb: revive TkGrid.grid
@ -22,6 +49,36 @@ Wed Sep 29 10:58:07 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
* enum.c (sort_by_i): internally used object must not be changed
outside. [ruby-dev:24368]
Mon Sep 27 09:14:03 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* ext/socket/socket.c (s_accept): don't retry for EWOULDBLOCK.
[ruby-talk:113807]
Fri Sep 24 16:09:42 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (proc_invoke): propagate DVAR_DONT_RECYCLE on termination
to avoid double call to rb_gc_force_recycle(). [ruby-dev:24311]
Fri Sep 24 08:29:45 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* array.c (rb_ary_subseq): original object might be modified after
sharing data creation. [ruby-dev:24327]
* array.c (rb_ary_replace): ditto.
* array.c (ary_make_shared): freeze shared array. [ruby-dev:24325]
* struct.c (struct_members): always check struct size and size of
members list in the class. [ruby-dev:24320]
Thu Sep 23 09:29:14 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* string.c (rb_str_sub_bang): check if string is not modified
during iteration. [ruby-dev:24315]
* hash.c (rb_hash_rehash): replace st_foreach() by its deep
checking counterpart. [ruby-dev:24310]
Wed Sep 22 13:38:12 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* hash.c (rb_hash_rehash): add iteration check. [ruby-dev:24301]

57
array.c
View file

@ -459,7 +459,7 @@ rb_ary_pop(ary)
return RARRAY(ary)->ptr[--RARRAY(ary)->len];
}
static void
static VALUE
ary_make_shared(ary)
VALUE ary;
{
@ -472,6 +472,11 @@ ary_make_shared(ary)
shared->aux.capa = RARRAY(ary)->aux.capa;
RARRAY(ary)->aux.shared = (VALUE)shared;
FL_SET(ary, ELTS_SHARED);
OBJ_FREEZE(shared);
return (VALUE)shared;
}
else {
return RARRAY(ary)->aux.shared;
}
}
@ -591,7 +596,8 @@ rb_ary_subseq(ary, beg, len)
VALUE ary;
long beg, len;
{
VALUE klass, ary2;
VALUE klass, ary2, shared;
VALUE *ptr;
if (beg > RARRAY(ary)->len) return Qnil;
if (beg < 0 || len < 0) return Qnil;
@ -604,11 +610,12 @@ rb_ary_subseq(ary, beg, len)
klass = rb_obj_class(ary);
if (len == 0) return ary_new(klass, 0);
ary_make_shared(ary);
shared = ary_make_shared(ary);
ptr = RARRAY(ary)->ptr;
ary2 = ary_alloc(klass);
RARRAY(ary2)->ptr = RARRAY(ary)->ptr + beg;
RARRAY(ary2)->ptr = ptr + beg;
RARRAY(ary2)->len = len;
RARRAY(ary2)->aux.shared = RARRAY(ary)->aux.shared;
RARRAY(ary2)->aux.shared = shared;
FL_SET(ary2, ELTS_SHARED);
return ary2;
@ -1562,9 +1569,10 @@ sort_1(a, b, data)
struct ary_sort_data *data;
{
VALUE retval = rb_yield_values(2, *a, *b);
int n;
ary_sort_check(data);
return rb_cmpint(retval, *a, *b);
n = rb_cmpint(retval, *a, *b);
return n;
}
static int
@ -1573,11 +1581,12 @@ sort_2(ap, bp, data)
struct ary_sort_data *data;
{
VALUE retval;
long a = (long)*ap, b = (long)*bp;
VALUE a = *ap, b = *bp;
int n;
if (FIXNUM_P(a) && FIXNUM_P(b)) {
if (a > b) return 1;
if (a < b) return -1;
if ((long)a > (long)b) return 1;
if ((long)a < (long)b) return -1;
return 0;
}
if (TYPE(a) == T_STRING && TYPE(b) == T_STRING) {
@ -1585,8 +1594,9 @@ sort_2(ap, bp, data)
}
retval = rb_funcall(a, id_cmp, 1, b);
ary_sort_check(data);
return rb_cmpint(retval, a, b);
n = rb_cmpint(retval, a, b);
return n;
}
static VALUE
@ -2150,15 +2160,17 @@ static VALUE
rb_ary_replace(copy, orig)
VALUE copy, orig;
{
VALUE shared;
rb_ary_modify(copy);
orig = to_ary(orig);
if (copy == orig) return copy;
ary_make_shared(orig);
shared = ary_make_shared(orig);
if (RARRAY(copy)->ptr && !FL_TEST(copy, ELTS_SHARED))
free(RARRAY(copy)->ptr);
RARRAY(copy)->ptr = RARRAY(orig)->ptr;
RARRAY(copy)->len = RARRAY(orig)->len;
RARRAY(copy)->aux.shared = RARRAY(orig)->aux.shared;
RARRAY(copy)->ptr = RARRAY(shared)->ptr;
RARRAY(copy)->len = RARRAY(shared)->len;
RARRAY(copy)->aux.shared = shared;
FL_SET(copy, ELTS_SHARED);
return copy;
@ -2874,8 +2886,11 @@ flatten(ary, idx, ary2, memo)
rb_ary_push(memo, id);
rb_ary_update(ary, idx, 1, ary2);
while (i < lim) {
if (TYPE(RARRAY(ary)->ptr[i]) == T_ARRAY) {
n = flatten(ary, i, RARRAY(ary)->ptr[i], memo);
VALUE tmp;
tmp = rb_check_array_type(RARRAY(ary)->ptr[i]);
if (!NIL_P(tmp)) {
n = flatten(ary, i, tmp, memo);
i += n; lim += n;
}
i++;
@ -2910,12 +2925,14 @@ rb_ary_flatten_bang(ary)
rb_ary_modify(ary);
while (i<RARRAY(ary)->len) {
VALUE ary2 = RARRAY(ary)->ptr[i];
VALUE tmp;
if (TYPE(ary2) == T_ARRAY) {
tmp = rb_check_array_type(ary2);
if (!NIL_P(tmp)) {
if (NIL_P(memo)) {
memo = rb_ary_new();
}
i += flatten(ary, i, ary2, memo);
i += flatten(ary, i, tmp, memo);
mod = 1;
}
i++;

25
enum.c
View file

@ -389,26 +389,26 @@ static VALUE
sort_by_i(i, ary)
VALUE i, ary;
{
VALUE v, e;
VALUE v;
NODE *memo;
v = rb_yield(i);
e = rb_assoc_new(v, i);
OBJ_FREEZE(e);
rb_ary_push(ary, e);
memo = rb_node_newnode(NODE_MEMO, v, i, 0);
rb_ary_push(ary, (VALUE)memo);
return Qnil;
}
static VALUE
sort_by_cmp(values, ary)
VALUE values;
VALUE values, ary;
{
VALUE a = RARRAY(values)->ptr[0];
VALUE b = RARRAY(values)->ptr[1];
NODE *a = (NODE*)RARRAY(values)->ptr[0];
NODE *b = (NODE*)RARRAY(values)->ptr[1];
/* pedantic check; they must be arrays */
Check_Type(a, T_ARRAY);
Check_Type(b, T_ARRAY);
return rb_funcall(RARRAY(a)->ptr[0], id_cmp, 1, RARRAY(b)->ptr[0]);
/* pedantic check; they must be memo nodes */
Check_Type(a, T_NODE);
Check_Type(b, T_NODE);
return rb_funcall(a->u1.value, id_cmp, 1, b->u1.value);
}
/*
@ -498,8 +498,7 @@ enum_sort_by(obj)
rb_iterate(rb_ary_sort_bang, ary, sort_by_cmp, ary);
}
for (i=0; i<RARRAY(ary)->len; i++) {
VALUE e = RARRAY(ary)->ptr[i];
RARRAY(ary)->ptr[i] = RARRAY(e)->ptr[1];
RARRAY(ary)->ptr[i] = RNODE(RARRAY(ary)->ptr[i])->u2.value;
}
return ary;
}

15
eval.c
View file

@ -6187,12 +6187,13 @@ rb_f_eval(argc, argv, self)
SafeStringValue(src);
}
if (argc >= 3) {
file = StringValuePtr(vfile);
StringValue(vfile);
}
if (argc >= 4) {
line = NUM2INT(vline);
}
if (!NIL_P(vfile)) file = RSTRING(vfile)->ptr;
if (NIL_P(scope) && ruby_frame->prev) {
struct FRAME *prev;
VALUE val;
@ -8096,6 +8097,14 @@ proc_invoke(proc, args, self, klass)
POP_ITER();
ruby_block = old_block;
ruby_wrapper = old_wrapper;
if (FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE)) {
struct RVarmap *vars;
for (vars = old_dvars; vars; vars = vars->next) {
if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
FL_SET(vars, DVAR_DONT_RECYCLE);
}
}
ruby_dyna_vars = old_dvars;
ruby_safe_level = safe;
@ -12076,6 +12085,7 @@ rb_callcc(self)
volatile rb_thread_t th_save;
struct tag *tag;
struct RVarmap *vars;
struct BLOCK *blk;
THREAD_ALLOC(th);
cont = Data_Wrap_Struct(rb_cCont, thread_mark, thread_free, th);
@ -12086,11 +12096,10 @@ rb_callcc(self)
}
th->thread = curr_thread->thread;
for (vars = th->dyna_vars; vars; vars = vars->next) {
for (vars = ruby_dyna_vars; vars; vars = vars->next) {
if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
FL_SET(vars, DVAR_DONT_RECYCLE);
}
th_save = th;
if (THREAD_SAVE_CONTEXT(th)) {
return th_save->result;

View file

@ -1168,6 +1168,8 @@ s_accept(klass, fd, sockaddr, len)
rb_gc();
retry = 1;
goto retry;
case EWOULDBLOCK:
break;
default:
if (!rb_io_wait_readable(fd)) break;
retry = 0;

11
file.c
View file

@ -1644,8 +1644,7 @@ rb_file_s_lchmod(argc, argv)
{
VALUE vmode;
VALUE rest;
int mode;
long n;
long mode, n;
rb_secure(2);
rb_scan_args(argc, argv, "1*", &vmode, &rest);
@ -2560,11 +2559,11 @@ rb_file_s_basename(argc, argv)
VALUE *argv;
{
VALUE fname, fext, basename;
char *name, *p, *ext = NULL;
char *name, *p;
int f;
if (rb_scan_args(argc, argv, "11", &fname, &fext) == 2) {
ext = StringValueCStr(fext);
StringValue(fext);
}
StringValue(fname);
if (RSTRING(fname)->len == 0 || !*(name = RSTRING(fname)->ptr))
@ -2580,7 +2579,7 @@ rb_file_s_basename(argc, argv)
#endif
}
else if (!(p = strrdirsep(name))) {
if (NIL_P(fext) || !(f = rmext(name, ext))) {
if (NIL_P(fext) || !(f = rmext(name, StringValueCStr(fext)))) {
f = chompdirsep(name) - name;
if (f == RSTRING(fname)->len) return fname;
}
@ -2588,7 +2587,7 @@ rb_file_s_basename(argc, argv)
}
else {
while (isdirsep(*p)) p++; /* skip last / */
if (NIL_P(fext) || !(f = rmext(p, ext))) {
if (NIL_P(fext) || !(f = rmext(p, StringValueCStr(fext)))) {
f = chompdirsep(p) - p;
}
}

116
hash.c
View file

@ -114,16 +114,54 @@ static struct st_hash_type objhash = {
rb_any_hash,
};
struct rb_hash_foreach_arg {
struct foreach_safe_arg {
st_table *tbl;
int (*func)();
st_data_t arg;
};
static int
foreach_safe_i(key, value, arg, err)
st_data_t key, value;
struct foreach_safe_arg *arg;
{
int status;
if (err) {
rb_raise(rb_eRuntimeError, "hash modified during iteration");
}
if (key == Qundef) return ST_CONTINUE;
status = (*arg->func)(key, value, arg->arg, err);
if (status == ST_CONTINUE) {
return ST_CHECK;
}
return status;
}
void
st_foreach_safe(table, func, a)
st_table *table;
int (*func)();
st_data_t a;
{
struct foreach_safe_arg arg;
arg.tbl = table;
arg.func = func;
arg.arg = a;
st_foreach(table, foreach_safe_i, (st_data_t)&arg);
}
struct hash_foreach_arg {
VALUE hash;
enum st_retval (*func)();
int (*func)();
VALUE arg;
};
static int
rb_hash_foreach_iter(key, value, arg, err)
hash_foreach_iter(key, value, arg, err)
VALUE key, value;
struct rb_hash_foreach_arg *arg;
struct hash_foreach_arg *arg;
int err;
{
int status;
@ -151,15 +189,7 @@ rb_hash_foreach_iter(key, value, arg, err)
}
static VALUE
rb_hash_foreach_call(arg)
struct rb_hash_foreach_arg *arg;
{
st_foreach(RHASH(arg->hash)->tbl, rb_hash_foreach_iter, (st_data_t)arg);
return Qnil;
}
static VALUE
rb_hash_foreach_ensure(hash)
hash_foreach_ensure(hash)
VALUE hash;
{
RHASH(hash)->iter_lev--;
@ -173,19 +203,27 @@ rb_hash_foreach_ensure(hash)
return 0;
}
static int
static VALUE
hash_foreach_call(arg)
struct hash_foreach_arg *arg;
{
st_foreach(RHASH(arg->hash)->tbl, hash_foreach_iter, (st_data_t)arg);
return Qnil;
}
void
rb_hash_foreach(hash, func, farg)
VALUE hash;
enum st_retval (*func)();
int (*func)();
VALUE farg;
{
struct rb_hash_foreach_arg arg;
struct hash_foreach_arg arg;
RHASH(hash)->iter_lev++;
arg.hash = hash;
arg.func = func;
arg.arg = farg;
return rb_ensure(rb_hash_foreach_call, (VALUE)&arg, rb_hash_foreach_ensure, hash);
rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash);
}
static VALUE hash_alloc _((VALUE));
@ -354,7 +392,7 @@ rb_hash_rehash(hash)
rb_hash_modify(hash);
tbl = st_init_table_with_size(&objhash, RHASH(hash)->tbl->num_entries);
st_foreach(RHASH(hash)->tbl, rb_hash_rehash_i, (st_data_t)tbl);
rb_hash_foreach(hash, rb_hash_rehash_i, (st_data_t)tbl);
st_free_table(RHASH(hash)->tbl);
RHASH(hash)->tbl = tbl;
@ -566,7 +604,7 @@ rb_hash_index(hash, value)
args[0] = value;
args[1] = Qnil;
st_foreach(RHASH(hash)->tbl, index_i, (st_data_t)args);
rb_hash_foreach(hash, index_i, (st_data_t)args);
return args[1];
}
@ -678,7 +716,7 @@ rb_hash_shift(hash)
rb_hash_modify(hash);
var.stop = 0;
st_foreach(RHASH(hash)->tbl, shift_i, (st_data_t)&var);
rb_hash_foreach(hash, shift_i, (st_data_t)&var);
if (var.stop) {
return rb_assoc_new(var.key, var.val);
@ -691,7 +729,7 @@ rb_hash_shift(hash)
}
}
static enum st_retval
static int
delete_if_i(key, value, hash)
VALUE key, value, hash;
{
@ -758,7 +796,7 @@ rb_hash_reject(hash)
return rb_hash_delete_if(rb_obj_dup(hash));
}
static enum st_retval
static int
select_i(key, value, result)
VALUE key, value, result;
{
@ -849,7 +887,7 @@ rb_hash_clear(hash)
rb_hash_modify(hash);
if (RHASH(hash)->tbl->num_entries > 0) {
st_foreach(RHASH(hash)->tbl, clear_i, 0);
rb_hash_foreach(hash, clear_i, 0);
}
return hash;
@ -917,7 +955,7 @@ rb_hash_replace(hash, hash2)
hash2 = to_hash(hash2);
if (hash == hash2) return hash;
rb_hash_clear(hash);
st_foreach(RHASH(hash2)->tbl, replace_i, hash);
rb_hash_foreach(hash2, replace_i, hash);
RHASH(hash)->ifnone = RHASH(hash2)->ifnone;
if (FL_TEST(hash2, HASH_PROC_DEFAULT)) {
FL_SET(hash, HASH_PROC_DEFAULT);
@ -969,7 +1007,7 @@ rb_hash_empty_p(hash)
return Qfalse;
}
static enum st_retval
static int
each_value_i(key, value)
VALUE key, value;
{
@ -1002,7 +1040,7 @@ rb_hash_each_value(hash)
return hash;
}
static enum st_retval
static int
each_key_i(key, value)
VALUE key, value;
{
@ -1034,7 +1072,7 @@ rb_hash_each_key(hash)
return hash;
}
static enum st_retval
static int
each_pair_i(key, value)
VALUE key, value;
{
@ -1068,7 +1106,7 @@ rb_hash_each_pair(hash)
return hash;
}
static enum st_retval
static int
each_i(key, value)
VALUE key, value;
{
@ -1132,7 +1170,7 @@ rb_hash_to_a(hash)
VALUE ary;
ary = rb_ary_new();
st_foreach(RHASH(hash)->tbl, to_a_i, ary);
rb_hash_foreach(hash, to_a_i, ary);
if (OBJ_TAINTED(hash)) OBJ_TAINT(ary);
return ary;
@ -1190,7 +1228,7 @@ inspect_hash(hash)
VALUE str;
str = rb_str_buf_new2("{");
st_foreach(RHASH(hash)->tbl, inspect_i, str);
rb_hash_foreach(hash, inspect_i, str);
rb_str_buf_cat2(str, "}");
OBJ_INFECT(str, hash);
@ -1284,7 +1322,7 @@ rb_hash_keys(hash)
VALUE ary;
ary = rb_ary_new();
st_foreach(RHASH(hash)->tbl, keys_i, ary);
rb_hash_foreach(hash, keys_i, ary);
return ary;
}
@ -1317,7 +1355,7 @@ rb_hash_values(hash)
VALUE ary;
ary = rb_ary_new();
st_foreach(RHASH(hash)->tbl, values_i, ary);
rb_hash_foreach(hash, values_i, ary);
return ary;
}
@ -1382,7 +1420,7 @@ rb_hash_has_value(hash, val)
data[0] = Qfalse;
data[1] = val;
st_foreach(RHASH(hash)->tbl, rb_hash_search_value, (st_data_t)data);
rb_hash_foreach(hash, rb_hash_search_value, (st_data_t)data);
return data[0];
}
@ -1434,7 +1472,7 @@ hash_equal(hash1, hash2, eql)
data.tbl = RHASH(hash2)->tbl;
data.result = Qtrue;
st_foreach(RHASH(hash1)->tbl, equal_i, (st_data_t)&data);
rb_hash_foreach(hash1, equal_i, (st_data_t)&data);
return data.result;
}
@ -1509,7 +1547,7 @@ rb_hash_invert(hash)
{
VALUE h = rb_hash_new();
st_foreach(RHASH(hash)->tbl, rb_hash_invert_i, h);
rb_hash_foreach(hash, rb_hash_invert_i, h);
return h;
}
@ -1555,10 +1593,10 @@ rb_hash_update(hash1, hash2)
{
hash2 = to_hash(hash2);
if (rb_block_given_p()) {
st_foreach(RHASH(hash2)->tbl, rb_hash_update_block_i, hash1);
rb_hash_foreach(hash2, rb_hash_update_block_i, hash1);
}
else {
st_foreach(RHASH(hash2)->tbl, rb_hash_update_i, hash1);
rb_hash_foreach(hash2, rb_hash_update_i, hash1);
}
return hash1;
}
@ -2345,7 +2383,7 @@ env_replace(env, hash)
if (env == hash) return env;
hash = to_hash(hash);
st_foreach(RHASH(hash)->tbl, env_replace_i, keys);
rb_hash_foreach(hash, env_replace_i, keys);
for (i=0; i<RARRAY(keys)->len; i++) {
env_delete(env, RARRAY(keys)->ptr[i]);
@ -2372,7 +2410,7 @@ env_update(env, hash)
{
if (env == hash) return env;
hash = to_hash(hash);
st_foreach(RHASH(hash)->tbl, env_update_i, 0);
rb_hash_foreach(hash, env_update_i, 0);
return env;
}

View file

@ -245,6 +245,8 @@ VALUE rb_gc_enable _((void));
VALUE rb_gc_disable _((void));
VALUE rb_gc_start _((void));
/* hash.c */
void st_foreach _((struct st_table *, int (*)(), unsigned long));
void rb_hash_foreach _((VALUE, int (*)(), VALUE));
VALUE rb_hash _((VALUE));
VALUE rb_hash_new _((void));
VALUE rb_hash_freeze _((VALUE));

6
io.c
View file

@ -1067,11 +1067,13 @@ io_read(argc, argv, io)
StringValue(str);
rb_str_modify(str);
rb_str_resize(str,len);
FL_SET(str, FL_FREEZE);
}
if (len == 0) return str;
READ_CHECK(fptr->f);
n = rb_io_fread(RSTRING(str)->ptr, len, fptr->f);
FL_UNSET(str, FL_FREEZE);
if (n == 0) {
rb_str_resize(str,0);
if (!fptr->f) return Qnil;
@ -2721,7 +2723,9 @@ rb_io_popen(str, argc, argv, klass)
mode = rb_io_modenum_mode(FIX2INT(pmode), mbuf);
}
else {
mode = StringValuePtr(pmode);
strncpy(mbuf, StringValuePtr(pmode), sizeof(mbuf) - 1);
mbuf[sizeof(mbuf) - 1] = 0;
mode = mbuf;
}
SafeStringValue(pname);
port = pipe_open(str, mode);

View file

@ -437,7 +437,7 @@ w_ivar(tbl, arg)
{
if (tbl) {
w_long(tbl->num_entries, arg->arg);
st_foreach(tbl, w_obj_each, (st_data_t)arg);
st_foreach_safe(tbl, w_obj_each, (st_data_t)arg);
}
else {
w_long(0, arg->arg);
@ -621,7 +621,7 @@ w_object(obj, arg, limit)
w_byte(TYPE_HASH_DEF, arg);
}
w_long(RHASH(obj)->tbl->num_entries, arg);
st_foreach(RHASH(obj)->tbl, hash_each, (st_data_t)&c_arg);
rb_hash_foreach(obj, hash_each, (st_data_t)&c_arg);
if (!NIL_P(RHASH(obj)->ifnone)) {
w_object(RHASH(obj)->ifnone, arg, limit);
}

View file

@ -404,7 +404,7 @@ static VALUE
inspect_obj(obj, str)
VALUE obj, str;
{
st_foreach(ROBJECT(obj)->iv_tbl, inspect_i, str);
st_foreach_safe(ROBJECT(obj)->iv_tbl, inspect_i, str);
rb_str_cat2(str, ">");
RSTRING(str)->ptr[0] = '#';
OBJ_INFECT(str, obj);

View file

@ -1214,8 +1214,8 @@ rb_f_exec(argc, argv)
rb_raise(rb_eArgError, "wrong first argument");
}
prog = RARRAY(tmp)->ptr[0];
SafeStringValue(prog);
argv[0] = RARRAY(tmp)->ptr[1];
SafeStringValue(prog);
}
if (argc == 1 && prog == 0) {
VALUE cmd = argv[0];

4
re.c
View file

@ -1681,8 +1681,6 @@ rb_reg_initialize_m(argc, argv, self)
len = RREGEXP(argv[0])->len;
}
else {
s = StringValuePtr(argv[0]);
len = RSTRING(argv[0])->len;
if (argc >= 2) {
if (FIXNUM_P(argv[1])) flags = FIX2INT(argv[1]);
else if (RTEST(argv[1])) flags = RE_OPTION_IGNORECASE;
@ -1708,6 +1706,8 @@ rb_reg_initialize_m(argc, argv, self)
break;
}
}
s = StringValuePtr(argv[0]);
len = RSTRING(argv[0])->len;
}
rb_reg_initialize(self, s, len, flags);
return self;

View file

@ -1913,8 +1913,13 @@ rb_str_sub_bang(argc, argv, str)
regs = RMATCH(match)->regs;
if (iter) {
char *p = RSTRING(str)->ptr; long len = RSTRING(str)->len;
rb_match_busy(match);
repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
if (RSTRING(str)->ptr != p || RSTRING(str)->len != len) {
rb_raise(rb_eRuntimeError, "string modified");
}
rb_backref_set(match);
}
else {
@ -3095,7 +3100,7 @@ tr_setup_table(str, table, init)
buf[c & 0xff] = !cflag;
}
for (i=0; i<256; i++) {
table[i] = table[i]&&buf[i];
table[i] = table[i] && buf[i];
}
}
@ -3554,6 +3559,17 @@ rb_f_split(argc, argv)
}
static inline void
str_mod_check(s, p, len)
VALUE s;
char *p;
long len;
{
if (RSTRING(s)->ptr != p || RSTRING(s)->len != len) {
rb_raise(rb_eRuntimeError, "string modified");
}
}
/*
* call-seq:
* str.each(separator=$/) {|substr| block } => str
@ -3628,8 +3644,7 @@ rb_str_each_line(argc, argv, str)
line = rb_str_new5(str, s, p - s);
OBJ_INFECT(line, str);
rb_yield(line);
if (RSTRING(str)->ptr != ptr || RSTRING(str)->len != len)
rb_raise(rb_eArgError, "string modified");
str_mod_check(str, ptr, len);
s = p;
}
}
@ -3799,11 +3814,13 @@ rb_str_chomp_bang(argc, argv, str)
{
VALUE rs;
int newline;
char *p = RSTRING(str)->ptr;
long len = RSTRING(str)->len, rslen;
char *p;
long len, rslen;
if (rb_scan_args(argc, argv, "01", &rs) == 0) {
len = RSTRING(str)->len;
if (len == 0) return Qnil;
p = RSTRING(str)->ptr;
rs = rb_rs;
if (rs == rb_default_rs) {
smart_chomp:
@ -3827,9 +3844,10 @@ rb_str_chomp_bang(argc, argv, str)
}
}
if (NIL_P(rs)) return Qnil;
if (len == 0) return Qnil;
StringValue(rs);
len = RSTRING(str)->len;
if (len == 0) return Qnil;
p = RSTRING(str)->ptr;
rslen = RSTRING(rs)->len;
if (rslen == 0) {
while (len>0 && p[len-1] == '\n') {
@ -4277,7 +4295,7 @@ rb_str_crypt(str, salt)
{
extern char *crypt();
VALUE result;
char *s;
char *s, *cr;
StringValue(salt);
if (RSTRING(salt)->len < 2)
@ -4285,7 +4303,10 @@ rb_str_crypt(str, salt)
if (RSTRING(str)->ptr) s = RSTRING(str)->ptr;
else s = "";
result = rb_str_new2(crypt(s, RSTRING(salt)->ptr));
cr = crypt(s, RSTRING(salt)->ptr);
s = ALLOCA_N(char, strlen(cr));
strcpy(s, cr);
result = rb_str_new2(s);
OBJ_INFECT(result, str);
OBJ_INFECT(result, salt);
return result;
@ -4348,14 +4369,17 @@ rb_str_sum(argc, argv, str)
{
VALUE vbits;
int bits;
char *p, *pend;
char *ptr, *p, *pend;
long len;
if (rb_scan_args(argc, argv, "01", &vbits) == 0) {
bits = 16;
}
else bits = NUM2INT(vbits);
p = RSTRING(str)->ptr; pend = p + RSTRING(str)->len;
ptr = p = RSTRING(str)->ptr;
len = RSTRING(str)->len;
pend = p + len;
if (bits > sizeof(long)*CHAR_BIT) {
VALUE res = INT2FIX(0);
VALUE mod;
@ -4364,6 +4388,7 @@ rb_str_sum(argc, argv, str)
mod = rb_funcall(mod, '-', 1, INT2FIX(1));
while (p < pend) {
str_mod_check(str, ptr, len);
res = rb_funcall(res, '+', 1, INT2FIX((unsigned int)*p));
p++;
}
@ -4378,6 +4403,7 @@ rb_str_sum(argc, argv, str)
mod = -1;
}
while (p < pend) {
str_mod_check(str, ptr, len);
res += (unsigned int)*p;
p++;
}

123
struct.c
View file

@ -34,18 +34,43 @@ rb_struct_iv_get(c, name)
}
static VALUE
rb_struct_s_members(obj)
VALUE obj;
struct_s_members(klass)
VALUE klass;
{
VALUE member, ary;
VALUE members = rb_struct_iv_get(klass, "__members__");
if (NIL_P(members)) {
rb_bug("non-initialized struct");
}
return members;
}
static VALUE
struct_members(s)
VALUE s;
{
VALUE members = struct_s_members(rb_obj_class(s));
if (NIL_P(members)) {
rb_bug("non-initialized struct");
}
if (RSTRUCT(s)->len != RARRAY(members)->len) {
rb_raise(rb_eTypeError, "struct size differs (%d required %d given)",
RARRAY(members)->len, RSTRUCT(s)->len);
}
return members;
}
static VALUE
rb_struct_s_members(klass)
VALUE klass;
{
VALUE members, ary;
VALUE *p, *pend;
member = rb_struct_iv_get(obj, "__member__");
if (NIL_P(member)) {
rb_bug("uninitialized struct");
}
ary = rb_ary_new2(RARRAY(member)->len);
p = RARRAY(member)->ptr; pend = p + RARRAY(member)->len;
members = struct_s_members(klass);
ary = rb_ary_new2(RARRAY(members)->len);
p = RARRAY(members)->ptr; pend = p + RARRAY(members)->len;
while (p < pend) {
rb_ary_push(ary, rb_str_new2(rb_id2name(SYM2ID(*p))));
p++;
@ -78,16 +103,16 @@ rb_struct_getmember(obj, id)
VALUE obj;
ID id;
{
VALUE member, slot;
VALUE members, slot;
long i;
member = rb_struct_iv_get(rb_obj_class(obj), "__member__");
if (NIL_P(member)) {
members = rb_struct_iv_get(rb_obj_class(obj), "__members__");
if (NIL_P(members)) {
rb_bug("uninitialized struct");
}
slot = ID2SYM(id);
for (i=0; i<RARRAY(member)->len; i++) {
if (RARRAY(member)->ptr[i] == slot) {
for (i=0; i<RARRAY(members)->len; i++) {
if (RARRAY(members)->ptr[i] == slot) {
return RSTRUCT(obj)->ptr[i];
}
}
@ -139,16 +164,16 @@ static VALUE
rb_struct_set(obj, val)
VALUE obj, val;
{
VALUE member, slot;
VALUE members, slot;
long i;
member = rb_struct_iv_get(rb_obj_class(obj), "__member__");
if (NIL_P(member)) {
members = rb_struct_iv_get(rb_obj_class(obj), "__members__");
if (NIL_P(members)) {
rb_bug("uninitialized struct");
}
rb_struct_modify(obj);
for (i=0; i<RARRAY(member)->len; i++) {
slot = RARRAY(member)->ptr[i];
for (i=0; i<RARRAY(members)->len; i++) {
slot = RARRAY(members)->ptr[i];
if (rb_id_attrset(SYM2ID(slot)) == rb_frame_last_func()) {
return RSTRUCT(obj)->ptr[i] = val;
}
@ -159,13 +184,14 @@ rb_struct_set(obj, val)
}
static VALUE
make_struct(name, member, klass)
VALUE name, member, klass;
make_struct(name, members, klass)
VALUE name, members, klass;
{
VALUE nstr;
ID id;
long i;
OBJ_FREEZE(members);
if (NIL_P(name)) {
nstr = rb_class_new(klass);
rb_make_metaclass(nstr, RBASIC(klass)->klass);
@ -183,15 +209,15 @@ make_struct(name, member, klass)
}
nstr = rb_define_class_under(klass, cname, klass);
}
rb_iv_set(nstr, "__size__", LONG2NUM(RARRAY(member)->len));
rb_iv_set(nstr, "__member__", member);
rb_iv_set(nstr, "__size__", LONG2NUM(RARRAY(members)->len));
rb_iv_set(nstr, "__members__", members);
rb_define_alloc_func(nstr, struct_alloc);
rb_define_singleton_method(nstr, "new", rb_class_new_instance, -1);
rb_define_singleton_method(nstr, "[]", rb_class_new_instance, -1);
rb_define_singleton_method(nstr, "members", rb_struct_s_members, 0);
for (i=0; i< RARRAY(member)->len; i++) {
ID id = SYM2ID(RARRAY(member)->ptr[i]);
for (i=0; i< RARRAY(members)->len; i++) {
ID id = SYM2ID(RARRAY(members)->ptr[i]);
if (i<10) {
rb_define_method_id(nstr, id, ref_func[i], 0);
}
@ -427,15 +453,12 @@ static VALUE
rb_struct_each_pair(s)
VALUE s;
{
VALUE member;
VALUE members;
long i;
member = rb_struct_iv_get(rb_obj_class(s), "__member__");
if (NIL_P(member)) {
rb_bug("non-initialized struct");
}
members = struct_members(s);
for (i=0; i<RSTRUCT(s)->len; i++) {
rb_yield_values(2, RARRAY(member)->ptr[i], RSTRUCT(s)->ptr[i]);
rb_yield_values(2, rb_ary_entry(members, i), RSTRUCT(s)->ptr[i]);
}
return s;
}
@ -445,14 +468,10 @@ inspect_struct(s)
VALUE s;
{
char *cname = rb_class2name(rb_obj_class(s));
VALUE str, member;
VALUE str, members;
long i;
member = rb_struct_iv_get(rb_obj_class(s), "__member__");
if (NIL_P(member)) {
rb_bug("non-initialized struct");
}
members = struct_members(s);
str = rb_str_buf_new2("#<struct ");
rb_str_cat2(str, cname);
rb_str_cat2(str, " ");
@ -463,7 +482,7 @@ inspect_struct(s)
if (i > 0) {
rb_str_cat2(str, ", ");
}
slot = RARRAY(member)->ptr[i];
slot = RARRAY(members)->ptr[i];
p = rb_id2name(SYM2ID(slot));
rb_str_cat2(str, p);
rb_str_cat2(str, "=");
@ -539,17 +558,13 @@ rb_struct_aref_id(s, id)
VALUE s;
ID id;
{
VALUE member;
VALUE members;
long i, len;
member = rb_struct_iv_get(rb_obj_class(s), "__member__");
if (NIL_P(member)) {
rb_bug("non-initialized struct");
}
len = RARRAY(member)->len;
members = struct_members(s);
len = RARRAY(members)->len;
for (i=0; i<len; i++) {
if (SYM2ID(RARRAY(member)->ptr[i]) == id) {
if (SYM2ID(RARRAY(members)->ptr[i]) == id) {
return RSTRUCT(s)->ptr[i];
}
}
@ -602,18 +617,18 @@ rb_struct_aset_id(s, id, val)
VALUE s, val;
ID id;
{
VALUE member;
VALUE members;
long i, len;
member = rb_struct_iv_get(rb_obj_class(s), "__member__");
if (NIL_P(member)) {
rb_bug("non-initialized struct");
}
members = struct_members(s);
rb_struct_modify(s);
len = RARRAY(member)->len;
len = RARRAY(members)->len;
if (RSTRUCT(s)->len != RARRAY(members)->len) {
rb_raise(rb_eTypeError, "struct size differs (%d required %d given)",
RARRAY(members)->len, RSTRUCT(s)->len);
}
for (i=0; i<len; i++) {
if (SYM2ID(RARRAY(member)->ptr[i]) == id) {
if (SYM2ID(RARRAY(members)->ptr[i]) == id) {
RSTRUCT(s)->ptr[i] = val;
return val;
}

View file

@ -98,7 +98,7 @@ fc_i(key, value, res)
arg.klass = res->klass;
arg.track = value;
arg.prev = res;
st_foreach(RCLASS(value)->iv_tbl, fc_i, (st_data_t)&arg);
st_foreach_safe(RCLASS(value)->iv_tbl, fc_i, (st_data_t)&arg);
if (arg.path) {
res->path = arg.path;
return ST_STOP;
@ -124,7 +124,7 @@ find_class_path(klass)
arg.track = rb_cObject;
arg.prev = 0;
if (RCLASS(rb_cObject)->iv_tbl) {
st_foreach(RCLASS(rb_cObject)->iv_tbl, fc_i, (st_data_t)&arg);
st_foreach_safe(RCLASS(rb_cObject)->iv_tbl, fc_i, (st_data_t)&arg);
}
if (arg.path == 0) {
st_foreach(rb_class_tbl, fc_i, (st_data_t)&arg);
@ -958,7 +958,7 @@ rb_mark_generic_ivar_tbl()
{
if (!generic_iv_tbl) return;
if (special_generic_ivar == 0) return;
st_foreach(generic_iv_tbl, givar_i, 0);
st_foreach_safe(generic_iv_tbl, givar_i, 0);
}
void
@ -1118,7 +1118,7 @@ rb_obj_instance_variables(obj)
case T_CLASS:
case T_MODULE:
if (ROBJECT(obj)->iv_tbl) {
st_foreach(ROBJECT(obj)->iv_tbl, ivar_i, ary);
st_foreach_safe(ROBJECT(obj)->iv_tbl, ivar_i, ary);
}
break;
default:
@ -1127,7 +1127,7 @@ rb_obj_instance_variables(obj)
st_table *tbl;
if (st_lookup(generic_iv_tbl, obj, (st_data_t *)&tbl)) {
st_foreach(tbl, ivar_i, ary);
st_foreach_safe(tbl, ivar_i, ary);
}
}
break;
@ -1511,7 +1511,7 @@ rb_mod_const_at(mod, data)
tbl = st_init_numtable();
}
if (RCLASS(mod)->iv_tbl) {
st_foreach(RCLASS(mod)->iv_tbl, sv_i, (st_data_t)tbl);
st_foreach_safe(RCLASS(mod)->iv_tbl, sv_i, (st_data_t)tbl);
}
return tbl;
}
@ -1875,7 +1875,7 @@ rb_mod_class_variables(obj)
for (;;) {
if (RCLASS(obj)->iv_tbl) {
st_foreach(RCLASS(obj)->iv_tbl, cv_i, ary);
st_foreach_safe(RCLASS(obj)->iv_tbl, cv_i, ary);
}
obj = RCLASS(obj)->super;
if (!obj) break;