aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog24
-rw-r--r--enum.c25
-rw-r--r--eval.c3
-rw-r--r--file.c11
-rw-r--r--gc.c14
-rw-r--r--io.c6
-rw-r--r--process.c2
-rw-r--r--re.c4
-rw-r--r--string.c34
9 files changed, 84 insertions, 39 deletions
diff --git a/ChangeLog b/ChangeLog
index 9d8b6a7a4e..5f4e1b6d8d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/enum.c b/enum.c
index eee0e04291..b5de2a3fc2 100644
--- a/enum.c
+++ b/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;
}
diff --git a/eval.c b/eval.c
index b074ecb0c7..76726f012f 100644
--- a/eval.c
+++ b/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;
diff --git a/file.c b/file.c
index 578274c6ce..36cb34a8cc 100644
--- a/file.c
+++ b/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;
}
}
diff --git a/gc.c b/gc.c
index fba3ee8fba..d3a7b477fc 100644
--- a/gc.c
+++ b/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();
}
diff --git a/io.c b/io.c
index ccd019f4f1..71273ed0b6 100644
--- a/io.c
+++ b/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)) {
diff --git a/process.c b/process.c
index b7be36fbf7..c806250810 100644
--- a/process.c
+++ b/process.c
@@ -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]);
diff --git a/re.c b/re.c
index 8fbd3b568a..ee5433015f 100644
--- a/re.c
+++ b/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;
diff --git a/string.c b/string.c
index 933c233a53..6f52434181 100644
--- a/string.c
+++ b/string.c
@@ -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++;
}