mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* 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:
		
							parent
							
								
									8e292f6285
								
							
						
					
					
						commit
						1b4d97ddba
					
				
					 9 changed files with 84 additions and 39 deletions
				
			
		
							
								
								
									
										24
									
								
								ChangeLog
									
										
									
									
									
								
							
							
						
						
									
										24
									
								
								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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										25
									
								
								enum.c
									
										
									
									
									
								
							
							
						
						
									
										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
									
										
									
									
									
								
							
							
						
						
									
										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
									
										
									
									
									
								
							
							
						
						
									
										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
									
										
									
									
									
								
							
							
						
						
									
										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
									
										
									
									
									
								
							
							
						
						
									
										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
									
										
									
									
									
								
							
							
						
						
									
										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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										34
									
								
								string.c
									
										
									
									
									
								
							
							
						
						
									
										34
									
								
								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++;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue