From 889c289308d269f333481e061e95f791a4afb1b0 Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Tue, 10 Jul 2007 15:04:49 +0000 Subject: [PATCH] - Add a bunch of fixes and patchs from the upstream. These fixes a lot of serious bugs, some of which can pose security-related problems. - Bump up PORTREVISION. Requested by: many --- Mk/bsd.ruby.mk | 2 +- lang/ruby18/Makefile | 3 +- lang/ruby18/files/patch-bignum.c | 111 +++++++ lang/ruby18/files/patch-dir.c | 41 +++ lang/ruby18/files/patch-eval.c | 270 ++++++++++++++++++ .../files/patch-ext_bigdecimal_bigdecimal.c | 11 + lang/ruby18/files/patch-ext_dl_dl.c | 11 + lang/ruby18/files/patch-ext_etc_etc.c | 11 + lang/ruby18/files/patch-ext_thread_thread.c | 270 ++++++++++++++++++ ...ch-ext_tk_lib_tkextlib_tcllib_tablelist.rb | 9 + .../patch-ext_tk_lib_tkextlib_tile_dialog.rb | 11 + lang/ruby18/files/patch-intern.h | 16 ++ lang/ruby18/files/patch-lib_cgi.rb | 10 + lang/ruby18/files/patch-lib_monitor.rb | 46 +++ lang/ruby18/files/patch-lib_net_imap.rb | 15 + lang/ruby18/files/patch-process.c | 10 + lang/ruby18/files/patch-util.c | 13 + 17 files changed, 858 insertions(+), 2 deletions(-) create mode 100644 lang/ruby18/files/patch-bignum.c create mode 100644 lang/ruby18/files/patch-dir.c create mode 100644 lang/ruby18/files/patch-eval.c create mode 100644 lang/ruby18/files/patch-ext_bigdecimal_bigdecimal.c create mode 100644 lang/ruby18/files/patch-ext_dl_dl.c create mode 100644 lang/ruby18/files/patch-ext_etc_etc.c create mode 100644 lang/ruby18/files/patch-ext_thread_thread.c create mode 100644 lang/ruby18/files/patch-ext_tk_lib_tkextlib_tcllib_tablelist.rb create mode 100644 lang/ruby18/files/patch-ext_tk_lib_tkextlib_tile_dialog.rb create mode 100644 lang/ruby18/files/patch-intern.h create mode 100644 lang/ruby18/files/patch-lib_cgi.rb create mode 100644 lang/ruby18/files/patch-lib_monitor.rb create mode 100644 lang/ruby18/files/patch-lib_net_imap.rb create mode 100644 lang/ruby18/files/patch-process.c create mode 100644 lang/ruby18/files/patch-util.c diff --git a/Mk/bsd.ruby.mk b/Mk/bsd.ruby.mk index ce66f27f02ae..3a29cc4fe6a6 100644 --- a/Mk/bsd.ruby.mk +++ b/Mk/bsd.ruby.mk @@ -162,7 +162,7 @@ RUBY?= ${LOCALBASE}/bin/${RUBY_NAME} .if defined(RUBY_VER) && ${RUBY_VER} == 1.8 RUBY_RELVERSION= 1.8.6 -RUBY_PORTREVISION= 0 +RUBY_PORTREVISION= 1 RUBY_PORTEPOCH= 1 RUBY_PATCHLEVEL= 0 diff --git a/lang/ruby18/Makefile b/lang/ruby18/Makefile index ca53811b4cff..444c5b3da839 100644 --- a/lang/ruby18/Makefile +++ b/lang/ruby18/Makefile @@ -44,8 +44,9 @@ OPTIONS= PTHREADS "Enable pthreads support (may break some apps)" off \ .include -# PORTEPOCH hack +# PORTEPOCH/PORTREVISION hack _SUF2= ,${PORTEPOCH} +_SUF1= _${PORTREVISION} PKGNAMESUFFIX= #empty CFLAGS+= ${PTHREAD_CFLAGS} # Keep this, else ruby will fail to load diff --git a/lang/ruby18/files/patch-bignum.c b/lang/ruby18/files/patch-bignum.c new file mode 100644 index 000000000000..570101c49640 --- /dev/null +++ b/lang/ruby18/files/patch-bignum.c @@ -0,0 +1,111 @@ +--- bignum.c.orig Tue Feb 13 02:01:19 2007 ++++ bignum.c Wed May 23 00:37:49 2007 +@@ -96,35 +96,49 @@ + } + + static VALUE +-bignorm(x) ++bigtrunc(x) + VALUE x; + { +- if (FIXNUM_P(x)) { +- return x; +- } +- else if (TYPE(x) == T_BIGNUM) { +- long len = RBIGNUM(x)->len; +- BDIGIT *ds = BDIGITS(x); +- +- while (len-- && !ds[len]) ; +- RBIGNUM(x)->len = ++len; +- +- if (len*SIZEOF_BDIGITS <= sizeof(VALUE)) { +- long num = 0; +- while (len--) { +- num = BIGUP(num) + ds[len]; ++ long len = RBIGNUM(x)->len; ++ BDIGIT *ds = BDIGITS(x); ++ ++ while (len-- && !ds[len]); ++ RBIGNUM(x)->len = ++len; ++ return x; ++} ++ ++static VALUE ++bigfixize(VALUE x) ++{ ++ long len = RBIGNUM(x)->len; ++ BDIGIT *ds = BDIGITS(x); ++ ++ if (len*SIZEOF_BDIGITS <= sizeof(VALUE)) { ++ long num = 0; ++ while (len--) { ++ num = BIGUP(num) + ds[len]; ++ } ++ if (num >= 0) { ++ if (RBIGNUM(x)->sign) { ++ if (POSFIXABLE(num)) return LONG2FIX(num); + } +- if (num >= 0) { +- if (RBIGNUM(x)->sign) { +- if (POSFIXABLE(num)) return LONG2FIX(num); +- } +- else if (NEGFIXABLE(-(long)num)) return LONG2FIX(-(long)num); ++ else { ++ if (NEGFIXABLE(-(long)num)) return LONG2FIX(-(long)num); + } + } + } + return x; + } + ++static VALUE ++bignorm(VALUE x) ++{ ++ if (!FIXNUM_P(x) && TYPE(x) == T_BIGNUM) { ++ x = bigfixize(bigtrunc(x)); ++ } ++ return x; ++} ++ + VALUE + rb_big_norm(x) + VALUE x; +@@ -642,10 +656,10 @@ + j = j * 53L / 84 + 1; + break; + case 4: case 5: case 6: case 7: +- j /= 2; ++ j = (j + 1) / 2; + break; + case 8: case 9: +- j /= 3; ++ j = (j + 2) / 3; + break; + case 10: case 11: case 12: case 13: case 14: case 15: + j = j * 28L / 93 + 1; +@@ -653,10 +667,10 @@ + case 16: case 17: case 18: case 19: case 20: case 21: + case 22: case 23: case 24: case 25: case 26: case 27: + case 28: case 29: case 30: case 31: +- j /= 4; ++ j = (j + 3) / 4; + break; + case 32: case 33: case 34: case 35: case 36: +- j /= 5; ++ j = (j + 4) / 5; + break; + default: + rb_raise(rb_eArgError, "illegal radix %d", base); +@@ -1641,10 +1655,10 @@ + while (yy % 2 == 0) { + yy /= 2; + x = rb_big_mul0(x, x); +- if (!BDIGITS(x)[RBIGNUM(x)->len-1]) RBIGNUM(x)->len--; ++ bigtrunc(x); + } + z = rb_big_mul0(z, x); +- if (!BDIGITS(z)[RBIGNUM(z)->len-1]) RBIGNUM(z)->len--; ++ bigtrunc(z); + } + return bignorm(z); + } diff --git a/lang/ruby18/files/patch-dir.c b/lang/ruby18/files/patch-dir.c new file mode 100644 index 000000000000..f8c491e965e2 --- /dev/null +++ b/lang/ruby18/files/patch-dir.c @@ -0,0 +1,41 @@ +--- dir.c.orig Sat Feb 24 10:55:06 2007 ++++ dir.c Tue May 22 23:22:14 2007 +@@ -958,13 +958,19 @@ + #define GLOB_ALLOC_N(type, n) (type *)malloc(sizeof(type) * (n)) + #define GLOB_JUMP_TAG(status) ((status == -1) ? rb_memerror() : rb_jump_tag(status)) + ++/* ++ * ENOTDIR can be returned by stat(2) if a non-leaf element of the path ++ * is not a directory. ++ */ ++#define to_be_ignored(e) ((e) == ENOENT || (e) == ENOTDIR) ++ + /* System call with warning */ + static int + do_stat(const char *path, struct stat *pst, int flags) + + { + int ret = stat(path, pst); +- if (ret < 0 && errno != ENOENT) ++ if (ret < 0 && !to_be_ignored(errno)) + sys_warning(path); + + return ret; +@@ -974,7 +980,7 @@ + do_lstat(const char *path, struct stat *pst, int flags) + { + int ret = lstat(path, pst); +- if (ret < 0 && errno != ENOENT) ++ if (ret < 0 && !to_be_ignored(errno)) + sys_warning(path); + + return ret; +@@ -984,7 +990,7 @@ + do_opendir(const char *path, int flags) + { + DIR *dirp = opendir(path); +- if (dirp == NULL && errno != ENOENT && errno != ENOTDIR) ++ if (dirp == NULL && !to_be_ignored(errno)) + sys_warning(path); + + return dirp; diff --git a/lang/ruby18/files/patch-eval.c b/lang/ruby18/files/patch-eval.c new file mode 100644 index 000000000000..5f4cbc6d3008 --- /dev/null +++ b/lang/ruby18/files/patch-eval.c @@ -0,0 +1,270 @@ +--- eval.c.orig Sun Mar 11 11:31:53 2007 ++++ eval.c Fri Jun 8 13:33:59 2007 +@@ -1562,11 +1565,15 @@ + int ex; + { + int state; +- volatile VALUE err = ruby_errinfo; ++ VALUE err; ++ volatile VALUE errs[2]; ++ int nerr; + ++ errs[0] = ruby_errinfo; + ruby_safe_level = 0; + Init_stack((void*)&state); + ruby_finalize_0(); ++ errs[1] = ruby_errinfo; + PUSH_TAG(PROT_NONE); + PUSH_ITER(ITER_NOT); + if ((state = EXEC_TAG()) == 0) { +@@ -1577,15 +1584,15 @@ + ex = state; + } + POP_ITER(); +- ruby_errinfo = err; ++ ruby_errinfo = errs[0]; + ex = error_handle(ex); + ruby_finalize_1(); + POP_TAG(); + +- if (err) { ++ for (nerr = sizeof(errs) / sizeof(errs[0]); nerr;) { ++ if (!(err = errs[--nerr])) continue; + if (rb_obj_is_kind_of(err, rb_eSystemExit)) { +- VALUE st = rb_iv_get(err, "status"); +- return NUM2INT(st); ++ return sysexit_status(err); + } + else if (rb_obj_is_kind_of(err, rb_eSignal)) { + VALUE sig = rb_iv_get(err, "signo"); +@@ -1855,7 +1862,7 @@ + POP_TAG(); + POP_FRAME(); + +- jump_tag_but_local_jump(state, val); ++ if (state) jump_tag_but_local_jump(state, val); + return val; + } + +@@ -3494,6 +3501,10 @@ + } + argv = RARRAY(RBASIC(ruby_scope)->klass)->ptr; + } ++ else if (!ruby_scope->local_vars) { ++ argc = 0; ++ argv = 0; ++ } + else { + argv = ruby_scope->local_vars + 2; + } +@@ -4998,8 +5009,10 @@ + CHECK_INTS; + goto redo; + case TAG_NEXT: +- state = 0; +- result = prot_tag->retval; ++ if (!lambda) { ++ state = 0; ++ result = prot_tag->retval; ++ } + break; + case TAG_BREAK: + if (TAG_DST()) { +@@ -7017,7 +7030,8 @@ + return Qfalse; + } + else if (IS_SOEXT(ext) || IS_DLEXT(ext)) { +- return Qfalse; /* may be overriden by .rb file */ ++ if (rb_feature_p(feature, ext, Qfalse)) return Qtrue; ++ return Qfalse; + } + } + if (rb_feature_p(feature, feature + strlen(feature), Qtrue)) +@@ -8597,6 +8611,7 @@ + proc_jump_error(TAG_RETRY, Qnil); /* xxx */ + JUMP_TAG(state); + break; ++ case TAG_NEXT: + case TAG_BREAK: + if (!pcall && result != Qundef) { + proc_jump_error(state, result); +@@ -8966,7 +8981,6 @@ + (FL_TEST(rklass, FL_SINGLETON) || TYPE(rklass) == T_ICLASS)) { + rklass = RCLASS(rklass)->super; + } +- if (TYPE(klass) == T_ICLASS) klass = RBASIC(klass)->klass; + method = Data_Make_Struct(mklass, struct METHOD, bm_mark, free, data); + data->klass = klass; + data->recv = obj; +@@ -9441,8 +9455,12 @@ + else { + rb_str_buf_cat2(str, rb_class2name(data->rklass)); + if (data->rklass != data->klass) { ++ VALUE klass = data -> klass; ++ if (TYPE(klass) == T_ICLASS) { ++ klass = RBASIC(klass)->klass; ++ } + rb_str_buf_cat2(str, "("); +- rb_str_buf_cat2(str, rb_class2name(data->klass)); ++ rb_str_buf_cat2(str, rb_class2name(klass)); + rb_str_buf_cat2(str, ")"); + } + } +@@ -11201,10 +11217,19 @@ + rb_thread_wakeup(thread) + VALUE thread; + { ++ if (!RTEST(rb_thread_wakeup_alive(thread))) ++ rb_raise(rb_eThreadError, "killed thread"); ++ return thread; ++} ++ ++VALUE ++rb_thread_wakeup_alive(thread) ++ VALUE thread; ++{ + rb_thread_t th = rb_thread_check(thread); + + if (th->status == THREAD_KILLED) +- rb_raise(rb_eThreadError, "killed thread"); ++ return Qnil; + rb_thread_ready(th); + + return thread; +@@ -11630,6 +11657,15 @@ + } + + ++enum thread_status ++rb_thread_status(thread) ++ VALUE thread; ++{ ++ rb_thread_t th = rb_thread_check(thread); ++ return th->status; ++} ++ ++ + /* + * call-seq: + * thr.group => thgrp or nil +@@ -11736,21 +11772,36 @@ + /* cause EINTR */ + } + ++static int time_thread_alive_p = 0; + static pthread_t time_thread; + + static void* + thread_timer(dummy) + void *dummy; + { ++#ifdef _THREAD_SAFE ++#define test_cancel() pthread_testcancel() ++#else ++#define test_cancel() /* void */ ++#endif ++ ++ sigset_t all_signals; ++ ++ sigfillset(&all_signals); ++ pthread_sigmask(SIG_BLOCK, &all_signals, 0); ++ + for (;;) { + #ifdef HAVE_NANOSLEEP + struct timespec req, rem; + ++ test_cancel(); + req.tv_sec = 0; + req.tv_nsec = 10000000; + nanosleep(&req, &rem); + #else + struct timeval tv; ++ ++ test_cancel(); + tv.tv_sec = 0; + tv.tv_usec = 10000; + select(0, NULL, NULL, NULL, &tv); +@@ -11762,6 +11813,7 @@ + } + } + } ++#undef test_cancel + } + + void +@@ -11773,6 +11825,20 @@ + rb_thread_stop_timer() + { + } ++ ++void ++rb_thread_cancel_timer() ++{ ++#ifdef _THREAD_SAFE ++ if( time_thread_alive_p ) ++ { ++ pthread_cancel( time_thread ); ++ pthread_join( time_thread, NULL ); ++ time_thread_alive_p = 0; ++ } ++ thread_init = 0; ++#endif ++} + #elif defined(HAVE_SETITIMER) + static void + catch_timer(sig) +@@ -11810,8 +11876,19 @@ + tval.it_value = tval.it_interval; + setitimer(ITIMER_VIRTUAL, &tval, NULL); + } ++ ++void ++rb_thread_cancel_timer() ++{ ++} ++ + #else /* !(_THREAD_SAFE || HAVE_SETITIMER) */ + int rb_thread_tick = THREAD_TICK; ++ ++void ++rb_thread_cancel_timer() ++{ ++} + #endif + + static VALUE +@@ -11842,6 +11919,7 @@ + + #ifdef _THREAD_SAFE + pthread_create(&time_thread, 0, thread_timer, 0); ++ time_thread_alive_p = 1; + #else + rb_thread_start_timer(); + #endif +@@ -12106,7 +12184,7 @@ + */ + + static VALUE +-rb_thread_status(thread) ++rb_thread_status_name(thread) + VALUE thread; + { + rb_thread_t th = rb_thread_check(thread); +@@ -12133,7 +12211,7 @@ + * thr.alive? #=> false + */ + +-static VALUE ++VALUE + rb_thread_alive_p(thread) + VALUE thread; + { +@@ -12967,7 +13045,7 @@ + rb_define_method(rb_cThread, "terminate!", rb_thread_kill_bang, 0); + rb_define_method(rb_cThread, "exit!", rb_thread_kill_bang, 0); + rb_define_method(rb_cThread, "value", rb_thread_value, 0); +- rb_define_method(rb_cThread, "status", rb_thread_status, 0); ++ rb_define_method(rb_cThread, "status", rb_thread_status_name, 0); + rb_define_method(rb_cThread, "join", rb_thread_join_m, -1); + rb_define_method(rb_cThread, "alive?", rb_thread_alive_p, 0); + rb_define_method(rb_cThread, "stop?", rb_thread_stop_p, 0); diff --git a/lang/ruby18/files/patch-ext_bigdecimal_bigdecimal.c b/lang/ruby18/files/patch-ext_bigdecimal_bigdecimal.c new file mode 100644 index 000000000000..2aa3ef9a4473 --- /dev/null +++ b/lang/ruby18/files/patch-ext_bigdecimal_bigdecimal.c @@ -0,0 +1,11 @@ +--- ext/bigdecimal/bigdecimal.c.orig Tue Feb 27 14:51:55 2007 ++++ ext/bigdecimal/bigdecimal.c Fri Mar 16 13:07:26 2007 +@@ -3921,7 +3921,7 @@ + /* get integer part */ + i = 0; + sign = 1; +- if(ni > 0) { ++ if(ni >= 0) { + if(int_chr[0] == '-') { + sign = -1; + ++i; diff --git a/lang/ruby18/files/patch-ext_dl_dl.c b/lang/ruby18/files/patch-ext_dl_dl.c new file mode 100644 index 000000000000..1527786a7aca --- /dev/null +++ b/lang/ruby18/files/patch-ext_dl_dl.c @@ -0,0 +1,11 @@ +--- ext/dl/dl.c.orig Tue Feb 13 02:01:19 2007 ++++ ext/dl/dl.c Mon Mar 19 10:43:56 2007 +@@ -459,7 +459,7 @@ + VALUE val0; + + val0 = rb_check_array_type(v); +- if(NIL_P(TYPE(val0))) { ++ if(NIL_P(val0)) { + rb_raise(rb_eDLTypeError, "an array is expected."); + } + v = val0; diff --git a/lang/ruby18/files/patch-ext_etc_etc.c b/lang/ruby18/files/patch-ext_etc_etc.c new file mode 100644 index 000000000000..b70983b64888 --- /dev/null +++ b/lang/ruby18/files/patch-ext_etc_etc.c @@ -0,0 +1,11 @@ +--- ext/etc/etc.c.orig Tue Feb 13 02:01:19 2007 ++++ ext/etc/etc.c Fri Mar 16 14:53:15 2007 +@@ -337,7 +337,7 @@ + struct group *grp; + + rb_secure(4); +- gid = getgid(); ++ gid = PW_VAL2GID(id); + grp = getgrgid(gid); + if (grp == 0) rb_raise(rb_eArgError, "can't find group for %d", gid); + return setup_group(grp); diff --git a/lang/ruby18/files/patch-ext_thread_thread.c b/lang/ruby18/files/patch-ext_thread_thread.c new file mode 100644 index 000000000000..121dfa5380f6 --- /dev/null +++ b/lang/ruby18/files/patch-ext_thread_thread.c @@ -0,0 +1,270 @@ +--- ext/thread/thread.c.orig Sat Mar 3 13:08:06 2007 ++++ ext/thread/thread.c Tue Jul 10 03:08:38 2007 +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + + static VALUE rb_cMutex; + static VALUE rb_cConditionVariable; +@@ -163,13 +164,18 @@ + remove_one(List *list, VALUE value) + { + Entry **ref; ++ Entry *prev; + Entry *entry; + +- for (ref = &list->entries, entry = list->entries; ++ for (ref = &list->entries, prev = NULL, entry = list->entries; + entry != NULL; +- ref = &entry->next, entry = entry->next) { ++ ref = &entry->next, prev = entry, entry = entry->next) { + if (entry->value == value) { + *ref = entry->next; ++ list->size--; ++ if (!entry->next) { ++ list->last_entry = prev; ++ } + recycle_entries(list, entry, entry); + break; + } +@@ -202,15 +208,16 @@ + static VALUE + wake_thread(VALUE thread) + { +- return rb_rescue2(rb_thread_wakeup, thread, +- NULL, Qundef, rb_eThreadError, 0); ++ return rb_thread_wakeup_alive(thread); + } + + static VALUE + run_thread(VALUE thread) + { +- return rb_rescue2(rb_thread_run, thread, +- NULL, Qundef, rb_eThreadError, 0); ++ thread = wake_thread(thread); ++ if (RTEST(thread) && !rb_thread_critical) ++ rb_thread_schedule(); ++ return thread; + } + + static VALUE +@@ -220,7 +227,9 @@ + + waking = Qnil; + while (list->entries && !RTEST(waking)) { +- waking = wake_thread(shift_list(list)); ++ waking = shift_list(list); ++ if (waking == Qundef) break; ++ waking = wake_thread(waking); + } + + return waking; +@@ -251,7 +260,7 @@ + return Qnil; + } + +-static void ++static VALUE + wait_list(List *list) + { + rb_ensure(wait_list_inner, (VALUE)list, wait_list_cleanup, (VALUE)list); +@@ -261,10 +270,17 @@ + assert_no_survivors(List *waiting, const char *label, void *addr) + { + Entry *entry; ++ VALUE ths = 0; ++ + for (entry = waiting->entries; entry; entry = entry->next) { +- if (RTEST(wake_thread(entry->value))) { +- rb_bug("%s %p freed with live thread(s) waiting", label, addr); +- } ++ if (RTEST(wake_thread(entry->value))) { ++ if (!ths) ths = rb_ary_new(); ++ rb_ary_push(ths, entry->value); ++ } ++ } ++ if (ths) { ++ rb_bug("%s %p freed with live thread(s) %s waiting", ++ label, addr, RSTRING_PTR(rb_inspect(ths))); + } + } + +@@ -298,6 +314,8 @@ + List waiting; + } Mutex; + ++#define MUTEX_LOCKED_P(mutex) (RTEST((mutex)->owner) && rb_thread_alive_p((mutex)->owner)) ++ + static void + mark_mutex(Mutex *mutex) + { +@@ -356,7 +374,7 @@ + { + Mutex *mutex; + Data_Get_Struct(self, Mutex, mutex); +- return RTEST(mutex->owner) ? Qtrue : Qfalse; ++ return MUTEX_LOCKED_P(mutex) ? Qtrue : Qfalse; + } + + /* +@@ -375,7 +393,7 @@ + + Data_Get_Struct(self, Mutex, mutex); + +- if (RTEST(mutex->owner)) ++ if (MUTEX_LOCKED_P(mutex)) + return Qfalse; + + mutex->owner = rb_thread_current(); +@@ -390,7 +408,7 @@ + * + */ + +-static void ++static VALUE + lock_mutex(Mutex *mutex) + { + VALUE current; +@@ -398,13 +416,23 @@ + + rb_thread_critical = 1; + +- while (RTEST(mutex->owner)) { +- wait_list(&mutex->waiting); +- rb_thread_critical = 1; ++ if (!MUTEX_LOCKED_P(mutex)) { ++ mutex->owner = current; ++ } ++ else { ++ push_list(&mutex->waiting, current); ++ do { ++ rb_thread_stop(); ++ rb_thread_critical = 1; ++ if (!MUTEX_LOCKED_P(mutex)) { ++ mutex->owner = current; ++ break; ++ } ++ } while (mutex->owner != current); + } +- mutex->owner = current; + + rb_thread_critical = 0; ++ return Qnil; + } + + static VALUE +@@ -416,6 +444,22 @@ + return self; + } + ++static VALUE ++relock_mutex(Mutex *mutex) ++{ ++ VALUE current = rb_thread_current(); ++ ++ switch (rb_thread_status(current)) { ++ case THREAD_RUNNABLE: ++ case THREAD_STOPPED: ++ lock_mutex(mutex); ++ break; ++ default: ++ break; ++ } ++ return Qundef; ++} ++ + /* + * Document-method: unlock + * +@@ -428,11 +472,12 @@ + { + VALUE waking; + +- if (!RTEST(mutex->owner)) { +- return Qundef; ++ if (mutex->owner != rb_thread_current()) { ++ rb_raise(rb_eThreadError, "not owner"); + } +- mutex->owner = Qnil; ++ + waking = wake_one(&mutex->waiting); ++ mutex->owner = waking; + + return waking; + } +@@ -451,14 +496,11 @@ + + rb_thread_critical = 1; + waking = rb_ensure(unlock_mutex_inner, (VALUE)mutex, set_critical, 0); +- +- if (waking == Qundef) { ++ if (!RTEST(waking)) { + return Qfalse; + } + +- if (RTEST(waking)) { +- run_thread(waking); +- } ++ run_thread(waking); + + return Qtrue; + } +@@ -504,13 +546,11 @@ + rb_thread_critical = 1; + waking = rb_ensure(rb_mutex_exclusive_unlock_inner, (VALUE)mutex, set_critical, 0); + +- if (waking == Qundef) { ++ if (waking == Qundef || !RTEST(waking)) { + return Qnil; + } + +- if (RTEST(waking)) { +- run_thread(waking); +- } ++ run_thread(waking); + + return self; + } +@@ -622,19 +662,18 @@ + static void + wait_condvar(ConditionVariable *condvar, Mutex *mutex) + { ++ VALUE waking; ++ + rb_thread_critical = 1; +- if (!RTEST(mutex->owner)) { ++ if (rb_thread_current() != mutex->owner) { + rb_thread_critical = 0; +- return; ++ rb_raise(rb_eThreadError, "not owner of the synchronization mutex"); + } +- if (mutex->owner != rb_thread_current()) { +- rb_thread_critical = 0; +- rb_raise(rb_eThreadError, "Not owner"); ++ waking = unlock_mutex_inner(mutex); ++ if (RTEST(waking)) { ++ wake_thread(waking); + } +- mutex->owner = Qnil; +- wait_list(&condvar->waiting); +- +- lock_mutex(mutex); ++ rb_ensure(wait_list, (VALUE)&condvar->waiting, relock_mutex, (VALUE)mutex); + } + + static VALUE +@@ -830,10 +869,10 @@ + + array = rb_marshal_load(data); + if (TYPE(array) != T_ARRAY) { +- rb_raise(rb_eRuntimeError, "expected Array of queue data"); ++ rb_raise(rb_eTypeError, "expected Array of queue data"); + } + if (RARRAY(array)->len < 1) { +- rb_raise(rb_eRuntimeError, "missing capacity value"); ++ rb_raise(rb_eArgError, "missing capacity value"); + } + queue->capacity = NUM2ULONG(rb_ary_shift(array)); + push_multiple_list(&queue->values, RARRAY(array)->ptr, (unsigned)RARRAY(array)->len); diff --git a/lang/ruby18/files/patch-ext_tk_lib_tkextlib_tcllib_tablelist.rb b/lang/ruby18/files/patch-ext_tk_lib_tkextlib_tcllib_tablelist.rb new file mode 100644 index 000000000000..3602f8ec347f --- /dev/null +++ b/lang/ruby18/files/patch-ext_tk_lib_tkextlib_tcllib_tablelist.rb @@ -0,0 +1,9 @@ +--- ext/tk/lib/tkextlib/tcllib/tablelist.rb.orig Tue Feb 13 02:01:19 2007 ++++ ext/tk/lib/tkextlib/tcllib/tablelist.rb Fri May 25 20:11:52 2007 +@@ -23,5 +23,5 @@ + # TkPackage.require('Tablelist', '4.2') + TkPackage.require('Tablelist') + +- requrie 'tkextlib/tcllib/tablelist_core' ++ require 'tkextlib/tcllib/tablelist_core' + end diff --git a/lang/ruby18/files/patch-ext_tk_lib_tkextlib_tile_dialog.rb b/lang/ruby18/files/patch-ext_tk_lib_tkextlib_tile_dialog.rb new file mode 100644 index 000000000000..fd5e97c2db1d --- /dev/null +++ b/lang/ruby18/files/patch-ext_tk_lib_tkextlib_tile_dialog.rb @@ -0,0 +1,11 @@ +--- ext/tk/lib/tkextlib/tile/dialog.rb.orig Tue Feb 13 02:01:19 2007 ++++ ext/tk/lib/tkextlib/tile/dialog.rb Fri May 25 20:11:52 2007 +@@ -51,7 +51,7 @@ + alias display show + + def client_frame +- window(tk_call_without_enc('::ttk::dialog::clientframe')) ++ window(tk_call_without_enc('::ttk::dialog::clientframe', @path)) + end + + def cget(slot) diff --git a/lang/ruby18/files/patch-intern.h b/lang/ruby18/files/patch-intern.h new file mode 100644 index 000000000000..97669273d111 --- /dev/null +++ b/lang/ruby18/files/patch-intern.h @@ -0,0 +1,16 @@ +--- intern.h.orig Sun Mar 11 11:31:53 2007 ++++ intern.h Thu Jun 7 16:40:01 2007 +@@ -204,10 +204,13 @@ + void rb_thread_polling _((void)); + void rb_thread_sleep _((int)); + void rb_thread_sleep_forever _((void)); ++enum thread_status rb_thread_status _((VALUE)); + VALUE rb_thread_stop _((void)); + VALUE rb_thread_wakeup _((VALUE)); ++VALUE rb_thread_wakeup_alive _((VALUE)); + VALUE rb_thread_run _((VALUE)); + VALUE rb_thread_kill _((VALUE)); ++VALUE rb_thread_alive_p _((VALUE)); + VALUE rb_thread_create _((VALUE (*)(ANYARGS), void*)); + void rb_thread_interrupt _((void)); + void rb_thread_trap_eval _((VALUE, int, int)); diff --git a/lang/ruby18/files/patch-lib_cgi.rb b/lang/ruby18/files/patch-lib_cgi.rb new file mode 100644 index 000000000000..e3c7b0b412f8 --- /dev/null +++ b/lang/ruby18/files/patch-lib_cgi.rb @@ -0,0 +1,10 @@ +--- lib/cgi.rb.orig Mon Mar 12 20:55:03 2007 ++++ lib/cgi.rb Wed May 23 01:58:09 2007 +@@ -1163,6 +1163,7 @@ + # retrieved; use #params() to get the array of values. + def [](key) + params = @params[key] ++ return '' unless params + value = params[0] + if @multipart + if value diff --git a/lang/ruby18/files/patch-lib_monitor.rb b/lang/ruby18/files/patch-lib_monitor.rb new file mode 100644 index 000000000000..0c1d04371781 --- /dev/null +++ b/lang/ruby18/files/patch-lib_monitor.rb @@ -0,0 +1,46 @@ +--- lib/monitor.rb.orig Tue Feb 13 02:01:19 2007 ++++ lib/monitor.rb Tue May 22 22:35:57 2007 +@@ -105,14 +105,17 @@ + return false + ensure + Thread.critical = true +- if timer && timer.alive? +- Thread.kill(timer) ++ begin ++ if timer && timer.alive? ++ Thread.kill(timer) ++ end ++ if @waiters.include?(Thread.current) # interrupted? ++ @waiters.delete(Thread.current) ++ end ++ @monitor.instance_eval {mon_enter_for_cond(count)} ++ ensure ++ Thread.critical = false + end +- if @waiters.include?(Thread.current) # interrupted? +- @waiters.delete(Thread.current) +- end +- @monitor.instance_eval {mon_enter_for_cond(count)} +- Thread.critical = false + end + end + +@@ -210,6 +213,7 @@ + Thread.critical = true + mon_acquire(@mon_entering_queue) + @mon_count += 1 ++ ensure + Thread.critical = false + end + +@@ -299,8 +303,9 @@ + def mon_exit_for_cond + count = @mon_count + @mon_count = 0 +- mon_release + return count ++ ensure ++ mon_release + end + end + diff --git a/lang/ruby18/files/patch-lib_net_imap.rb b/lang/ruby18/files/patch-lib_net_imap.rb new file mode 100644 index 000000000000..8ff68bb20ee2 --- /dev/null +++ b/lang/ruby18/files/patch-lib_net_imap.rb @@ -0,0 +1,15 @@ +--- lib/net/imap.rb.orig Tue Feb 13 02:01:19 2007 ++++ lib/net/imap.rb Tue May 22 20:44:37 2007 +@@ -284,7 +284,11 @@ + + # Disconnects from the server. + def disconnect +- @sock.shutdown unless @usessl ++ if SSL::SSLSocket === @sock ++ @sock.io.shutdown ++ else ++ @sock.shutdown ++ end + @receiver_thread.join + @sock.close + end diff --git a/lang/ruby18/files/patch-process.c b/lang/ruby18/files/patch-process.c new file mode 100644 index 000000000000..598cf5db50c8 --- /dev/null +++ b/lang/ruby18/files/patch-process.c @@ -0,0 +1,10 @@ +--- process.c.orig Tue Feb 13 02:01:19 2007 ++++ process.c Wed May 23 02:32:16 2007 +@@ -981,6 +981,7 @@ + } + #endif /* MSDOS or __human68k__ or __EMX__ */ + before_exec(); ++ rb_thread_cancel_timer(); + execv(prog, argv); + after_exec(); + return -1; diff --git a/lang/ruby18/files/patch-util.c b/lang/ruby18/files/patch-util.c new file mode 100644 index 000000000000..e236a9cd4154 --- /dev/null +++ b/lang/ruby18/files/patch-util.c @@ -0,0 +1,13 @@ +--- util.c.orig Sun Mar 4 17:20:24 2007 ++++ util.c Tue May 22 22:25:13 2007 +@@ -683,8 +683,8 @@ + * + */ + +-#define MDMINEXPT DBL_MIN_EXP +-#define MDMAXEXPT DBL_MAX_EXP ++#define MDMINEXPT DBL_MIN_10_EXP ++#define MDMAXEXPT DBL_MAX_10_EXP + + static const + double powersOf10[] = { /* Table giving binary powers of 10. Entry */