* 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> Fri Oct 1 11:25:20 2004 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk/grid.rb: revive TkGrid.grid * ext/tk/lib/tk/grid.rb: revive TkGrid.grid

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

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

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

@ -6187,12 +6187,13 @@ rb_f_eval(argc, argv, self)
SafeStringValue(src); SafeStringValue(src);
} }
if (argc >= 3) { if (argc >= 3) {
file = StringValuePtr(vfile); StringValue(vfile);
} }
if (argc >= 4) { if (argc >= 4) {
line = NUM2INT(vline); line = NUM2INT(vline);
} }
if (!NIL_P(vfile)) file = RSTRING(vfile)->ptr;
if (NIL_P(scope) && ruby_frame->prev) { if (NIL_P(scope) && ruby_frame->prev) {
struct FRAME *prev; struct FRAME *prev;
VALUE val; VALUE val;

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

@ -1729,8 +1729,7 @@ rb_file_s_lchmod(argc, argv)
{ {
VALUE vmode; VALUE vmode;
VALUE rest; VALUE rest;
int mode; long mode, n;
long n;
rb_secure(2); rb_secure(2);
rb_scan_args(argc, argv, "1*", &vmode, &rest); rb_scan_args(argc, argv, "1*", &vmode, &rest);
@ -2654,11 +2653,11 @@ rb_file_s_basename(argc, argv)
VALUE *argv; VALUE *argv;
{ {
VALUE fname, fext, basename; VALUE fname, fext, basename;
char *name, *p, *ext = NULL; char *name, *p;
int f; int f;
if (rb_scan_args(argc, argv, "11", &fname, &fext) == 2) { if (rb_scan_args(argc, argv, "11", &fname, &fext) == 2) {
ext = StringValueCStr(fext); StringValue(fext);
} }
StringValue(fname); StringValue(fname);
if (RSTRING(fname)->len == 0 || !*(name = RSTRING(fname)->ptr)) if (RSTRING(fname)->len == 0 || !*(name = RSTRING(fname)->ptr))
@ -2674,7 +2673,7 @@ rb_file_s_basename(argc, argv)
#endif #endif
} }
else if (!(p = strrdirsep(name))) { 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; f = chompdirsep(name) - name;
if (f == RSTRING(fname)->len) return fname; if (f == RSTRING(fname)->len) return fname;
} }
@ -2682,7 +2681,7 @@ rb_file_s_basename(argc, argv)
} }
else { else {
while (isdirsep(*p)) p++; /* skip last / */ 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; 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 unsigned long malloc_limit = GC_MALLOC_LIMIT;
static void run_final(); static void run_final();
static VALUE nomem_error; static VALUE nomem_error;
static void gc_internal(); static void garbage_collect();
void void
rb_memerror() rb_memerror()
@ -120,11 +120,11 @@ ruby_xmalloc(size)
malloc_increase += size; malloc_increase += size;
if (malloc_increase > malloc_limit) { if (malloc_increase > malloc_limit) {
gc_internal(); garbage_collect();
} }
RUBY_CRITICAL(mem = malloc(size)); RUBY_CRITICAL(mem = malloc(size));
if (!mem) { if (!mem) {
gc_internal(); garbage_collect();
RUBY_CRITICAL(mem = malloc(size)); RUBY_CRITICAL(mem = malloc(size));
if (!mem) { if (!mem) {
rb_memerror(); rb_memerror();
@ -161,7 +161,7 @@ ruby_xrealloc(ptr, size)
malloc_increase += size; malloc_increase += size;
RUBY_CRITICAL(mem = realloc(ptr, size)); RUBY_CRITICAL(mem = realloc(ptr, size));
if (!mem) { if (!mem) {
gc_internal(); garbage_collect();
RUBY_CRITICAL(mem = realloc(ptr, size)); RUBY_CRITICAL(mem = realloc(ptr, size));
if (!mem) { if (!mem) {
rb_memerror(); rb_memerror();
@ -381,7 +381,7 @@ rb_newobj()
{ {
VALUE obj; VALUE obj;
if (!freelist) gc_internal(); if (!freelist) garbage_collect();
obj = (VALUE)freelist; obj = (VALUE)freelist;
freelist = freelist->as.free.next; freelist = freelist->as.free.next;
@ -1288,7 +1288,7 @@ int rb_setjmp (rb_jmp_buf);
#endif /* __GNUC__ */ #endif /* __GNUC__ */
static void static void
gc_internal() garbage_collect()
{ {
struct gc_list *list; struct gc_list *list;
struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug?? */ struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug?? */
@ -1403,7 +1403,7 @@ gc_internal()
void void
rb_gc() rb_gc()
{ {
gc_internal(); garbage_collect();
rb_gc_finalize_deferred(); rb_gc_finalize_deferred();
} }

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

@ -1194,11 +1194,13 @@ io_read(argc, argv, io)
StringValue(str); StringValue(str);
rb_str_modify(str); rb_str_modify(str);
rb_str_resize(str,len); rb_str_resize(str,len);
FL_SET(str, FL_FREEZE);
} }
if (len == 0) return str; if (len == 0) return str;
READ_CHECK(fptr->f); READ_CHECK(fptr->f);
n = rb_io_fread(RSTRING(str)->ptr, len, fptr->f); n = rb_io_fread(RSTRING(str)->ptr, len, fptr->f);
FL_UNSET(str, FL_FREEZE);
if (n == 0) { if (n == 0) {
rb_str_resize(str,0); rb_str_resize(str,0);
if (!fptr->f) return Qnil; if (!fptr->f) return Qnil;
@ -2972,7 +2974,9 @@ rb_io_s_popen(argc, argv, klass)
mode = rb_io_modenum_mode(FIX2INT(pmode), mbuf); mode = rb_io_modenum_mode(FIX2INT(pmode), mbuf);
} }
else { else {
mode = StringValuePtr(pmode); strncpy(mbuf, StringValuePtr(pmode), sizeof(mbuf) - 1);
mbuf[sizeof(mbuf) - 1] = 0;
mode = mbuf;
} }
tmp = rb_check_array_type(pname); tmp = rb_check_array_type(pname);
if (!NIL_P(tmp)) { if (!NIL_P(tmp)) {

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

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

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

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

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

@ -3139,7 +3139,7 @@ tr_setup_table(str, table, init)
buf[c & 0xff] = !cflag; buf[c & 0xff] = !cflag;
} }
for (i=0; i<256; i++) { 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: * call-seq:
* str.each(separator=$/) {|substr| block } => str * 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); line = rb_str_new5(str, s, p - s);
OBJ_INFECT(line, str); OBJ_INFECT(line, str);
rb_yield(line); rb_yield(line);
if (RSTRING(str)->ptr != ptr || RSTRING(str)->len != len) str_mod_check(str, ptr, len);
rb_raise(rb_eArgError, "string modified");
s = p; s = p;
} }
} }
@ -3843,11 +3853,13 @@ rb_str_chomp_bang(argc, argv, str)
{ {
VALUE rs; VALUE rs;
int newline; int newline;
char *p = RSTRING(str)->ptr; char *p;
long len = RSTRING(str)->len, rslen; long len, rslen;
if (rb_scan_args(argc, argv, "01", &rs) == 0) { if (rb_scan_args(argc, argv, "01", &rs) == 0) {
len = RSTRING(str)->len;
if (len == 0) return Qnil; if (len == 0) return Qnil;
p = RSTRING(str)->ptr;
rs = rb_rs; rs = rb_rs;
if (rs == rb_default_rs) { if (rs == rb_default_rs) {
smart_chomp: smart_chomp:
@ -3871,9 +3883,10 @@ rb_str_chomp_bang(argc, argv, str)
} }
} }
if (NIL_P(rs)) return Qnil; if (NIL_P(rs)) return Qnil;
if (len == 0) return Qnil;
StringValue(rs); StringValue(rs);
len = RSTRING(str)->len;
if (len == 0) return Qnil;
p = RSTRING(str)->ptr;
rslen = RSTRING(rs)->len; rslen = RSTRING(rs)->len;
if (rslen == 0) { if (rslen == 0) {
while (len>0 && p[len-1] == '\n') { while (len>0 && p[len-1] == '\n') {
@ -4393,13 +4406,16 @@ rb_str_sum(argc, argv, str)
VALUE vbits; VALUE vbits;
int bits; int bits;
char *p, *pend; char *p, *pend;
long len;
if (rb_scan_args(argc, argv, "01", &vbits) == 0) { if (rb_scan_args(argc, argv, "01", &vbits) == 0) {
bits = 16; bits = 16;
} }
else bits = NUM2INT(vbits); 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) { if (bits > sizeof(long)*CHAR_BIT) {
VALUE res = INT2FIX(0); VALUE res = INT2FIX(0);
VALUE mod; VALUE mod;
@ -4408,6 +4424,7 @@ rb_str_sum(argc, argv, str)
mod = rb_funcall(mod, '-', 1, INT2FIX(1)); mod = rb_funcall(mod, '-', 1, INT2FIX(1));
while (p < pend) { while (p < pend) {
str_mod_check(str, p, len);
res = rb_funcall(res, '+', 1, INT2FIX((unsigned int)*p)); res = rb_funcall(res, '+', 1, INT2FIX((unsigned int)*p));
p++; p++;
} }
@ -4422,6 +4439,7 @@ rb_str_sum(argc, argv, str)
mod = -1; mod = -1;
} }
while (p < pend) { while (p < pend) {
str_mod_check(str, p, len);
res += (unsigned int)*p; res += (unsigned int)*p;
p++; p++;
} }