From: nobu.nakada@... Date: 2003-06-23T14:35:28+09:00 Subject: [ruby-dev:20412] Re: In 1.8.0 nil.to_s is not the same as "" なかだです。 At Mon, 23 Jun 2003 08:59:26 +0900, Yukihiro Matsumoto wrote: > |Well, all I found are attached. > | > |Not only NULL pointer access, contains fixes for: > |* possible buffer overrun > |* File.readlink truncated long symbolic link > |* String#reverse! always returned self > > Incredible speed. After my change to use constant empty string, some > of your fix is not needed. I will apply required fix. Thank you. 作り直しました。関係なくなってるので、スレッド切ってついでに(説 明がめんどくさいので)devへ。 * dir.c (find_dirsep): get rid of warnings. qualifierを無視してるといって警告を出すコンパイラがあります。 gcc3だったかな? * eval.c (error_print): temporary value might be disposed by GC. 一応念のため。 * eval.c (error_print): did not insert exception class path properly when message had \0. $ ./ruby -e 'class Eptr; elen = RSTRING(e)->len; @@ -1095,5 +1095,5 @@ error_print() if (RSTRING(epath)->ptr[0] == '#') epath = 0; - if (tail = strchr(einfo, '\n')) { + if (tail = memchr(einfo, '\n', elen)) { len = tail - einfo; tail++; /* skip newline */ Index: file.c =================================================================== RCS file: /cvs/ruby/src/ruby/file.c,v retrieving revision 1.147 diff -u -2 -p -r1.147 file.c --- file.c 20 Jun 2003 07:11:40 -0000 1.147 +++ file.c 22 Jun 2003 20:50:28 -0000 @@ -1276,5 +1276,5 @@ rb_file_s_readlink(klass, path) SafeStringValue(path); buf = xmalloc(size); - if ((rv = readlink(RSTRING(path)->ptr, buf, size)) == size) { + while ((rv = readlink(RSTRING(path)->ptr, buf, size)) == size) { size *= 2; buf = xrealloc(buf, size); Index: hash.c =================================================================== RCS file: /cvs/ruby/src/ruby/hash.c,v retrieving revision 1.109 diff -u -2 -p -r1.109 hash.c --- hash.c 20 Jun 2003 06:22:50 -0000 1.109 +++ hash.c 22 Jun 2003 20:51:53 -0000 @@ -1583,6 +1583,6 @@ env_has_value(dmy, value) env = GET_ENVIRON(environ); while (*env) { - char *s = strchr(*env, '=')+1; - if (s) { + char *s = strchr(*env, '='); + if (s++) { #ifdef ENV_IGNORECASE if (strncasecmp(s, RSTRING(value)->ptr, strlen(s)) == 0) { @@ -1610,6 +1610,6 @@ env_index(dmy, value) env = GET_ENVIRON(environ); while (*env) { - char *s = strchr(*env, '=')+1; - if (s) { + char *s = strchr(*env, '='); + if (s++) { #ifdef ENV_IGNORECASE if (strncasecmp(s, RSTRING(value)->ptr, strlen(s)) == 0) { Index: io.c =================================================================== RCS file: /cvs/ruby/src/ruby/io.c,v retrieving revision 1.213 diff -u -2 -p -r1.213 io.c --- io.c 7 Jun 2003 15:33:40 -0000 1.213 +++ io.c 22 Jun 2003 20:58:00 -0000 @@ -824,5 +824,4 @@ io_read(argc, argv, io) if (NIL_P(str)) { str = rb_str_new(0, len); - if (len == 0) return str; } else { @@ -831,4 +830,5 @@ io_read(argc, argv, io) rb_str_resize(str,len); } + if (len == 0) return str; READ_CHECK(fptr->f); @@ -1574,4 +1574,5 @@ rb_io_sysread(argc, argv, io) rb_str_resize(str, ilen); } + if (ilen == 0) return str; n = fileno(fptr->f); @@ -2273,5 +2236,6 @@ rb_io_s_sysopen(argc, argv) else if (FIXNUM_P(vmode)) flags = NUM2INT(vmode); else { - flags = rb_io_mode_modenum(StringValuePtr(vmode)); + SafeStringValue(vmode); + flags = rb_io_mode_modenum(RSTRING(vmode)->ptr); } if (NIL_P(perm)) fmode = 0666; @@ -2433,4 +2397,7 @@ rb_io_reopen(argc, argv, file) rb_io_taint_check(file); fptr = RFILE(file)->fptr; + if (!fptr) { + fptr = RFILE(file)->fptr = ALLOC(OpenFile); + } if (!NIL_P(nmode)) { @@ -2491,8 +2458,12 @@ rb_io_init_copy(dest, io) if (orig->f2) { io_fflush(orig->f2, orig); + fseeko(orig->f, 0L, SEEK_CUR); } else if (orig->mode & FMODE_WRITABLE) { io_fflush(orig->f, orig); } + else { + fseeko(orig->f, 0L, SEEK_CUR); + } /* copy OpenFile structure */ @@ -3517,10 +3496,19 @@ rb_f_syscall(argc, argv) } +static VALUE io_new_instance _((VALUE)); +static VALUE +io_new_instance(args) + VALUE args; +{ + return rb_class_new_instance(2, (VALUE*)args+1, *(VALUE*)args); +} + static VALUE -rb_io_s_pipe() +rb_io_s_pipe(klass) + VALUE klass; { #ifndef __human68k__ - int pipes[2]; - VALUE r, w; + int pipes[2], state; + VALUE r, w, args[3]; #ifdef _WIN32 @@ -3531,6 +3519,22 @@ rb_io_s_pipe() rb_sys_fail(0); - r = prep_stdio(rb_fdopen(pipes[0], "r"), FMODE_READABLE, rb_cIO); - w = prep_stdio(rb_fdopen(pipes[1], "w"), FMODE_WRITABLE|FMODE_SYNC, rb_cIO); + args[0] = klass; + args[1] = INT2NUM(pipes[0]); + args[2] = INT2FIX(O_RDONLY); + r = rb_protect(io_new_instance, (VALUE)args, &state); + if (state) { + close(pipes[0]); + close(pipes[1]); + rb_jump_tag(state); + } + args[1] = INT2NUM(pipes[1]); + args[2] = INT2FIX(O_WRONLY); + w = rb_protect(io_new_instance, (VALUE)args, &state); + if (state) { + close(pipes[1]); + if (!NIL_P(r)) rb_io_close(r); + rb_jump_tag(state); + } + rb_io_synchronized(RFILE(w)->fptr); return rb_assoc_new(r, w); Index: pack.c =================================================================== RCS file: /cvs/ruby/src/ruby/pack.c,v retrieving revision 1.53 diff -u -2 -p -r1.53 pack.c --- pack.c 23 May 2003 06:16:20 -0000 1.53 +++ pack.c 22 Jun 2003 21:19:48 -0000 @@ -1678,4 +1678,6 @@ pack_unpack(str, fmt) case '@': + if (len > RSTRING(str)->len) + rb_raise(rb_eArgError, "@ outside of string"); s = RSTRING(str)->ptr + len; break; Index: string.c =================================================================== RCS file: /cvs/ruby/src/ruby/string.c,v retrieving revision 1.156 diff -u -2 -p -r1.156 string.c --- string.c 26 May 2003 08:22:28 -0000 1.156 +++ string.c 22 Jun 2003 21:07:30 -0000 @@ -1003,7 +994,6 @@ rb_str_rindex_m(argc, argv, str) char *pbeg = RSTRING(str)->ptr; - while (pbeg <= p) { + while (pbeg <= --p) { if (*p == c) return LONG2NUM(p - RSTRING(str)->ptr); - p--; } return Qnil; -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦