diff --git a/.cvsignore b/.cvsignore index 237576f..bcd6a57 100644 --- a/.cvsignore +++ b/.cvsignore @@ -2,3 +2,4 @@ ruby-1.8.6-p388.tar.bz2 ruby-refm-rdp-1.8.2-ja-html.tar.gz rubyfaq-990927.tar.gz rubyfaq-jp-990927.tar.gz +ruby-1.8.6-p399.tar.bz2 diff --git a/ruby.spec b/ruby.spec index 8fb0abf..1fa8ccb 100644 --- a/ruby.spec +++ b/ruby.spec @@ -1,6 +1,6 @@ %define rubyxver 1.8 %define rubyver 1.8.6 -%define _patchlevel 388 +%define _patchlevel 399 %define dotpatchlevel %{?_patchlevel:.%{_patchlevel}} %define patchlevel %{?_patchlevel:-p%{_patchlevel}} %define arcver %{rubyver}%{?patchlevel} @@ -16,7 +16,7 @@ Name: ruby Version: %{rubyver}%{?dotpatchlevel} -Release: 9%{?dist} +Release: 1%{?dist} License: Ruby or GPLv2 URL: http://www.ruby-lang.org/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -57,7 +57,10 @@ Patch31: ruby-1.8.6-p369-ri-gem_multipath.patch Patch32: ruby-1.8head-irb-save-history.patch Patch33: ruby-1.8.6-p383-mkmf-use-shared.patch # Testing -Patch34: ruby-1.8.6-simplify-openssl-digest.patch +# Patch34 disabled for now +Patch34: ruby-1.8.6-simplify-openssl-digest.patch +# bz 580993 +Patch35: ruby_1_8_7-gc-open4_096segv.patch Summary: An interpreter of object-oriented scripting language Group: Development/Languages @@ -199,9 +202,9 @@ pushd %{name}-%{arcver} %patch31 -p1 %patch32 -p0 %patch33 -p1 - # Once kill patch34 due to build failure on actionpack #%%patch34 -p1 +%patch35 -p1 popd %build @@ -577,6 +580,10 @@ rm -rf $RPM_BUILD_ROOT %{_emacs_sitestartdir}/ruby-mode-init.el %changelog +* Tue Apr 27 2010 Mamoru Tasaka - 1.8.6.399-1 +- Update to 1.8.6 p 399 (bug 579675) +- Patch to fix gc bug causing open4 crash (bug 580993) + * Fri Mar 12 2010 Mamoru Tasaka - 1.8.6.388-9 - F-14: rebuild against new gdbm diff --git a/ruby_1_8_7-gc-open4_096segv.patch b/ruby_1_8_7-gc-open4_096segv.patch new file mode 100644 index 0000000..4514022 --- /dev/null +++ b/ruby_1_8_7-gc-open4_096segv.patch @@ -0,0 +1,351 @@ +Index: ruby_1_8_7/marshal.c +=================================================================== +--- ruby_1_8_7/marshal.c (revision 26075) ++++ ruby_1_8_7/marshal.c (revision 26076) +@@ -85,12 +85,10 @@ + static ID s_getc, s_read, s_write, s_binmode; + + struct dump_arg { +- VALUE obj; + VALUE str, dest; + st_table *symbols; + st_table *data; + int taint; +- VALUE wrapper; + }; + + struct dump_call_arg { +@@ -104,22 +102,32 @@ + struct dump_arg *arg; + ID sym; + { +- if (!DATA_PTR(arg->wrapper)) { ++ if (!arg->symbols) { + rb_raise(rb_eRuntimeError, "Marshal.dump reentered at %s", + rb_id2name(sym)); + } + } + ++static void clear_dump_arg _((struct dump_arg *arg)); ++ + static void + mark_dump_arg(ptr) + void *ptr; + { + struct dump_arg *p = ptr; +- if (!ptr) ++ if (!p->symbols) + return; + rb_mark_set(p->data); + } + ++static void ++free_dump_arg(ptr) ++ void *ptr; ++{ ++ clear_dump_arg(ptr); ++ xfree(ptr); ++} ++ + static VALUE + class2path(klass) + VALUE klass; +@@ -699,32 +707,17 @@ + } + } + +-static VALUE +-dump(arg) +- struct dump_call_arg *arg; +-{ +- w_object(arg->obj, arg->arg, arg->limit); +- if (arg->arg->dest) { +- rb_io_write(arg->arg->dest, arg->arg->str); +- rb_str_resize(arg->arg->str, 0); +- } +- return 0; +-} +- +-static VALUE +-dump_ensure(arg) ++static void ++clear_dump_arg(arg) + struct dump_arg *arg; + { +- if (!DATA_PTR(arg->wrapper)) return 0; ++ if (!arg->symbols) return; + st_free_table(arg->symbols); ++ arg->symbols = 0; + st_free_table(arg->data); +- DATA_PTR(arg->wrapper) = 0; +- arg->wrapper = 0; + if (arg->taint) { + OBJ_TAINT(arg->str); + } +- +- return 0; + } + + /* +@@ -760,8 +753,8 @@ + { + VALUE obj, port, a1, a2; + int limit = -1; +- struct dump_arg arg; +- struct dump_call_arg c_arg; ++ struct dump_arg *arg; ++ VALUE wrapper; + + port = Qnil; + rb_scan_args(argc, argv, "12", &obj, &a1, &a2); +@@ -775,37 +768,40 @@ + else if (NIL_P(a1)) goto type_error; + else port = a1; + } +- arg.dest = 0; +- arg.symbols = st_init_numtable(); +- arg.data = st_init_numtable(); +- arg.taint = Qfalse; +- arg.str = rb_str_buf_new(0); +- RBASIC(arg.str)->klass = 0; +- arg.wrapper = Data_Wrap_Struct(rb_cData, mark_dump_arg, 0, &arg); ++ wrapper = Data_Make_Struct(rb_cData, struct dump_arg, mark_dump_arg, free_dump_arg, arg); ++ arg->dest = 0; ++ arg->symbols = st_init_numtable(); ++ arg->data = st_init_numtable(); ++ arg->taint = Qfalse; ++ arg->str = rb_str_buf_new(0); ++ RBASIC(arg->str)->klass = 0; + if (!NIL_P(port)) { + if (!rb_respond_to(port, s_write)) { + type_error: + rb_raise(rb_eTypeError, "instance of IO needed"); + } +- arg.dest = port; ++ arg->dest = port; + if (rb_respond_to(port, s_binmode)) { + rb_funcall2(port, s_binmode, 0, 0); +- check_dump_arg(&arg, s_binmode); ++ check_dump_arg(arg, s_binmode); + } + } + else { +- port = arg.str; ++ port = arg->str; + } + +- c_arg.obj = obj; +- c_arg.arg = &arg; +- c_arg.limit = limit; ++ w_byte(MARSHAL_MAJOR, arg); ++ w_byte(MARSHAL_MINOR, arg); + +- w_byte(MARSHAL_MAJOR, &arg); +- w_byte(MARSHAL_MINOR, &arg); ++ w_object(obj, arg, limit); ++ if (arg->dest) { ++ rb_io_write(arg->dest, arg->str); ++ rb_str_resize(arg->str, 0); ++ } + +- rb_ensure(dump, (VALUE)&c_arg, dump_ensure, (VALUE)&arg); +- RBASIC(arg.str)->klass = rb_cString; ++ RBASIC(arg->str)->klass = rb_cString; ++ clear_dump_arg(arg); ++ RB_GC_GUARD(wrapper); + + return port; + } +@@ -817,7 +813,6 @@ + st_table *data; + VALUE proc; + int taint; +- VALUE wrapper; + }; + + static void +@@ -825,22 +820,31 @@ + struct load_arg *arg; + ID sym; + { +- if (!DATA_PTR(arg->wrapper)) { ++ if (!arg->symbols) { + rb_raise(rb_eRuntimeError, "Marshal.load reentered at %s", + rb_id2name(sym)); + } + } + ++static void clear_load_arg _((struct load_arg *arg)); ++ + static void + mark_load_arg(ptr) + void *ptr; + { + struct load_arg *p = ptr; +- if (!ptr) ++ if (!p->symbols) + return; + rb_mark_tbl(p->data); + } + ++static void ++free_load_arg(void *ptr) ++{ ++ clear_load_arg(ptr); ++ xfree(ptr); ++} ++ + static VALUE r_object _((struct load_arg *arg)); + + static int +@@ -1415,23 +1419,14 @@ + return r_object0(arg, arg->proc, 0, Qnil); + } + +-static VALUE +-load(arg) ++static void ++clear_load_arg(arg) + struct load_arg *arg; + { +- return r_object(arg); +-} +- +-static VALUE +-load_ensure(arg) +- struct load_arg *arg; +-{ +- if (!DATA_PTR(arg->wrapper)) return 0; ++ if (!arg->symbols) return; + st_free_table(arg->symbols); ++ arg->symbols = 0; + st_free_table(arg->data); +- DATA_PTR(arg->wrapper) = 0; +- arg->wrapper = 0; +- return 0; + } + + /* +@@ -1451,35 +1446,37 @@ + VALUE *argv; + { + VALUE port, proc; +- int major, minor; +- VALUE v; +- struct load_arg arg; ++ int major, minor, taint = Qfalse; ++ VALUE v, wrapper; ++ struct load_arg *arg; + + rb_scan_args(argc, argv, "11", &port, &proc); + v = rb_check_string_type(port); + if (!NIL_P(v)) { +- arg.taint = OBJ_TAINTED(port); /* original taintedness */ ++ taint = OBJ_TAINTED(port); /* original taintedness */ + port = v; + } + else if (rb_respond_to(port, s_getc) && rb_respond_to(port, s_read)) { + if (rb_respond_to(port, s_binmode)) { + rb_funcall2(port, s_binmode, 0, 0); + } +- arg.taint = Qtrue; ++ taint = Qtrue; + } + else { + rb_raise(rb_eTypeError, "instance of IO needed"); + } +- arg.src = port; +- arg.offset = 0; +- arg.symbols = st_init_numtable(); +- arg.data = st_init_numtable(); +- arg.proc = 0; +- arg.wrapper = Data_Wrap_Struct(rb_cData, mark_load_arg, 0, &arg); ++ wrapper = Data_Make_Struct(rb_cData, struct load_arg, mark_load_arg, free_load_arg, arg); ++ arg->src = port; ++ arg->offset = 0; ++ arg->symbols = st_init_numtable(); ++ arg->data = st_init_numtable(); ++ arg->proc = 0; ++ arg->taint = taint; + +- major = r_byte(&arg); +- minor = r_byte(&arg); ++ major = r_byte(arg); ++ minor = r_byte(arg); + if (major != MARSHAL_MAJOR || minor > MARSHAL_MINOR) { ++ clear_load_arg(arg); + rb_raise(rb_eTypeError, "incompatible marshal file format (can't be read)\n\ + \tformat version %d.%d required; %d.%d given", + MARSHAL_MAJOR, MARSHAL_MINOR, major, minor); +@@ -1490,8 +1487,10 @@ + MARSHAL_MAJOR, MARSHAL_MINOR, major, minor); + } + +- if (!NIL_P(proc)) arg.proc = proc; +- v = rb_ensure(load, (VALUE)&arg, load_ensure, (VALUE)&arg); ++ if (!NIL_P(proc)) arg->proc = proc; ++ v = r_object(arg); ++ clear_load_arg(arg); ++ RB_GC_GUARD(wrapper); + + return v; + } +Index: ruby_1_8_7/test/ruby/test_marshal.rb +=================================================================== +--- ruby_1_8_7/test/ruby/test_marshal.rb (revision 26075) ++++ ruby_1_8_7/test/ruby/test_marshal.rb (revision 26076) +@@ -71,4 +71,41 @@ + } + assert_equal("marshal data too short", e.message) + end ++ ++ class DumpTest ++ def marshal_dump ++ loop { Thread.pass } ++ end ++ end ++ ++ class LoadTest ++ def marshal_dump ++ nil ++ end ++ def marshal_load(obj) ++ loop { Thread.pass } ++ end ++ end ++ ++ def test_context_switch ++ o = DumpTest.new ++ Thread.new { Marshal.dump(o) } ++ GC.start ++ assert(true, '[ruby-dev:39425]') ++ ++ o = LoadTest.new ++ m = Marshal.dump(o) ++ Thread.new { Marshal.load(m) } ++ GC.start ++ assert(true, '[ruby-dev:39425]') ++ end ++ ++ def test_taint ++ x = Object.new ++ x.taint ++ s = Marshal.dump(x) ++ assert_equal(true, s.tainted?) ++ y = Marshal.load(s) ++ assert_equal(true, y.tainted?) ++ end + end +Index: ruby_1_8_7/ruby.h +=================================================================== +--- ruby_1_8_7/ruby.h (revision 16014) ++++ ruby_1_8_7/ruby.h (revision 16015) +@@ -224,6 +224,8 @@ + + #define TYPE(x) rb_type((VALUE)(x)) + ++#define RB_GC_GUARD(v) (*(volatile VALUE *)&(v)) ++ + void rb_check_type _((VALUE,int)); + #define Check_Type(v,t) rb_check_type((VALUE)(v),t) + diff --git a/sources b/sources index 402aa20..4217687 100644 --- a/sources +++ b/sources @@ -2,3 +2,4 @@ f26cefbc8ab6728650ab9ae773d22bcb ruby-1.8.6-p388.tar.bz2 b6dd396f513efeb7864685c840f9643a ruby-refm-rdp-1.8.2-ja-html.tar.gz 634c25b14e19925d10af3720d72e8741 rubyfaq-990927.tar.gz 4fcec898f51d8371cc42d0a013940469 rubyfaq-jp-990927.tar.gz +f77c307cb72fb8808b0e85af5d05cefc ruby-1.8.6-p399.tar.bz2