* 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/trunk@6976 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2004-10-01 15:56:05 +00:00
Родитель 8e292f6285
Коммит 1b4d97ddba
9 изменённых файлов: 84 добавлений и 39 удалений

Просмотреть файл

@ -1,3 +1,27 @@
Sat Oct 2 00:42:20 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* 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

25
enum.c
Просмотреть файл

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

3
eval.c
Просмотреть файл

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

11
file.c
Просмотреть файл

@ -1729,8 +1729,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);
@ -2654,11 +2653,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))
@ -2674,7 +2673,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;
}
@ -2682,7 +2681,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;
}
}

14
gc.c
Просмотреть файл

@ -92,7 +92,7 @@ static unsigned long malloc_increase = 0;
static unsigned long malloc_limit = GC_MALLOC_LIMIT;
static void run_final();
static VALUE nomem_error;
static void gc_internal();
static void garbage_collect();
void
rb_memerror()
@ -120,11 +120,11 @@ ruby_xmalloc(size)
malloc_increase += size;
if (malloc_increase > malloc_limit) {
gc_internal();
garbage_collect();
}
RUBY_CRITICAL(mem = malloc(size));
if (!mem) {
gc_internal();
garbage_collect();
RUBY_CRITICAL(mem = malloc(size));
if (!mem) {
rb_memerror();
@ -161,7 +161,7 @@ ruby_xrealloc(ptr, size)
malloc_increase += size;
RUBY_CRITICAL(mem = realloc(ptr, size));
if (!mem) {
gc_internal();
garbage_collect();
RUBY_CRITICAL(mem = realloc(ptr, size));
if (!mem) {
rb_memerror();
@ -381,7 +381,7 @@ rb_newobj()
{
VALUE obj;
if (!freelist) gc_internal();
if (!freelist) garbage_collect();
obj = (VALUE)freelist;
freelist = freelist->as.free.next;
@ -1288,7 +1288,7 @@ int rb_setjmp (rb_jmp_buf);
#endif /* __GNUC__ */
static void
gc_internal()
garbage_collect()
{
struct gc_list *list;
struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug?? */
@ -1403,7 +1403,7 @@ gc_internal()
void
rb_gc()
{
gc_internal();
garbage_collect();
rb_gc_finalize_deferred();
}

6
io.c
Просмотреть файл

@ -1194,11 +1194,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;
@ -2972,7 +2974,9 @@ rb_io_s_popen(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;
}
tmp = rb_check_array_type(pname);
if (!NIL_P(tmp)) {

Просмотреть файл

@ -1207,8 +1207,8 @@ rb_check_argv(argc, argv)
rb_raise(rb_eArgError, "wrong first argument");
}
prog = RARRAY(tmp)->ptr[0];
SafeStringValue(prog);
argv[0] = RARRAY(tmp)->ptr[1];
SafeStringValue(prog);
}
for (i = 0; i < argc; i++) {
SafeStringValue(argv[i]);

4
re.c
Просмотреть файл

@ -1722,8 +1722,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;
@ -1749,6 +1747,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;

Просмотреть файл

@ -3139,7 +3139,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];
}
}
@ -3598,6 +3598,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
@ -3672,8 +3683,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;
}
}
@ -3843,11 +3853,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:
@ -3871,9 +3883,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') {
@ -4393,13 +4406,16 @@ rb_str_sum(argc, argv, str)
VALUE vbits;
int bits;
char *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;
p = RSTRING(str)->ptr;
len = RSTRING(str)->len;
pend = p + len;
if (bits > sizeof(long)*CHAR_BIT) {
VALUE res = INT2FIX(0);
VALUE mod;
@ -4408,6 +4424,7 @@ rb_str_sum(argc, argv, str)
mod = rb_funcall(mod, '-', 1, INT2FIX(1));
while (p < pend) {
str_mod_check(str, p, len);
res = rb_funcall(res, '+', 1, INT2FIX((unsigned int)*p));
p++;
}
@ -4422,6 +4439,7 @@ rb_str_sum(argc, argv, str)
mod = -1;
}
while (p < pend) {
str_mod_check(str, p, len);
res += (unsigned int)*p;
p++;
}