diff -burN ruby-1.8.7-p22/array.c ruby-1.8.7-p72/array.c
--- ruby-1.8.7-p22/array.c	2008-06-20 09:38:15.000000000 +0200
+++ ruby-1.8.7-p72/array.c	2008-07-01 08:14:29.000000000 +0200
@@ -3,7 +3,7 @@
   array.c -
 
   $Author: shyouhei $
-  $Date: 2008-06-20 16:38:15 +0900 (Fri, 20 Jun 2008) $
+  $Date: 2008-07-01 15:14:29 +0900 (Tue, 01 Jul 2008) $
   created at: Fri Aug  6 09:46:12 JST 1993
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -2416,10 +2416,13 @@
 	break;
     }
     rb_ary_modify(ary);
-    end = beg + len;
-    if (end < 0) {
+    if (len < 0) {
+        return ary;
+    }
+    if (beg >= ARY_MAX_SIZE || len > ARY_MAX_SIZE - beg) {
 	rb_raise(rb_eArgError, "argument too big");
     }
+    end = beg + len;
     if (end > RARRAY(ary)->len) {
 	if (end >= RARRAY(ary)->aux.capa) {
 	    REALLOC_N(RARRAY(ary)->ptr, VALUE, end);
diff -burN ruby-1.8.7-p22/bignum.c ruby-1.8.7-p72/bignum.c
--- ruby-1.8.7-p22/bignum.c	2008-04-01 13:33:27.000000000 +0200
+++ ruby-1.8.7-p72/bignum.c	2008-08-04 07:05:38.000000000 +0200
@@ -2,8 +2,8 @@
 
   bignum.c -
 
-  $Author: matz $
-  $Date: 2008-04-01 20:33:27 +0900 (Tue, 01 Apr 2008) $
+  $Author: shyouhei $
+  $Date: 2008-08-04 14:05:38 +0900 (Mon, 04 Aug 2008) $
   created at: Fri Jun 10 00:48:55 JST 1994
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -11,6 +11,7 @@
 **********************************************************************/
 
 #include "ruby.h"
+#include "rubysig.h"
 
 #include <math.h>
 #include <float.h>
@@ -720,6 +721,7 @@
     s = RSTRING(ss)->ptr;
 
     s[0] = RBIGNUM(x)->sign ? '+' : '-';
+    TRAP_BEG;
     while (i && j > 1) {
 	long k = i;
 	BDIGIT_DBL num = 0;
@@ -749,6 +751,7 @@
 	RSTRING(ss)->len = i;
     }
     s[RSTRING(ss)->len] = '\0';
+    TRAP_END;
 
     return ss;
 }
@@ -1735,11 +1738,13 @@
     RBIGNUM(z)->len = len;
     a2 = bigtrunc(rb_big_mul0(a, b));
     len = RBIGNUM(a2)->len;
+    TRAP_BEG;
     for (i = 0, num = 0; i < len; i++) {
 	num += (BDIGIT_DBL)BDIGITS(z)[i + k] + ((BDIGIT_DBL)BDIGITS(a2)[i] << 1);
 	BDIGITS(z)[i + k] = BIGLO(num);
 	num = BIGDN(num);
     }
+    TRAP_END;
     if (num) {
 	len = RBIGNUM(z)->len;
 	for (i += k; i < len && num; ++i) {
diff -burN ruby-1.8.7-p22/ChangeLog ruby-1.8.7-p72/ChangeLog
--- ruby-1.8.7-p22/ChangeLog	2008-06-20 11:28:35.000000000 +0200
+++ ruby-1.8.7-p72/ChangeLog	2008-08-11 02:37:21.000000000 +0200
@@ -1,3 +1,305 @@
+Fri Aug  8 10:53:52 2008  Tanaka Akira  <akr@fsij.org>
+
+	* lib/resolv.rb: randomize source port and transaction id.
+	  CVE-2008-1447.
+
+	* lib/resolv-replace.rb (UDPSocket#bind): don't resolv host if host is
+	  "".
+
+Mon Aug  4 14:49:35 2008  URABE Shyouhei  <shyouhei@ruby-lang.org>
+
+	* lib/net/smtp.rb (Net::SMTP::rcptto): fix a typo. a patch from
+	  Masao Takaku <masao at nii.ac.jp>
+	  fix [ruby-dev:35489].
+
+Mon Aug  4 14:13:15 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* regex.c (xmalloc, xrealloc, xfree): not to use ruby managed memory.
+
+	* regex.c (DOUBLE_STACK, re_compile_fastmap0, re_adjust_startpos),
+	  (re_search, re_match_exec): check if failed to allocate memory.
+
+Mon Aug  4 13:53:42 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* bignum.c (rb_big2str0, bigsqr): made interruptible.  [ruby-Bugs-20622]
+
+Mon Aug  4 13:31:41 2008  NAKAMURA Usaku  <usa@ruby-lang.org>
+
+	* numeric.c (check_uint, rb_num2uint, rb_fix2uint): fixed wrong check
+	  about 64bit positive value.
+Mon Aug  4 13:31:41 2008  NAKAMURA Usaku  <usa@ruby-lang.org>
+
+	* numeric.c (check_uint, rb_num2uint, rb_fix2uint): strict check.
+	  fixed [ruby-dev:33683]
+Mon Aug 11 09:37:17 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>
+
+	* ext/dl/dl.c (rb_str_to_ptr): should propagate taint to dlptr.
+
+	* ext/dl/dl.c (rb_ary_to_ptr): ditto.
+
+	* ext/dl/sym.c (rb_dlsym_call): should check taint of DLPtrData as
+	  well.
+
+
+Thu Jul 17 21:42:07 2008  URABE Shyouhei  <shyouhei@ruby-lang.org>
+
+	* lib/net/smtp.rb (Net::SMTP::start): revert to avoid RFC2821
+	  violation. [ruby-dev:35487]
+
+Thu Jul 17 21:32:49 2008  Tanaka Akira  <akr@fsij.org>
+
+	* string.c (rb_str_format_m): make tmp volatile to avoid possible GC
+	  problem.
+
+Thu Jul 17 21:30:55 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* lib/optparse.rb (OptionParser#environment): requires shellwords.
+	  [ruby-dev:35466]
+
+Thu Jul 17 02:05:10 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* lib/xmlrpc/client.rb (XMLRPC::Client#do_rpc): requires
+	  webrick/cookie.  [ ruby-Bugs-21139 ]
+
+Thu Jul 17 01:38:31 2008  Yusuke Endoh  <mame@tsg.ne.jp>
+
+	* ext/zlib/zlib.c (rb_gzfile_set_mtime): fix typo.  [ruby-core:17713]
+
+Sun Jul 13 00:08:16 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* lib/ipaddr.rb (IPAddr#initialize): get rid of ArgumentError in
+	  IPAddr#to_range.  a patch from okkez <okkez000 AT gmail.com> in
+	  [ruby-dev:35091].
+
+Sun Jul 13 00:04:38 2008  Tanaka Akira  <akr@fsij.org>
+
+	* configure.in (erfc): erfc of glibc comes with Debian GNU/Linux Etch
+	  on IA64 is broken.  erfc(10000.0) aborts.
+	  use missing/erf.c instead.
+	  http://sources.redhat.com/ml/libc-hacker/2005-08/msg00008.html
+
+Thu Jul 10 18:50:48 2008  Tanaka Akira  <akr@fsij.org>
+
+	* common.mk (SPEC_GIT_BASE): update RubySpec GIT URL.
+
+Thu Jul 10 18:46:28 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* file.c (rb_file_s_extname): fix for file name with spaces.
+	  [ruby-talk:307404]
+
+Thu Jul 10 18:42:37 2008  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>
+
+	* lib/erb.rb (PercentScanner#scan): fix %% line bug. [ruby-core:17491]
+
+	* test/erb/test_erb.rb (test_percent): ditto.
+
+Thu Jul 10 18:40:22 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* lib/net/ftp.rb (Net::FTP#sendport): use divmod.  [ruby-core:17557]
+
+Thu Jul 10 18:36:53 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>
+
+	* ruby.c: Mac OS X needs origargc times of '\0' in
+	  origargv. [ruby-dev:35308]
+
+Thu Jul 10 13:53:08 2008  Tanaka Akira  <akr@fsij.org>
+
+	* include/ruby/ruby.h (POSFIXABLE): use FIXNUM_MAX+1 instead of
+	  FIXNUM_MAX to make it possible to convert to double accurately.
+	  It assumes FLT_RADIX is 2.
+	  fix RubyForge bug #14102.
+	  backported from 1.9.
+
+Mon Jul  7 16:21:38 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>
+
+	* lib/net/smtp.rb (Net::SMTP::start): use 'localhost' instead of
+	  'localhost.localdomain'.  [ruby-dev:35333]
+
+	* lib/net/smtp.rb (Net::SMTP::SMTP.start): ditto.
+
+Mon Jul  7 15:02:13 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* eval.c (rb_longjmp): duplicate the thrown exception to set backtrace
+	  if it was frozen.  clear all raised flags.
+
+	* eval.c (stack_check): leave clearing flag to rb_longjmp.
+
+	* eval.c (rb_thread_set_raised, rb_thread_reset_raised): use generic
+	  flags.
+
+	* eval.c (Init_Proc), gc.c (Init_GC): freeze preallocated special exceptions.
+
+	* gc.c (rb_memerror): use thread raised flag instead of static flag,
+	  and raise nomem_error without backtrace if failed to make backtrace.
+	  [ruby-dev:34724]
+
+	* gc.c (ruby_xmalloc): increase malloc_increase only if malloc
+	  succeeds.  failed malloc size can be huge.  it may increase
+	  malloc_limit too big which cause less GC and memory full.
+	  (ruby_xrealloc): ditto.
+
+Mon Jul  7 12:23:05 2008  Masaki Suketa  <masaki.suketa@nifty.ne.jp>
+
+	* ext/win32ole/win32ole.c: avoid creating Ruby object during
+	  GC. thanks to arton <artonx AT yahoo.co.jp>. [ruby-dev:35313]
+
+	* ext/win32ole/tests: add test_win32ole_event.rb, remove
+	  testOLEEVENT.rb
+
+	* ext/win32ole/tests/testWIN32OLE.rb(test_convert_bignum):
+	  fix test.
+
+Mon Jul  7 12:23:05 2008  Masaki Suketa  <masaki.suketa@nifty.ne.jp>
+
+	* gc.c: add rb_during_gc(). based on a patch from arton <artonx AT
+	  yahoo.co.jp> at [ruby-dev:35313].   
+
+	* intern.h: ditto.
+
+Thu Jul  3 20:13:20 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* marshal.c (w_object, marshal_dump, r_object0, marshal_load): search
+	  public methods only.  [ruby-core:17283]
+
+	* object.c (convert_type): ditto.
+
+	* lib/singleton.rb (Singleton#_dump): conversion method should be
+	  public.
+
+Wed Jul  2 19:06:43 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* lib/cgi.rb (CGI::QueryExtension.read_multipart): blanks inside
+	  double quotes are allowed.  [ruby-list:45140]
+
+Wed Jul  2 19:03:37 2008  Tanaka Akira  <akr@fsij.org>
+
+	* numeric.c (num_coerce): call rb_Float(x) first.  don't depend on
+	  evaluation order of function arguments.
+
+Wed Jul  2 18:57:19 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>
+
+	* ext/syslog/syslog.c (syslog_write): syslog operations should be
+	  protected from $SAFE level 4.  a patch from Keita Yamaguchi
+	  <keita.yamaguchi at gmail.com>.
+
+	* ext/syslog/syslog.c (mSyslog_close): ditto.
+
+	* ext/syslog/syslog.c (mSyslog_set_mask): ditto.
+
+Wed Jul  2 18:26:20 2008  Tanaka Akira  <akr@fsij.org>
+
+	* math.c (domain_check): fix preprocess condition.
+
+Wed Jul  2 18:22:52 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* lib/tmpdir.rb (@@systmpdir): prior LOCAL_APPDATA if possible, and
+	  should be clean.  based on a patch from arton <artonx AT
+	  yahoo.co.jp> at [ruby-dev:35269]
+
+Wed Jul  2 18:16:19 2008  Masaki Suketa  <masaki.suketa@nifty.ne.jp>
+
+	* ext/win32ole/win32ole.c (date2time_str): fix the overflow in
+	  some situation. [ruby-bugs-20793]
+
+Tue Jul  1 15:11:14 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* array.c (rb_ary_fill): check if beg is too big.
+
+Mon Jun 30 20:35:32 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* string.c (str_buf_cat): check for self concatenation.
+
+Sun Jun 29 21:39:54 2008  Tanaka Akira  <akr@fsij.org>
+
+	* eval.c (rb_obj_respond_to): use RTEST to test the result of
+	  respond_to? method.
+
+Sun Jun 29 21:20:17 2008  URABE Shyouhei  <shyouhei@ruby-lang.org>
+
+	* array.c (rb_ary_fill): (compatibility) do not raise
+	  ArgumentError on negative length.  This behaviour shall change
+	  in a future release.
+
+Sun Jun 29 20:08:11 2008  Tanaka Akira  <akr@fsij.org>
+
+	* time.c (time_timeval): fix rounding negative float.
+
+Sun Jun 29 19:19:08 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* test/inlinetest.rb (InlineTest.in_progname): workaround for frozen
+	  $0.  [ruby-dev:35261]
+
+	* lib/test/unit/ui/console/testrunner.rb (TestRunner#finished): ditto.
+
+Sun Jun 29 19:19:08 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* ruby.c (set_arg0, ruby_prog_init): freeze $0.  a patch from Keita
+	  Yamaguchi <keita.yamaguchi at gmail.com>.
+
+Sun Jun 29 18:33:33 2008  Tanaka Akira  <akr@fsij.org>
+
+	* process.c: include sys/resource.h if HAVE_SYS_RESOURCE_H is defined.
+	  pointed by TOYOFUKU Chikanobu.  [ruby-dev:35258]
+
+Sun Jun 29 18:26:01 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>
+
+	* variable.c (rb_f_trace_var): should not be allowed at safe level 4.  
+	  a patch from Keita Yamaguchi <keita.yamaguchi at gmail.com>.
+
+	* eval.c (rb_call0): wrong condition to check insecure method.
+	  a patch from Keita Yamaguchi <keita.yamaguchi at gmail.com>.
+
+Sun Jun 29 18:22:52 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* array.c (rb_ary_fill): not depend on unspecified behavior at integer
+	  overflow.  reported by Vincenzo Iozzo <snagg AT openssl.it>.
+
+Sun Jun 29 18:22:06 2008  Masaki Suketa  <masaki.suketa@nifty.ne.jp>
+
+	* ext/win32ole/win32ole.c(ole_invoke): fix memory leak.
+	  [ruby-bugs-20792]
+
+Sun Jun 29 18:19:11 2008  Akinori MUSHA  <knu@iDaemons.org>
+
+	* eval.c (PUSH_FRAME, PUSH_CLASS): Add volatile to avoid a
+	  possible optimization bug on OS X/PPC.  This at least makes
+	  build with gcc -O1 and `make test' pass.
+
+Sun Jun 29 17:24:43 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* lib/rdoc/parsers/parse_rb.rb (RDoc#collect_first_comment): skip
+	  magic comment.
+
+Sun Jun 29 17:22:09 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* ext/stringio/stringio.c (strio_each, strio_readlines): IO#each and
+	  IO#readlines do not affect $_.  [ruby-core:17277]
+
+Sun Jun 29 17:19:59 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* ext/stringio/stringio.c (strio_readline, strio_each)
+	  (strio_readlines): set lastline.  [ruby-core:17257]
+
+Sun Jun 29 17:15:49 2008  NAKAMURA Usaku  <usa@ruby-lang.org>
+
+	* ext/openssl/ossl.h: include winsock.h if USE_WINSOCK2 is not defined.
+	  a patch from arton <artonx at yahoo.co.jp> in [ruby-dev:35078]
+
+Sun Jun 29 17:09:48 2008  wanabe  <s.wanabe@gmail.com>
+
+	* util.c (ruby_strtod): ruby_strtod don't allow a trailing
+	  decimal point like "7.". [ruby-dev:34835] [ruby-dev:35009]
+
+Sat Jun 28 19:23:40 2008  URABE Shyouhei  <shyouhei@ruby-lang.org>
+
+	* class.c (clone_method): use rb_copy_node_scope.
+	  fixed [ruby-list:45102]
+	  fixed [ruby-core:17393]
+
+Sat Jun 28 18:49:50 2008  URABE Shyouhei  <shyouhei@ruby-lang.org>
+
+	* class.c: revert to r15855.
+
 Fri Jun 20 18:25:18 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
 
 	* string.c (rb_str_buf_append): should infect.
diff -burN ruby-1.8.7-p22/class.c ruby-1.8.7-p72/class.c
--- ruby-1.8.7-p22/class.c	2008-05-23 07:22:13.000000000 +0200
+++ ruby-1.8.7-p72/class.c	2008-06-28 12:23:54.000000000 +0200
@@ -2,8 +2,8 @@
 
   class.c -
 
-  $Author: knu $
-  $Date: 2008-05-23 14:22:13 +0900 (Fri, 23 May 2008) $
+  $Author: shyouhei $
+  $Date: 2008-06-28 19:23:54 +0900 (Sat, 28 Jun 2008) $
   created at: Tue Aug 10 15:05:44 JST 1993
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -48,37 +48,26 @@
     return rb_class_boot(super);
 }
 
+struct clone_method_data {
+    st_table *tbl;
+    VALUE klass;
+};
+
 static int
-clone_method(mid, body, nklass)
+clone_method(mid, body, data)
     ID mid;
     NODE *body;
-    VALUE nklass;
+    struct clone_method_data *data;
 {
     NODE *fbody = body->nd_body;
 
-    if (fbody) {
-	VALUE nbody;
-
-	switch (nd_type(fbody)) {
-	  case NODE_SCOPE:
+    if (fbody && nd_type(fbody) == NODE_SCOPE) {
 	    fbody = rb_copy_node_scope(fbody, ruby_cref);
-    	    break;
-	  case NODE_BMETHOD:
-	    nbody = rb_block_dup(fbody->nd_cval, nklass, (VALUE)ruby_cref);
-	    fbody = NEW_BMETHOD(nbody);
-	    break;
-	  case NODE_DMETHOD:
-	    nbody = rb_method_dup(fbody->nd_cval, nklass, (VALUE)ruby_cref);
-	    fbody = NEW_DMETHOD(nbody);
-	    break;
-	}
     }
-    st_insert(RCLASS(nklass)->m_tbl, mid, (st_data_t)NEW_METHOD(fbody, body->nd_noex));
+    st_insert(data->tbl, mid, (st_data_t)NEW_METHOD(fbody, body->nd_noex));
     return ST_CONTINUE;
 }
 
-static VALUE singleton_class_clone_int _((VALUE, VALUE));
-
 /* :nodoc: */
 VALUE
 rb_mod_init_copy(clone, orig)
@@ -86,7 +75,8 @@
 {
     rb_obj_init_copy(clone, orig);
     if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
-	RBASIC(clone)->klass = singleton_class_clone_int(orig, clone);
+	RBASIC(clone)->klass = RBASIC(orig)->klass;
+	RBASIC(clone)->klass = rb_singleton_class_clone(clone);
     }
     RCLASS(clone)->super = RCLASS(orig)->super;
     if (RCLASS(orig)->iv_tbl) {
@@ -99,8 +89,12 @@
 	st_delete(RCLASS(clone)->iv_tbl, (st_data_t*)&id, 0);
     }
     if (RCLASS(orig)->m_tbl) {
- 	RCLASS(clone)->m_tbl = st_init_numtable();
-	st_foreach(RCLASS(orig)->m_tbl, clone_method, clone);
+	struct clone_method_data data;
+
+	data.tbl = RCLASS(clone)->m_tbl = st_init_numtable();
+	data.klass = (VALUE)clone;
+
+	st_foreach(RCLASS(orig)->m_tbl, clone_method, (st_data_t)&data);
     }
 
     return clone;
@@ -120,9 +114,9 @@
     return rb_mod_init_copy(clone, orig);
 }
 
-static VALUE
-singleton_class_clone_int(obj, nklass)
-    VALUE obj, nklass;
+VALUE
+rb_singleton_class_clone(obj)
+    VALUE obj;
 {
     VALUE klass = RBASIC(obj)->klass;
 
@@ -146,21 +140,28 @@
 	if (RCLASS(klass)->iv_tbl) {
 	    clone->iv_tbl = st_copy(RCLASS(klass)->iv_tbl);
 	}
-	clone->m_tbl = st_init_numtable();
-	st_foreach(RCLASS(klass)->m_tbl, clone_method, NIL_P(nklass) ? (VALUE)clone : nklass);
+	{
+	    struct clone_method_data data;
+
+	    data.tbl = clone->m_tbl = st_init_numtable();
+	    switch (TYPE(obj)) {
+	      case T_CLASS:
+	      case T_MODULE:
+		data.klass = obj;
+		break;
+	      default:
+		data.klass = 0;
+		break;
+	    }
+
+	    st_foreach(RCLASS(klass)->m_tbl, clone_method, (st_data_t)&data);
+	}
 	rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
 	FL_SET(clone, FL_SINGLETON);
 	return (VALUE)clone;
     }
 }
 
-VALUE
-rb_singleton_class_clone(obj)
-    VALUE obj;
-{
-    return singleton_class_clone_int(obj, Qnil);
-}
-
 void
 rb_singleton_class_attached(klass, obj)
     VALUE klass, obj;
diff -burN ruby-1.8.7-p22/common.mk ruby-1.8.7-p72/common.mk
--- ruby-1.8.7-p22/common.mk	2008-05-23 07:22:13.000000000 +0200
+++ ruby-1.8.7-p72/common.mk	2008-08-04 07:05:38.000000000 +0200
@@ -5,7 +5,7 @@
 RUBYLIB       = -
 RUBYOPT       = -
 
-SPEC_GIT_BASE = git://github.com/brixen
+SPEC_GIT_BASE = git://github.com/rubyspec
 MSPEC_GIT_URL = $(SPEC_GIT_BASE)/mspec.git
 RUBYSPEC_GIT_URL = $(SPEC_GIT_BASE)/rubyspec.git
 
@@ -362,7 +362,8 @@
   {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
   {$(VPATH)}util.h {$(VPATH)}st.h
 bignum.$(OBJEXT): {$(VPATH)}bignum.c {$(VPATH)}ruby.h config.h \
-  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h
+  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
+  {$(VPATH)}rubysig.h
 class.$(OBJEXT): {$(VPATH)}class.c {$(VPATH)}ruby.h config.h \
   {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
   {$(VPATH)}rubysig.h {$(VPATH)}node.h {$(VPATH)}st.h
diff -burN ruby-1.8.7-p22/configure ruby-1.8.7-p72/configure
--- ruby-1.8.7-p22/configure	2008-06-20 11:30:12.000000000 +0200
+++ ruby-1.8.7-p72/configure	2008-08-11 02:39:51.000000000 +0200
@@ -13218,6 +13218,74 @@
 done
 
 
+# http://sources.redhat.com/ml/libc-hacker/2005-08/msg00008.html
+# Debian GNU/Linux Etch's libc6.1 2.3.6.ds1-13etch5 has this problem.
+# Debian GNU/Linux Lenny's libc6.1 2.7-10 has no problem.
+{ echo "$as_me:$LINENO: checking for broken erfc of glibc-2.3.6 on IA64" >&5
+echo $ECHO_N "checking for broken erfc of glibc-2.3.6 on IA64... $ECHO_C" >&6; }
+if test "${rb_broken_glibc_ia64_erfc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  rb_broken_glibc_ia64_erfc=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <math.h>
+int
+main()
+{
+   erfc(10000.0);
+   return 0;
+}
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  rb_broken_glibc_ia64_erfc=no
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+rb_broken_glibc_ia64_erfc=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+{ echo "$as_me:$LINENO: result: $rb_broken_glibc_ia64_erfc" >&5
+echo "${ECHO_T}$rb_broken_glibc_ia64_erfc" >&6; }
+case $rb_broken_glibc_ia64_erfc in
+  yes) ac_cv_func_erf=no;;
+esac
+
+
 
 
 
diff -burN ruby-1.8.7-p22/configure.in ruby-1.8.7-p72/configure.in
--- ruby-1.8.7-p22/configure.in	2008-06-15 12:28:47.000000000 +0200
+++ ruby-1.8.7-p72/configure.in	2008-07-12 17:06:09.000000000 +0200
@@ -559,6 +559,27 @@
 AC_FUNC_MEMCMP
 AC_FUNC_FSEEKO
 AC_CHECK_FUNCS(ftello)
+
+# http://sources.redhat.com/ml/libc-hacker/2005-08/msg00008.html
+# Debian GNU/Linux Etch's libc6.1 2.3.6.ds1-13etch5 has this problem.
+# Debian GNU/Linux Lenny's libc6.1 2.7-10 has no problem.
+AC_CACHE_CHECK(for broken erfc of glibc-2.3.6 on IA64, rb_broken_glibc_ia64_erfc,
+  [AC_TRY_RUN([
+#include <math.h>
+int
+main()
+{
+   erfc(10000.0);
+   return 0;
+}
+],
+	rb_broken_glibc_ia64_erfc=no,
+	rb_broken_glibc_ia64_erfc=yes,
+	rb_broken_glibc_ia64_erfc=no)])
+case $rb_broken_glibc_ia64_erfc in
+  yes) ac_cv_func_erf=no;;
+esac
+
 AC_REPLACE_FUNCS(dup2 memmove strcasecmp strncasecmp strerror strftime\
 		 strchr strstr strtoul crypt flock vsnprintf\
 		 isnan finite isinf hypot acosh erf)
diff -burN ruby-1.8.7-p22/error.c ruby-1.8.7-p72/error.c
--- ruby-1.8.7-p22/error.c	2008-05-31 15:37:06.000000000 +0200
+++ ruby-1.8.7-p72/error.c	2008-08-04 05:24:26.000000000 +0200
@@ -2,8 +2,8 @@
 
   error.c -
 
-  $Author: knu $
-  $Date: 2008-05-31 22:37:06 +0900 (Sat, 31 May 2008) $
+  $Author: shyouhei $
+  $Date: 2008-08-04 12:24:26 +0900 (Mon, 04 Aug 2008) $
   created at: Mon Aug  9 16:11:34 JST 1993
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -333,7 +333,7 @@
     VALUE etype, str;
 {
     StringValue(str);
-    return rb_exc_new(etype, RSTRING(str)->ptr, RSTRING(str)->len);
+    return rb_funcall(etype, rb_intern("new"), 1, str);
 }
 
 /*
diff -burN ruby-1.8.7-p22/eval.c ruby-1.8.7-p72/eval.c
--- ruby-1.8.7-p22/eval.c	2008-05-31 13:44:49.000000000 +0200
+++ ruby-1.8.7-p72/eval.c	2008-08-04 05:24:26.000000000 +0200
@@ -2,8 +2,8 @@
 
   eval.c -
 
-  $Author: knu $
-  $Date: 2008-05-31 20:44:49 +0900 (Sat, 31 May 2008) $
+  $Author: shyouhei $
+  $Date: 2008-08-04 12:24:26 +0900 (Mon, 04 Aug 2008) $
   created at: Thu Jun 10 14:22:17 JST 1993
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -758,7 +758,7 @@
 static unsigned long frame_unique = 0;
 
 #define PUSH_FRAME() do {		\
-    struct FRAME _frame;		\
+    volatile struct FRAME _frame;	\
     _frame.prev = ruby_frame;		\
     _frame.tmp  = 0;			\
     _frame.node = ruby_current_node;	\
@@ -1055,7 +1055,7 @@
 static VALUE ruby_wrapper;	/* security wrapper */
 
 #define PUSH_CLASS(c) do {		\
-    VALUE _class = ruby_class;		\
+    volatile VALUE _class = ruby_class;	\
     ruby_class = (c)
 
 #define POP_CLASS() ruby_class = _class; \
@@ -1441,9 +1441,6 @@
 static void rb_thread_cleanup _((void));
 static void rb_thread_wait_other_threads _((void));
 
-static int thread_set_raised();
-static int thread_reset_raised();
-
 static int thread_no_ensure _((void));
 
 static VALUE exception_error;
@@ -1462,8 +1459,10 @@
     int ex;
 {
     int status = EXIT_FAILURE;
+    rb_thread_t th = curr_thread;
 
-    if (thread_set_raised()) return EXIT_FAILURE;
+    if (rb_thread_set_raised(th))
+	return EXIT_FAILURE;
     switch (ex & TAG_MASK) {
       case 0:
 	status = EXIT_SUCCESS;
@@ -1516,7 +1515,7 @@
 	rb_bug("Unknown longjmp status %d", ex);
 	break;
     }
-    thread_reset_raised();
+    rb_thread_reset_raised(th);
     return status;
 }
 
@@ -2709,6 +2708,7 @@
     NODE *node_save;
     VALUE srcfile;
     const char *event_name;
+    rb_thread_t th = curr_thread;
 
     if (!trace_func) return;
     if (tracing) return;
@@ -2740,7 +2740,7 @@
 	}
     }
     PUSH_TAG(PROT_NONE);
-    raised = thread_reset_raised();
+    raised = rb_thread_reset_raised(th);
     if ((state = EXEC_TAG()) == 0) {
 	srcfile = rb_str_new2(ruby_sourcefile?ruby_sourcefile:"(ruby)");
 	event_name = get_event_name(event);
@@ -2752,7 +2752,7 @@
 					    klass),
 		    Qundef, 0);
     }
-    if (raised) thread_set_raised();
+    if (raised) rb_thread_set_raised(th);
     POP_TAG();
     POP_FRAME();
 
@@ -4233,7 +4233,7 @@
 	int n = 0;
 	args[n++] = ID2SYM(id);
 	if (priv) args[n++] = Qtrue;
-	return rb_funcall2(obj, respond_to, n, args);
+	return RTEST(rb_funcall2(obj, respond_to, n, args));
     }
 }
 
@@ -4571,8 +4571,9 @@
     VALUE mesg;
 {
     VALUE at;
+    rb_thread_t th = curr_thread;
 
-    if (thread_set_raised()) {
+    if (rb_thread_set_raised(th)) {
 	ruby_errinfo = exception_error;
 	JUMP_TAG(TAG_FATAL);
     }
@@ -4586,6 +4587,9 @@
 	at = get_backtrace(mesg);
 	if (NIL_P(at)) {
 	    at = make_backtrace();
+	    if (OBJ_FROZEN(mesg)) {
+		mesg = rb_obj_dup(mesg);
+	    }
 	    set_backtrace(mesg, at);
 	}
     }
@@ -4611,7 +4615,7 @@
 	    ruby_errinfo = mesg;
 	}
 	else if (status) {
-	    thread_reset_raised();
+	    rb_thread_reset_raised(th);
 	    JUMP_TAG(status);
 	}
     }
@@ -4626,11 +4630,20 @@
     if (!prot_tag) {
 	error_print();
     }
-    thread_reset_raised();
+    rb_thread_raised_clear(th);
     JUMP_TAG(tag);
 }
 
 void
+rb_exc_jump(mesg)
+    VALUE mesg;
+{
+    rb_thread_raised_clear(rb_curr_thread);
+    ruby_errinfo = mesg;
+    JUMP_TAG(TAG_RAISE);
+}
+
+void
 rb_exc_raise(mesg)
     VALUE mesg;
 {
@@ -5578,19 +5591,12 @@
 static void
 stack_check()
 {
-    static int overflowing = 0;
+    rb_thread_t th = rb_curr_thread;
 
-    if (!overflowing && ruby_stack_check()) {
-	int state;
-	overflowing = 1;
-	PUSH_TAG(PROT_NONE);
-	if ((state = EXEC_TAG()) == 0) {
+    if (!rb_thread_raised_p(th, RAISED_STACKOVERFLOW) && ruby_stack_check()) {
+	rb_thread_raised_set(th, RAISED_STACKOVERFLOW);
 	    rb_exc_raise(sysstack_error);
 	}
-	POP_TAG();
-	overflowing = 0;
-	JUMP_TAG(state);
-    }
 }
 
 static int last_call_status;
@@ -5828,8 +5834,7 @@
     TMP_PROTECT;
     volatile int safe = -1;
 
-    if (NOEX_SAFE(flags) > ruby_safe_level &&
-	ruby_safe_level == 0 && NOEX_SAFE(flags) > 2) {
+    if (NOEX_SAFE(flags) > ruby_safe_level && NOEX_SAFE(flags) > 2) {
 	rb_raise(rb_eSecurityError, "calling insecure method: %s",
 		 rb_id2name(id));
     }
@@ -9987,12 +9992,17 @@
     rb_define_method(rb_eLocalJumpError, "reason", localjump_reason, 0);
 
     rb_global_variable(&exception_error);
-    exception_error = rb_exc_new2(rb_eFatal, "exception reentered");
+    exception_error = rb_exc_new3(rb_eFatal,
+				  rb_obj_freeze(rb_str_new2("exception reentered")));
+    OBJ_TAINT(exception_error);
+    OBJ_FREEZE(exception_error);
 
     rb_eSysStackError = rb_define_class("SystemStackError", rb_eStandardError);
     rb_global_variable(&sysstack_error);
-    sysstack_error = rb_exc_new2(rb_eSysStackError, "stack level too deep");
+    sysstack_error = rb_exc_new3(rb_eSysStackError,
+				 rb_obj_freeze(rb_str_new2("stack level too deep")));
     OBJ_TAINT(sysstack_error);
+    OBJ_FREEZE(sysstack_error);
 
     rb_cProc = rb_define_class("Proc", rb_cObject);
     rb_undef_alloc_func(rb_cProc);
@@ -10170,10 +10180,9 @@
 # endif
 #endif
 
-#define THREAD_RAISED 0x200	 /* temporary flag */
 #define THREAD_TERMINATING 0x400 /* persistent flag */
 #define THREAD_NO_ENSURE 0x800   /* persistent flag */
-#define THREAD_FLAGS_MASK  0xc00 /* mask for persistent flags */
+#define THREAD_FLAGS_MASK 0xfc00 /* mask for persistent flags */
 
 #define FOREACH_THREAD_FROM(f,x) x = f; do { x = x->next;
 #define END_FOREACH_FROM(f,x) } while (x != f)
@@ -10225,19 +10234,25 @@
     (dst)->join = (src)->join,			\
     0)
 
-static int
-thread_set_raised()
+int
+rb_thread_set_raised(th)
+    rb_thread_t th;
 {
-    if (curr_thread->flags & THREAD_RAISED) return 1;
-    curr_thread->flags |= THREAD_RAISED;
+    if (th->flags & RAISED_EXCEPTION) {
+	return 1;
+    }
+    th->flags |= RAISED_EXCEPTION;
     return 0;
 }
 
-static int
-thread_reset_raised()
+int
+rb_thread_reset_raised(th)
+    rb_thread_t th;
 {
-    if (!(curr_thread->flags & THREAD_RAISED)) return 0;
-    curr_thread->flags &= ~THREAD_RAISED;
+    if (!(th->flags & RAISED_EXCEPTION)) {
+	return 0;
+    }
+    th->flags &= ~RAISED_EXCEPTION;
     return 1;
 }
 
@@ -11375,7 +11390,7 @@
 	if (!rb_thread_dead(th)) return Qfalse;
     }
 
-    if (!NIL_P(th->errinfo) && (th->flags & THREAD_RAISED)) {
+    if (!NIL_P(th->errinfo) && (th->flags & RAISED_EXCEPTION)) {
 	VALUE oldbt = get_backtrace(th->errinfo);
 	VALUE errat = make_backtrace();
 	VALUE errinfo = rb_obj_dup(th->errinfo);
@@ -12251,7 +12266,7 @@
     }
 
     if (state && status != THREAD_TO_KILL && !NIL_P(ruby_errinfo)) {
-	th->flags |= THREAD_RAISED;
+	th->flags |= RAISED_EXCEPTION;
 	if (state == TAG_FATAL) {
 	    /* fatal error within this thread, need to stop whole script */
 	    main_thread->errinfo = ruby_errinfo;
@@ -12469,7 +12484,7 @@
     rb_thread_t th = rb_thread_check(thread);
 
     if (rb_thread_dead(th)) {
-	if (!NIL_P(th->errinfo) && (th->flags & THREAD_RAISED))
+	if (!NIL_P(th->errinfo) && (th->flags & RAISED_EXCEPTION))
 	    return Qnil;
 	return Qfalse;
     }
diff -burN ruby-1.8.7-p22/ext/dl/dl.c ruby-1.8.7-p72/ext/dl/dl.c
--- ruby-1.8.7-p22/ext/dl/dl.c	2008-04-15 05:35:55.000000000 +0200
+++ ruby-1.8.7-p72/ext/dl/dl.c	2008-08-11 02:37:21.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * $Id: dl.c 16025 2008-04-15 03:35:55Z nobu $
+ * $Id: dl.c 18479 2008-08-11 00:37:21Z shyouhei $
  */
 
 #include <ruby.h>
@@ -522,12 +522,15 @@
 {
   char *ptr;
   int  len;
+  VALUE p;
 
   len = RSTRING(self)->len;
   ptr = (char*)dlmalloc(len + 1);
   memcpy(ptr, RSTRING(self)->ptr, len);
   ptr[len] = '\0';
-  return rb_dlptr_new((void*)ptr,len,dlfree);
+  p = rb_dlptr_new((void*)ptr,len,dlfree);
+  OBJ_INFECT(p, self);
+  return p;
 }
 
 VALUE
@@ -545,7 +548,12 @@
     ptr = rb_ary2cary(0, self, &size);
     break;
   }
-  return ptr ? rb_dlptr_new(ptr, size, dlfree) : Qnil;
+  if (ptr) {
+      VALUE p = rb_dlptr_new(ptr, size, dlfree);
+      OBJ_INFECT(p, self);
+      return p;
+  }
+  return Qnil;
 }
 
 VALUE
@@ -563,7 +571,7 @@
 VALUE
 rb_dl_dlopen(int argc, VALUE argv[], VALUE self)
 {
-  rb_secure(4);
+  rb_secure(2);
   return rb_class_new_instance(argc, argv, rb_cDLHandle);
 }
 
diff -burN ruby-1.8.7-p22/ext/dl/sym.c ruby-1.8.7-p72/ext/dl/sym.c
--- ruby-1.8.7-p22/ext/dl/sym.c	2007-07-22 07:33:47.000000000 +0200
+++ ruby-1.8.7-p72/ext/dl/sym.c	2008-08-11 02:37:21.000000000 +0200
@@ -1,5 +1,5 @@
 /* -*- C -*-
- * $Id: sym.c 12835 2007-07-22 05:33:47Z nobu $
+ * $Id: sym.c 18479 2008-08-11 00:37:21Z shyouhei $
  */
 
 #include <ruby.h>
@@ -492,6 +492,7 @@
 	      rb_raise(rb_eDLTypeError, "unexpected type of argument #%d", i);
 	    }
 	  }
+	  rb_check_safe_obj(pval);
 	  Data_Get_Struct(pval, struct ptr_data, data);
 	  ANY2P(args[i]) = DLVOIDP(data->ptr);
 	}
diff -burN ruby-1.8.7-p22/ext/openssl/openssl_missing.h ruby-1.8.7-p72/ext/openssl/openssl_missing.h
--- ruby-1.8.7-p22/ext/openssl/openssl_missing.h	2008-05-19 05:00:52.000000000 +0200
+++ ruby-1.8.7-p72/ext/openssl/openssl_missing.h	2008-08-04 06:44:17.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * $Id: openssl_missing.h 16467 2008-05-19 03:00:52Z knu $
+ * $Id: openssl_missing.h 18335 2008-08-04 04:44:17Z shyouhei $
  * 'OpenSSL for Ruby' project
  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
  * All rights reserved.
@@ -15,6 +15,10 @@
 extern "C" {
 #endif
 
+#ifndef TYPEDEF_D2I_OF
+typedef char *d2i_of_void();
+#endif
+
 /*
  * These functions are not included in headers of OPENSSL <= 0.9.6b
  */
diff -burN ruby-1.8.7-p22/ext/openssl/ossl.h ruby-1.8.7-p72/ext/openssl/ossl.h
--- ruby-1.8.7-p22/ext/openssl/ossl.h	2007-07-15 15:24:51.000000000 +0200
+++ ruby-1.8.7-p72/ext/openssl/ossl.h	2008-06-29 10:16:02.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * $Id: ossl.h 12800 2007-07-15 13:24:51Z nobu $
+ * $Id: ossl.h 17656 2008-06-29 08:16:02Z shyouhei $
  * 'OpenSSL for Ruby' project
  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
  * All rights reserved.
@@ -46,7 +46,11 @@
 
 #if defined(_WIN32)
 #  define OSSL_NO_CONF_API 1
+#  ifdef USE_WINSOCK2
 #  include <winsock2.h>
+#  else
+#    include <winsock.h>
+#  endif
 #endif
 #include <errno.h>
 #include <openssl/err.h>
diff -burN ruby-1.8.7-p22/ext/stringio/stringio.c ruby-1.8.7-p72/ext/stringio/stringio.c
--- ruby-1.8.7-p22/ext/stringio/stringio.c	2008-05-27 12:07:07.000000000 +0200
+++ ruby-1.8.7-p72/ext/stringio/stringio.c	2008-06-29 10:22:39.000000000 +0200
@@ -2,8 +2,8 @@
 
   stringio.c -
 
-  $Author: knu $
-  $Date: 2008-05-27 19:07:07 +0900 (Tue, 27 May 2008) $
+  $Author: shyouhei $
+  $Date: 2008-06-29 17:22:39 +0900 (Sun, 29 Jun 2008) $
   $RoughId: stringio.c,v 1.13 2002/03/14 03:24:18 nobu Exp $
   created at: Tue Feb 19 04:10:38 JST 2002
 
@@ -990,7 +990,7 @@
     VALUE *argv;
     VALUE self;
 {
-    VALUE line = strio_getline(argc, argv, readable(StringIO(self)));
+    VALUE line = strio_gets(argc, argv, self);
     if (NIL_P(line)) rb_eof_error();
     return line;
 }
diff -burN ruby-1.8.7-p22/ext/syslog/syslog.c ruby-1.8.7-p72/ext/syslog/syslog.c
--- ruby-1.8.7-p22/ext/syslog/syslog.c	2007-02-13 00:01:19.000000000 +0100
+++ ruby-1.8.7-p72/ext/syslog/syslog.c	2008-07-02 11:58:40.000000000 +0200
@@ -4,7 +4,7 @@
  * <amos+ruby@utdallas.edu>
  *
  * $RoughId: syslog.c,v 1.21 2002/02/25 12:21:17 knu Exp $
- * $Id: syslog.c 11708 2007-02-12 23:01:19Z shyouhei $
+ * $Id: syslog.c 17809 2008-07-02 09:58:40Z shyouhei $
  */
 
 #include "ruby.h"
@@ -22,6 +22,7 @@
 {
     VALUE str;
 
+    rb_secure(4);
     if (argc < 1) {
         rb_raise(rb_eArgError, "no log message supplied");
     }
@@ -38,6 +39,7 @@
 /* Syslog module methods */
 static VALUE mSyslog_close(VALUE self)
 {
+    rb_secure(4);
     if (!syslog_opened) {
         rb_raise(rb_eRuntimeError, "syslog not opened");
     }
@@ -132,6 +134,7 @@
 
 static VALUE mSyslog_set_mask(VALUE self, VALUE mask)
 {
+    rb_secure(4);
     if (!syslog_opened) {
         rb_raise(rb_eRuntimeError, "must open syslog before setting log mask");
     }
diff -burN ruby-1.8.7-p22/ext/win32ole/tests/testall.rb ruby-1.8.7-p72/ext/win32ole/tests/testall.rb
--- ruby-1.8.7-p22/ext/win32ole/tests/testall.rb	2007-02-13 00:01:19.000000000 +0100
+++ ruby-1.8.7-p72/ext/win32ole/tests/testall.rb	2008-07-07 05:29:28.000000000 +0200
@@ -12,4 +12,5 @@
 require "test_ole_methods.rb"
 require "test_propertyputref.rb"
 require "test_word.rb"
+require "test_win32ole_event.rb"
 # require "testOLEEVENT"
diff -burN ruby-1.8.7-p22/ext/win32ole/tests/testOLEEVENT.rb ruby-1.8.7-p72/ext/win32ole/tests/testOLEEVENT.rb
--- ruby-1.8.7-p22/ext/win32ole/tests/testOLEEVENT.rb	2007-02-13 00:01:19.000000000 +0100
+++ ruby-1.8.7-p72/ext/win32ole/tests/testOLEEVENT.rb	1970-01-01 01:00:00.000000000 +0100
@@ -1,91 +0,0 @@
-require 'rubyunit'
-require 'win32ole'
-
-class TestWIN32OLE_EVENT < RUNIT::TestCase
-  def setup
-    @excel = WIN32OLE.new("Excel.Application")
-    @excel.visible = true
-    @event = ""
-    @event2 = ""
-  end
-  def test_on_event
-    book = @excel.workbooks.Add
-    value = ""
-    begin
-      ev = WIN32OLE_EVENT.new(book, 'WorkbookEvents')
-      ev.on_event('SheetChange'){|arg1, arg2| 
-        begin
-          value = arg1.value
-        rescue
-          value = $!.message
-        end
-      }
-      book.Worksheets(1).Range("A1").value = "OK"
-    ensure
-      book.saved = true
-    end
-    assert_equal("OK", value)
-  end
-
-  def handler1
-    @event += "handler1"
-  end
-  def handler2
-    @event += "handler2"
-  end
-
-  def handler3
-    @event += "handler3"
-  end
-
-  def test_on_event2
-    book = @excel.workbooks.Add
-    begin
-      ev = WIN32OLE_EVENT.new(book, 'WorkbookEvents')
-      ev.on_event('SheetChange'){|arg1, arg2| 
-        handler1
-      }
-      ev.on_event('SheetChange'){|arg1, arg2| 
-        handler2
-      }
-      book.Worksheets(1).Range("A1").value = "OK"
-    ensure
-      book.saved = true
-    end
-    assert_equal("handler2", @event)
-  end
-
-  def test_on_event3
-    book = @excel.workbooks.Add
-    begin
-      ev = WIN32OLE_EVENT.new(book, 'WorkbookEvents')
-      ev.on_event{ handler1 }
-      ev.on_event{ handler2 }
-      book.Worksheets(1).Range("A1").value = "OK"
-    ensure
-      book.saved = true
-    end
-    assert_equal("handler2", @event)
-  end
-
-  def test_on_event4
-    book = @excel.workbooks.Add
-    begin
-      ev = WIN32OLE_EVENT.new(book, 'WorkbookEvents')
-      ev.on_event{ handler1 }
-      ev.on_event{ handler2 }
-      ev.on_event('SheetChange'){|arg1, arg2| handler3 }
-      book.Worksheets(1).Range("A1").value = "OK"
-    ensure
-      book.saved = true
-    end
-    assert_equal("handler3", @event)
-  end
-
-  def teardown
-    @excel.quit
-    @excel = nil
-    GC.start
-  end
-end
-
diff -burN ruby-1.8.7-p22/ext/win32ole/tests/test_win32ole_event.rb ruby-1.8.7-p72/ext/win32ole/tests/test_win32ole_event.rb
--- ruby-1.8.7-p22/ext/win32ole/tests/test_win32ole_event.rb	1970-01-01 01:00:00.000000000 +0100
+++ ruby-1.8.7-p72/ext/win32ole/tests/test_win32ole_event.rb	2008-07-07 09:40:23.000000000 +0200
@@ -0,0 +1,133 @@
+begin
+  require 'win32ole'
+rescue LoadError
+end
+require 'test/unit'
+
+if defined?(WIN32OLE_EVENT)
+  class TestWIN32OLE_EVENT < Test::Unit::TestCase
+    def create_temp_html
+      fso = WIN32OLE.new('Scripting.FileSystemObject')
+      dummy_file = fso.GetTempName + ".html"
+      cfolder = fso.getFolder(".")
+      f = cfolder.CreateTextFile(dummy_file)
+      f.writeLine("<html><body>This is test HTML file for Win32OLE.</body></html>")
+      f.close
+      dummy_path = cfolder.path + "\\" + dummy_file
+      dummy_path
+    end
+
+    def setup
+      @ie = WIN32OLE.new("InternetExplorer.Application")
+      @ie.visible = true
+      @event = ""
+      @event2 = ""
+      @event3 = ""
+      @f = create_temp_html
+    end
+
+    def default_handler(event, *args)
+      @event += event
+    end
+
+    def test_on_event
+      ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
+      ev.on_event {|*args| default_handler(*args)}
+      @ie.navigate("file:///#{@f}")
+      while @ie.busy
+        WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents') 
+        GC.start  
+        sleep 0.1
+      end
+      assert_match(/BeforeNavigate/, @event)
+      assert_match(/NavigateComplete/, @event)
+    end
+
+    def test_on_event2
+      ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
+      ev.on_event('BeforeNavigate') {|*args| handler1}
+      ev.on_event('BeforeNavigate') {|*args| handler2}
+      @ie.navigate("file:///#{@f}")
+      while @ie.busy
+        sleep 0.1
+      end
+      assert_equal("handler2", @event2)
+    end
+
+    def test_on_event3
+      ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
+      ev.on_event {|*args| handler1}
+      ev.on_event {|*args| handler2}
+      @ie.navigate("file:///#{@f}")
+      while @ie.busy
+        sleep 0.1
+      end
+      assert_equal("handler2", @event2)
+    end
+
+    def test_on_event4
+      ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
+      ev.on_event{|*args| handler1}
+      ev.on_event{|*args| handler2}
+      ev.on_event('NavigateComplete'){|*args| handler3(*args)}
+      @ie.navigate("file:///#{@f}")
+      while @ie.busy
+        sleep 0.1
+      end
+      assert(@event3!="")
+      assert("handler2", @event2)
+    end
+
+    def test_on_event5
+      ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
+      ev.on_event {|*args| default_handler(*args)}
+      ev.on_event('NavigateComplete'){|*args| handler3(*args)}
+      @ie.navigate("file:///#{@f}")
+      while @ie.busy
+        sleep 0.1
+      end
+      assert_match(/BeforeNavigate/, @event)
+      assert(/NavigateComplete/ !~ @event)
+      assert(@event!="")
+    end
+
+    def test_unadvise
+      ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
+      ev.on_event {|*args| default_handler(*args)}
+      @ie.navigate("file:///#{@f}")
+      while @ie.busy
+        sleep 0.1
+      end
+      assert_match(/BeforeNavigate/, @event)
+      ev.unadvise
+      @event = ""
+      @ie.navigate("file:///#{@f}")
+      while @ie.busy
+        sleep 0.1
+      end
+      assert_equal("", @event);
+      assert_raise(WIN32OLERuntimeError) {
+        ev.on_event {|*args| default_handler(*args)}
+      }
+    end
+
+    def handler1
+      @event2 = "handler1"
+    end
+
+    def handler2
+      @event2 = "handler2"
+    end
+
+    def handler3(url)
+      @event3 += url
+    end
+
+    def teardown
+      @ie.quit
+      @ie = nil
+      File.unlink(@f)
+      GC.start
+    end
+  end
+end
diff -burN ruby-1.8.7-p22/ext/win32ole/tests/testWIN32OLE.rb ruby-1.8.7-p72/ext/win32ole/tests/testWIN32OLE.rb
--- ruby-1.8.7-p22/ext/win32ole/tests/testWIN32OLE.rb	2007-02-13 00:01:19.000000000 +0100
+++ ruby-1.8.7-p72/ext/win32ole/tests/testWIN32OLE.rb	2008-07-07 05:29:28.000000000 +0200
@@ -156,7 +156,8 @@
       sheet.range("A3").value = "=A1*10 + 9"
       assert_equal(9999999999, sheet.range("A2").value)
       assert_equal(9999999999, sheet.range("A3").value)
-     
+      sheet.range("A4").value = "2008/03/04"
+      assert_equal("2008/03/04 00:00:00", sheet.range("A4").value)
     ensure
       book.saved = true
     end
diff -burN ruby-1.8.7-p22/ext/win32ole/win32ole.c ruby-1.8.7-p72/ext/win32ole/win32ole.c
--- ruby-1.8.7-p22/ext/win32ole/win32ole.c	2007-11-17 06:25:09.000000000 +0100
+++ ruby-1.8.7-p72/ext/win32ole/win32ole.c	2008-07-07 05:29:28.000000000 +0200
@@ -12,7 +12,7 @@
  */
 
 /*
-  $Date: 2007-11-17 14:25:09 +0900 (Sat, 17 Nov 2007) $
+  $Date: 2008-07-07 12:29:28 +0900 (Mon, 07 Jul 2008) $
   modified for win32ole (ruby) by Masaki.Suketa <masaki.suketa@nifty.ne.jp>
  */
 
@@ -29,7 +29,7 @@
 #include <varargs.h>
 #define va_init_list(a,b) va_start(a)
 #endif
-
+#include <objidl.h>
 
 #define DOUT fprintf(stderr,"[%d]\n",__LINE__)
 #define DOUTS(x) fprintf(stderr,"[%d]:" #x "=%s\n",__LINE__,x)
@@ -79,7 +79,7 @@
 
 #define WC2VSTR(x) ole_wc2vstr((x), TRUE)
 
-#define WIN32OLE_VERSION "0.7.4"
+#define WIN32OLE_VERSION "0.7.6"
 
 typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
     (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
@@ -157,6 +157,9 @@
 static IDispatchVtbl com_vtbl;
 static UINT  cWIN32OLE_cp = CP_ACP;
 static VARTYPE g_nil_to = VT_ERROR;
+static IMessageFilterVtbl message_filter;
+static IMessageFilter imessage_filter = { &message_filter };
+static IMessageFilter* previous_filter;
 
 struct oledata {
     IDispatch *pDispatch;
@@ -203,6 +206,101 @@
 static VALUE ole_variant2val(VARIANT*);
 static void ole_val2variant(VALUE, VARIANT*);
   
+static HRESULT (STDMETHODCALLTYPE mf_QueryInterface)(
+    IMessageFilter __RPC_FAR * This,
+    /* [in] */ REFIID riid,
+    /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
+{
+    if (MEMCMP(riid, &IID_IUnknown, GUID, 1) == 0
+        || MEMCMP(riid, &IID_IMessageFilter, GUID, 1) == 0)
+    {
+        *ppvObject = &message_filter;
+        return S_OK;
+    }
+    return E_NOINTERFACE;
+}
+
+static ULONG (STDMETHODCALLTYPE mf_AddRef)( 
+    IMessageFilter __RPC_FAR * This)
+{
+    return 1;
+}
+        
+static ULONG (STDMETHODCALLTYPE mf_Release)( 
+    IMessageFilter __RPC_FAR * This)
+{
+    return 1;
+}
+
+static DWORD (STDMETHODCALLTYPE mf_HandleInComingCall)(
+    IMessageFilter __RPC_FAR * pThis,
+    DWORD dwCallType,      //Type of incoming call
+    HTASK threadIDCaller,  //Task handle calling this task
+    DWORD dwTickCount,     //Elapsed tick count
+    LPINTERFACEINFO lpInterfaceInfo //Pointer to INTERFACEINFO structure
+    )
+{
+#ifdef DEBUG_MESSAGEFILTER
+    printf("incoming %08X, %08X, %d\n", dwCallType, threadIDCaller, dwTickCount);
+    fflush(stdout);
+#endif
+    switch (dwCallType)
+    {
+    case CALLTYPE_ASYNC:
+    case CALLTYPE_TOPLEVEL_CALLPENDING:
+    case CALLTYPE_ASYNC_CALLPENDING:
+        if (rb_during_gc()) {
+            return SERVERCALL_RETRYLATER;
+        }
+        break;
+    default:
+        break;
+    }
+    if (previous_filter) {
+        return previous_filter->lpVtbl->HandleInComingCall(previous_filter,
+                                                   dwCallType,
+                                                   threadIDCaller,
+                                                   dwTickCount,
+                                                   lpInterfaceInfo);
+    }
+    return SERVERCALL_ISHANDLED;
+}
+
+static DWORD (STDMETHODCALLTYPE mf_RetryRejectedCall)(
+    IMessageFilter* pThis,
+    HTASK threadIDCallee,  //Server task handle
+    DWORD dwTickCount,     //Elapsed tick count
+    DWORD dwRejectType     //Returned rejection message
+    )
+{
+    if (previous_filter) {
+        return previous_filter->lpVtbl->RetryRejectedCall(previous_filter,
+                                                  threadIDCallee,
+                                                  dwTickCount,
+                                                  dwRejectType);
+    }
+    return 1000;
+}
+
+static DWORD (STDMETHODCALLTYPE mf_MessagePending)(
+    IMessageFilter* pThis,
+    HTASK threadIDCallee,  //Called applications task handle
+    DWORD dwTickCount,     //Elapsed tick count
+    DWORD dwPendingType    //Call type
+    )
+{
+    if (rb_during_gc()) {
+        return PENDINGMSG_WAITNOPROCESS;
+    }
+    if (previous_filter) {
+        return previous_filter->lpVtbl->MessagePending(previous_filter,
+                                               threadIDCallee,
+                                               dwTickCount,
+                                               dwPendingType);
+    }
+    return PENDINGMSG_WAITNOPROCESS;
+}
+    
 typedef struct _Win32OLEIDispatch
 {
     IDispatch dispatch;
@@ -459,7 +557,7 @@
     double date;
 {
     int y, m, d, hh, mm, ss;
-    char szTime[20];
+    char szTime[40];
     double2time(date, &y, &m, &d, &hh, &mm, &ss);
     sprintf(szTime,
             "%4.4d/%02.2d/%02.2d %02.2d:%02.2d:%02.2d",
@@ -522,6 +620,15 @@
     return msg;
 }
 
+static void
+ole_freeexceptinfo(pExInfo)
+    EXCEPINFO *pExInfo;
+{
+    SysFreeString(pExInfo->bstrDescription);
+    SysFreeString(pExInfo->bstrSource);
+    SysFreeString(pExInfo->bstrHelpFile);
+}
+
 static VALUE
 ole_excepinfo2msg(pExInfo)
     EXCEPINFO *pExInfo;
@@ -561,9 +668,7 @@
     }
     if(pSource) free(pSource);
     if(pDescription) free(pDescription);
-    SysFreeString(pExInfo->bstrDescription);
-    SysFreeString(pExInfo->bstrSource);
-    SysFreeString(pExInfo->bstrHelpFile);
+    ole_freeexceptinfo(pExInfo);
     return error_msg;
 }
 
@@ -618,6 +723,11 @@
         /*
         atexit((void (*)(void))ole_uninitialize);
         */
+        hr = CoRegisterMessageFilter(&imessage_filter, &previous_filter);
+        if(FAILED(hr)) {
+            previous_filter = NULL;
+            ole_raise(hr, rb_eRuntimeError, "fail: install OLE MessageFilter");
+        }
     }
 }
 
@@ -2109,6 +2219,9 @@
                 param = rb_ary_entry(paramS, i-cNamedArgs);
                 ole_val2variant(param, &op.dp.rgvarg[n]);
             }
+            if (hr == DISP_E_EXCEPTION) {
+                ole_freeexceptinfo(&excepinfo);
+            }
             memset(&excepinfo, 0, sizeof(EXCEPINFO));
             VariantInit(&result);
             hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID, 
@@ -2121,6 +2234,9 @@
              * hResult == DISP_E_EXCEPTION. this only happens on
              * functions whose DISPID > 0x8000 */
             if ((hr == DISP_E_EXCEPTION || hr == DISP_E_MEMBERNOTFOUND) && DispID > 0x8000) {
+                if (hr == DISP_E_EXCEPTION) {
+                    ole_freeexceptinfo(&excepinfo);
+                }
                 memset(&excepinfo, 0, sizeof(EXCEPINFO));
                 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID, 
                         &IID_NULL, lcid, wFlags,
@@ -2140,6 +2256,9 @@
                     param = rb_ary_entry(paramS, i-cNamedArgs);
                     ole_val2variant2(param, &op.dp.rgvarg[n]);
                 }
+                if (hr == DISP_E_EXCEPTION) {
+                    ole_freeexceptinfo(&excepinfo);
+                }
                 memset(&excepinfo, 0, sizeof(EXCEPINFO));
                 VariantInit(&result);
                 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID, 
@@ -6167,6 +6286,14 @@
     com_vtbl.GetTypeInfo = GetTypeInfo;
     com_vtbl.GetIDsOfNames = GetIDsOfNames;
     com_vtbl.Invoke = Invoke;
+
+    message_filter.QueryInterface = mf_QueryInterface;
+    message_filter.AddRef = mf_AddRef;
+    message_filter.Release = mf_Release;
+    message_filter.HandleInComingCall = mf_HandleInComingCall;
+    message_filter.RetryRejectedCall = mf_RetryRejectedCall;
+    message_filter.MessagePending = mf_MessagePending;
+
     com_hash = Data_Wrap_Struct(rb_cData, rb_mark_hash, st_free_table, st_init_numtable());
 
     cWIN32OLE = rb_define_class("WIN32OLE", rb_cObject);
diff -burN ruby-1.8.7-p22/ext/zlib/zlib.c ruby-1.8.7-p72/ext/zlib/zlib.c
--- ruby-1.8.7-p22/ext/zlib/zlib.c	2008-06-08 20:28:37.000000000 +0200
+++ ruby-1.8.7-p72/ext/zlib/zlib.c	2008-07-16 18:39:00.000000000 +0200
@@ -3,7 +3,7 @@
  *
  *   Copyright (C) UENO Katsuhiro 2000-2003
  *
- * $Id: zlib.c 17033 2008-06-08 18:28:37Z knu $
+ * $Id: zlib.c 18089 2008-07-16 16:39:00Z shyouhei $
  */
 
 #include <ruby.h>
@@ -2491,7 +2491,7 @@
 	rb_raise(cGzError, "header is already written");
     }
 
-    if (FIXNUM_P(time)) {
+    if (FIXNUM_P(mtime)) {
 	gz->mtime = FIX2INT(mtime);
     }
     else {
diff -burN ruby-1.8.7-p22/file.c ruby-1.8.7-p72/file.c
--- ruby-1.8.7-p22/file.c	2008-06-17 08:10:23.000000000 +0200
+++ ruby-1.8.7-p72/file.c	2008-07-10 11:47:31.000000000 +0200
@@ -2,8 +2,8 @@
 
   file.c -
 
-  $Author: knu $
-  $Date: 2008-06-17 15:10:23 +0900 (Tue, 17 Jun 2008) $
+  $Author: shyouhei $
+  $Date: 2008-07-10 18:47:31 +0900 (Thu, 10 Jul 2008) $
   created at: Mon Nov 15 12:24:34 JST 1993
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -3044,7 +3044,7 @@
 		p = last;
 		break;
 	    }
-	    e = dot;
+	    if (*last == '.') e = dot;
 	    continue;
 #else
 	    e = p;	  /* get the last dot of the last component */
diff -burN ruby-1.8.7-p22/gc.c ruby-1.8.7-p72/gc.c
--- ruby-1.8.7-p22/gc.c	2008-06-08 20:21:56.000000000 +0200
+++ ruby-1.8.7-p72/gc.c	2008-08-04 05:24:26.000000000 +0200
@@ -2,8 +2,8 @@
 
   gc.c -
 
-  $Author: knu $
-  $Date: 2008-06-09 03:21:56 +0900 (Mon, 09 Jun 2008) $
+  $Author: shyouhei $
+  $Date: 2008-08-04 12:24:26 +0900 (Mon, 04 Aug 2008) $
   created at: Tue Oct  5 09:44:46 JST 1993
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -78,16 +78,22 @@
 
 int ruby_gc_stress = 0;
 
+NORETURN(void rb_exc_jump _((VALUE)));
+
 void
 rb_memerror()
 {
-    static int recurse = 0;
+    rb_thread_t th = rb_curr_thread;
 
-    if (!nomem_error || (recurse > 0 && rb_safe_level() < 4)) {
+    if (!nomem_error ||
+	(rb_thread_raised_p(th, RAISED_NOMEMORY) && rb_safe_level() < 4)) {
 	fprintf(stderr, "[FATAL] failed to allocate memory\n");
 	exit(1);
     }
-    recurse++;
+    if (rb_thread_raised_p(th, RAISED_NOMEMORY)) {
+	rb_exc_jump(nomem_error);
+    }
+    rb_thread_raised_set(th, RAISED_NOMEMORY);
     rb_exc_raise(nomem_error);
 }
 
@@ -136,9 +142,8 @@
 	rb_raise(rb_eNoMemError, "negative allocation size (or too big)");
     }
     if (size == 0) size = 1;
-    malloc_increase += size;
 
-    if (ruby_gc_stress || malloc_increase > malloc_limit) {
+    if (ruby_gc_stress || (malloc_increase+size) > malloc_limit) {
 	garbage_collect();
     }
     RUBY_CRITICAL(mem = malloc(size));
@@ -149,6 +154,7 @@
 	    rb_memerror();
 	}
     }
+    malloc_increase += size;
 
     return mem;
 }
@@ -177,7 +183,6 @@
     }
     if (!ptr) return xmalloc(size);
     if (size == 0) size = 1;
-    malloc_increase += size;
     if (ruby_gc_stress) garbage_collect();
     RUBY_CRITICAL(mem = realloc(ptr, size));
     if (!mem) {
@@ -187,6 +192,7 @@
 	    rb_memerror();
         }
     }
+    malloc_increase += size;
 
     return mem;
 }
@@ -413,6 +419,12 @@
 }
 #define RANY(o) ((RVALUE*)(o))
 
+int 
+rb_during_gc()
+{
+    return during_gc;
+}
+
 VALUE
 rb_newobj()
 {
@@ -2103,7 +2115,10 @@
     source_filenames = st_init_strtable();
 
     rb_global_variable(&nomem_error);
-    nomem_error = rb_exc_new2(rb_eNoMemError, "failed to allocate memory");
+    nomem_error = rb_exc_new3(rb_eNoMemError,
+			      rb_obj_freeze(rb_str_new2("failed to allocate memory")));
+    OBJ_TAINT(nomem_error);
+    OBJ_FREEZE(nomem_error);
 
     rb_define_method(rb_mKernel, "hash", rb_obj_id, 0);
     rb_define_method(rb_mKernel, "__id__", rb_obj_id, 0);
diff -burN ruby-1.8.7-p22/intern.h ruby-1.8.7-p72/intern.h
--- ruby-1.8.7-p22/intern.h	2008-06-20 01:12:46.000000000 +0200
+++ ruby-1.8.7-p72/intern.h	2008-07-07 05:29:28.000000000 +0200
@@ -3,7 +3,7 @@
   intern.h -
 
   $Author: shyouhei $
-  $Date: 2008-06-20 08:12:46 +0900 (Fri, 20 Jun 2008) $
+  $Date: 2008-07-07 12:29:28 +0900 (Mon, 07 Jul 2008) $
   created at: Thu Jun 10 14:22:17 JST 1993
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -252,6 +252,7 @@
 NORETURN(void rb_memerror __((void)));
 int ruby_stack_check _((void));
 int ruby_stack_length _((VALUE**));
+int rb_during_gc _((void));
 char *rb_source_filename _((const char*));
 void rb_gc_mark_locations _((VALUE*, VALUE*));
 void rb_mark_tbl _((struct st_table*));
diff -burN ruby-1.8.7-p22/lib/cgi.rb ruby-1.8.7-p72/lib/cgi.rb
--- ruby-1.8.7-p22/lib/cgi.rb	2008-03-14 08:45:26.000000000 +0100
+++ ruby-1.8.7-p72/lib/cgi.rb	2008-07-02 12:06:58.000000000 +0200
@@ -284,7 +284,7 @@
   # Standard internet newline sequence
   EOL = CR + LF
 
-  REVISION = '$Id: cgi.rb 15778 2008-03-14 07:45:26Z matz $' #:nodoc:
+  REVISION = '$Id: cgi.rb 17817 2008-07-02 10:06:58Z shyouhei $' #:nodoc:
 
   NEEDS_BINMODE = true if /WIN/ni.match(RUBY_PLATFORM) 
 
@@ -1043,7 +1043,7 @@
 
         body.rewind
 
-        /Content-Disposition:.* filename=(?:"((?:\\.|[^\"\s])*)"|([^;\s]*))/ni.match(head)
+        /Content-Disposition:.* filename=(?:"((?:\\.|[^\"])*)"|([^;\s]*))/ni.match(head)
 	filename = ($1 or $2 or "")
 	if /Mac/ni.match(env_table['HTTP_USER_AGENT']) and
 	    /Mozilla/ni.match(env_table['HTTP_USER_AGENT']) and
diff -burN ruby-1.8.7-p22/lib/erb.rb ruby-1.8.7-p72/lib/erb.rb
--- ruby-1.8.7-p22/lib/erb.rb	2008-06-06 10:05:24.000000000 +0200
+++ ruby-1.8.7-p72/lib/erb.rb	2008-07-10 11:43:07.000000000 +0200
@@ -236,7 +236,7 @@
 # Rails, the web application framework, uses ERB to create views.
 #
 class ERB
-  Revision = '$Date: 2008-06-06 17:05:24 +0900 (Fri, 06 Jun 2008) $' 	#'
+  Revision = '$Date: 2008-07-10 18:43:07 +0900 (Thu, 10 Jul 2008) $' 	#'
 
   # Returns revision information for the erb.rb module.
   def self.version
@@ -427,7 +427,7 @@
       Scanner.regist_scanner(SimpleScanner2, nil, false)
 
       class PercentScanner < Scanner # :nodoc:
-	def scan
+	def scan(&blk)
           stag_reg = /(.*?)(^%%|^%|<%%|<%=|<%#|<%|\z)/m
           etag_reg = /(.*?)(%%>|%>|\z)/m
           scanner = StringScanner.new(@src)
@@ -437,14 +437,27 @@
 
             elem = scanner[2]
             if elem == '%%'
-              elem = '%'
+              yield('%')
+              inline_scan(scanner.scan(/.*?(\n|\z)/), &blk)
             elsif elem == '%'
-              elem = PercentLine.new(scanner.scan(/.*?(\n|\z)/).chomp)
-            end
+              yield(PercentLine.new(scanner.scan(/.*?(\n|\z)/).chomp))
+            else
             yield(elem)
           end
         end
       end
+
+        def inline_scan(line)
+          stag_reg = /(.*?)(<%%|<%=|<%#|<%|\z)/m
+          etag_reg = /(.*?)(%%>|%>|\z)/m
+          scanner = StringScanner.new(line)
+          while ! scanner.eos?
+            scanner.scan(@stag ? etag_reg : stag_reg)
+            yield(scanner[1])
+            yield(scanner[2])
+          end
+        end
+      end
       Scanner.regist_scanner(PercentScanner, nil, true)
 
       class ExplicitScanner < Scanner # :nodoc:
diff -burN ruby-1.8.7-p22/lib/ipaddr.rb ruby-1.8.7-p72/lib/ipaddr.rb
--- ruby-1.8.7-p22/lib/ipaddr.rb	2008-03-21 13:16:15.000000000 +0100
+++ ruby-1.8.7-p72/lib/ipaddr.rb	2008-07-12 17:08:29.000000000 +0200
@@ -7,7 +7,7 @@
 #
 # You can redistribute and/or modify it under the same terms as Ruby.
 #
-# $Id: ipaddr.rb 15822 2008-03-21 12:16:15Z knu $
+# $Id: ipaddr.rb 18049 2008-07-12 15:08:29Z shyouhei $
 #
 # Contact:
 #   - Akinori MUSHA <knu@iDaemons.org> (current maintainer)
@@ -483,7 +483,7 @@
     if prefixlen
       mask!(prefixlen)
     else
-      @mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK
+      @mask_addr = (@family == Socket::AF_INET) ? IN4MASK : IN6MASK
     end
   end
 
diff -burN ruby-1.8.7-p22/lib/net/ftp.rb ruby-1.8.7-p72/lib/net/ftp.rb
--- ruby-1.8.7-p22/lib/net/ftp.rb	2007-05-30 06:27:12.000000000 +0200
+++ ruby-1.8.7-p72/lib/net/ftp.rb	2008-07-10 11:40:34.000000000 +0200
@@ -278,12 +278,9 @@
     def sendport(host, port)
       af = (@sock.peeraddr)[0]
       if af == "AF_INET"
-	hbytes = host.split(".")
-	pbytes = [port / 256, port % 256]
-	bytes = hbytes + pbytes
-	cmd = "PORT " + bytes.join(",")
+	cmd = "PORT " + (host.split(".") + port.divmod(256)).join(",")
       elsif af == "AF_INET6"
-	cmd = "EPRT |2|" + host + "|" + sprintf("%d", port) + "|"
+	cmd = sprintf("EPRT |2|%s|%d|", host, port)
       else
 	raise FTPProtoError, host
       end
diff -burN ruby-1.8.7-p22/lib/net/smtp.rb ruby-1.8.7-p72/lib/net/smtp.rb
--- ruby-1.8.7-p22/lib/net/smtp.rb	2008-04-15 10:50:21.000000000 +0200
+++ ruby-1.8.7-p72/lib/net/smtp.rb	2008-08-04 07:51:11.000000000 +0200
@@ -14,7 +14,7 @@
 # NOTE: You can find Japanese version of this document at:
 # http://www.ruby-lang.org/ja/man/html/net_smtp.html
 # 
-# $Id: smtp.rb 16034 2008-04-15 08:50:21Z kazu $
+# $Id: smtp.rb 18353 2008-08-04 05:51:11Z shyouhei $
 #
 # See Net::SMTP for documentation. 
 # 
@@ -172,7 +172,7 @@
   #
   class SMTP
 
-    Revision = %q$Revision: 16034 $.split[1]
+    Revision = %q$Revision: 18353 $.split[1]
 
     # The default SMTP port number, 25.
     def SMTP.default_port
@@ -837,7 +837,7 @@
 
     def rcptto(to_addr)
       if $SAFE > 0
-        raise SecurityError, 'tainted to_addr' if to.tainted?
+        raise SecurityError, 'tainted to_addr' if to_addr.tainted?
       end
       getok("RCPT TO:<#{to_addr}>")
     end
diff -burN ruby-1.8.7-p22/lib/optparse.rb ruby-1.8.7-p72/lib/optparse.rb
--- ruby-1.8.7-p22/lib/optparse.rb	2008-06-06 10:05:24.000000000 +0200
+++ ruby-1.8.7-p72/lib/optparse.rb	2008-07-17 14:31:06.000000000 +0200
@@ -203,7 +203,7 @@
 #
 class OptionParser
   # :stopdoc:
-  RCSID = %w$Id: optparse.rb 16857 2008-06-06 08:05:24Z knu $[1..-1].each {|s| s.freeze}.freeze
+  RCSID = %w$Id: optparse.rb 18110 2008-07-17 12:31:06Z shyouhei $[1..-1].each {|s| s.freeze}.freeze
   Version = (RCSID[1].split('.').collect {|s| s.to_i}.extend(Comparable).freeze if RCSID[1])
   LastModified = (Time.gm(*RCSID[2, 2].join('-').scan(/\d+/).collect {|s| s.to_i}) if RCSID[2])
   Release = RCSID[2]
@@ -1476,6 +1476,7 @@
   #
   def environment(env = File.basename($0, '.*'))
     env = ENV[env] || ENV[env.upcase] or return
+    require 'shellwords'
     parse(*Shellwords.shellwords(env))
   end
 
diff -burN ruby-1.8.7-p22/lib/rdoc/parsers/parse_rb.rb ruby-1.8.7-p72/lib/rdoc/parsers/parse_rb.rb
--- ruby-1.8.7-p22/lib/rdoc/parsers/parse_rb.rb	2007-02-13 00:01:19.000000000 +0100
+++ ruby-1.8.7-p72/lib/rdoc/parsers/parse_rb.rb	2008-06-29 10:24:56.000000000 +0200
@@ -1546,10 +1546,15 @@
 
       tk = get_tk
       while tk.kind_of?(TkCOMMENT)
-        if first_line && tk.text[0,2] == "#!"
+        if first_line && /\A#!/ =~ tk.text
+          skip_tkspace
+          tk = get_tk
+        elsif first_line && /\A#\s*-\*-/ =~ tk.text
+          first_line = false
           skip_tkspace
           tk = get_tk
         else
+          first_line = false
           res << tk.text << "\n"
           tk = get_tk
           if tk.kind_of? TkNL
@@ -1557,7 +1562,6 @@
             tk = get_tk
           end
         end
-        first_line = false
       end
       unget_tk(tk)
       res
diff -burN ruby-1.8.7-p22/lib/resolv.rb ruby-1.8.7-p72/lib/resolv.rb
--- ruby-1.8.7-p22/lib/resolv.rb	2008-06-06 10:05:24.000000000 +0200
+++ ruby-1.8.7-p72/lib/resolv.rb	2008-08-08 03:58:40.000000000 +0200
@@ -3,6 +3,11 @@
 require 'timeout'
 require 'thread'
 
+begin
+  require 'securerandom'
+rescue LoadError
+end
+
 # Resolv is a thread-aware DNS resolver library written in Ruby.  Resolv can
 # handle multiple DNS requests concurrently without blocking.  The ruby
 # interpreter.
@@ -285,7 +290,7 @@
     UDPSize = 512
 
     ##
-    # Group of DNS resolver threads
+    # Group of DNS resolver threads (obsolete)
 
     DNSThreadGroup = ThreadGroup.new
 
@@ -330,13 +335,6 @@
       @mutex.synchronize {
         unless @initialized
           @config.lazy_initialize
-
-          if nameserver = @config.single?
-            @requester = Requester::ConnectedUDP.new(nameserver)
-          else
-            @requester = Requester::UnconnectedUDP.new
-          end
-
           @initialized = true
         end
       }
@@ -349,8 +347,6 @@
     def close
       @mutex.synchronize {
         if @initialized
-          @requester.close if @requester
-          @requester = nil
           @initialized = false
         end
       }
@@ -479,7 +475,7 @@
   
     def each_resource(name, typeclass, &proc)
       lazy_initialize
-      q = Queue.new
+      requester = make_requester
       senders = {}
       begin
         @config.resolv(name) {|candidate, tout, nameserver|
@@ -488,11 +484,9 @@
           msg.add_question(candidate, typeclass)
           unless sender = senders[[candidate, nameserver]]
             sender = senders[[candidate, nameserver]] =
-              @requester.sender(msg, candidate, q, nameserver)
+              requester.sender(msg, candidate, nameserver)
           end
-          sender.send
-          reply = reply_name = nil
-          timeout(tout, ResolvTimeout) { reply, reply_name = q.pop }
+          reply, reply_name = requester.request(sender, tout)
           case reply.rcode
           when RCode::NoError
             extract_resources(reply, reply_name, typeclass, &proc)
@@ -504,7 +498,15 @@
           end
         }
       ensure
-        @requester.delete(q)
+        requester.close
+      end
+    end
+
+    def make_requester # :nodoc:
+      if nameserver = @config.single?
+        Requester::ConnectedUDP.new(nameserver)
+      else
+        Requester::UnconnectedUDP.new
       end
     end
 
@@ -539,45 +541,106 @@
       }
     end
 
+    if defined? SecureRandom
+      def self.random(arg) # :nodoc:
+        begin
+          SecureRandom.random_number(arg)
+        rescue NotImplementedError
+          rand(arg)
+        end
+      end
+    else
+      def self.random(arg) # :nodoc:
+        rand(arg)
+      end
+    end
+
+
+    def self.rangerand(range) # :nodoc:
+      base = range.begin
+      len = range.end - range.begin
+      if !range.exclude_end?
+        len += 1
+      end
+      base + random(len)
+    end
+
+    RequestID = {}
+    RequestIDMutex = Mutex.new
+
+    def self.allocate_request_id(host, port) # :nodoc:
+      id = nil
+      RequestIDMutex.synchronize {
+        h = (RequestID[[host, port]] ||= {})
+        begin
+          id = rangerand(0x0000..0xffff)
+        end while h[id] 
+        h[id] = true
+      }
+      id
+    end
+
+    def self.free_request_id(host, port, id) # :nodoc:
+      RequestIDMutex.synchronize {
+        key = [host, port]
+        if h = RequestID[key]
+          h.delete id
+          if h.empty?
+            RequestID.delete key
+          end
+        end
+      }
+    end
+
+    def self.bind_random_port(udpsock) # :nodoc:
+      begin
+        port = rangerand(1024..65535)
+        udpsock.bind("", port)
+      rescue Errno::EADDRINUSE
+        retry
+      end
+    end
+
     class Requester # :nodoc:
       def initialize
         @senders = {}
+        @sock = nil
       end
 
-      def close
-        thread, sock, @thread, @sock = @thread, @sock
+      def request(sender, tout)
+        timelimit = Time.now + tout
+        sender.send
+        while (now = Time.now) < timelimit
+          timeout = timelimit - now
+          if !IO.select([@sock], nil, nil, timeout)
+            raise ResolvTimeout
+          end
+          reply, from = recv_reply
         begin
-          if thread
-            thread.kill
-            thread.join
+            msg = Message.decode(reply)
+          rescue DecodeError
+            next # broken DNS message ignored
           end
-        ensure
-          sock.close if sock
+          if s = @senders[[from,msg.id]]
+            break
+          else
+            # unexpected DNS message ignored
         end
       end
-
-      def delete(arg)
-        case arg
-        when Sender
-          @senders.delete_if {|k, s| s == arg }
-        when Queue
-          @senders.delete_if {|k, s| s.queue == arg }
-        else
-          raise ArgumentError.new("neither Sender or Queue: #{arg}")
+        return msg, s.data
         end
+
+      def close
+        sock = @sock
+        @sock = nil
+        sock.close if sock
       end
 
       class Sender # :nodoc:
-        def initialize(msg, data, sock, queue)
+        def initialize(msg, data, sock)
           @msg = msg
           @data = data
           @sock = sock
-          @queue = queue
-        end
-        attr_reader :queue
-
-        def recv(msg)
-          @queue.push([msg, @data])
         end
       end
 
@@ -585,45 +648,38 @@
         def initialize
           super()
           @sock = UDPSocket.new
-          @sock.fcntl(Fcntl::F_SETFD, 1) if defined? Fcntl::F_SETFD
-          @id = {}
-          @id.default = -1
-          @thread = Thread.new {
-            DNSThreadGroup.add Thread.current
-            loop {
-              reply, from = @sock.recvfrom(UDPSize)
-              msg = begin
-                Message.decode(reply)
-              rescue DecodeError
-                STDERR.print("DNS message decoding error: #{reply.inspect}\n")
-                next
-              end
-              if s = @senders[[[from[3],from[1]],msg.id]]
-                s.recv msg
-              else
-                #STDERR.print("non-handled DNS message: #{msg.inspect} from #{from.inspect}\n")
+          @sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD
+          DNS.bind_random_port(@sock)
               end
-            }
-          }
+
+        def recv_reply
+          reply, from = @sock.recvfrom(UDPSize)
+          return reply, [from[3],from[1]]
         end
 
-        def sender(msg, data, queue, host, port=Port)
+        def sender(msg, data, host, port=Port)
           service = [host, port]
-          id = Thread.exclusive {
-            @id[service] = (@id[service] + 1) & 0xffff
-          }
+          id = DNS.allocate_request_id(host, port)
           request = msg.encode
           request[0,2] = [id].pack('n')
           return @senders[[service, id]] =
-            Sender.new(request, data, @sock, host, port, queue)
+            Sender.new(request, data, @sock, host, port)
+        end
+
+        def close
+          super
+          @senders.each_key {|service, id|
+            DNS.free_request_id(service[0], service[1], id)
+          }
         end
 
         class Sender < Requester::Sender # :nodoc:
-          def initialize(msg, data, sock, host, port, queue)
-            super(msg, data, sock, queue)
+          def initialize(msg, data, sock, host, port)
+            super(msg, data, sock)
             @host = host
             @port = port
           end
+          attr_reader :data
 
           def send
             @sock.send(@msg, 0, @host, @port)
@@ -637,42 +693,38 @@
           @host = host
           @port = port
           @sock = UDPSocket.new(host.index(':') ? Socket::AF_INET6 : Socket::AF_INET)
+          DNS.bind_random_port(@sock)
           @sock.connect(host, port)
-          @sock.fcntl(Fcntl::F_SETFD, 1) if defined? Fcntl::F_SETFD
-          @id = -1
-          @thread = Thread.new {
-            DNSThreadGroup.add Thread.current
-            loop {
-              reply = @sock.recv(UDPSize)
-              msg = begin
-                Message.decode(reply)
-              rescue DecodeError
-                STDERR.print("DNS message decoding error: #{reply.inspect}")
-                next
-              end
-              if s = @senders[msg.id]
-                s.recv msg
-              else
-                #STDERR.print("non-handled DNS message: #{msg.inspect}")
+          @sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD
               end
-            }
-          }
+
+        def recv_reply
+          reply = @sock.recv(UDPSize)
+          return reply, nil
         end
 
-        def sender(msg, data, queue, host=@host, port=@port)
+        def sender(msg, data, host=@host, port=@port)
           unless host == @host && port == @port
             raise RequestError.new("host/port don't match: #{host}:#{port}")
           end
-          id = Thread.exclusive { @id = (@id + 1) & 0xffff }
+          id = DNS.allocate_request_id(@host, @port)
           request = msg.encode
           request[0,2] = [id].pack('n')
-          return @senders[id] = Sender.new(request, data, @sock, queue)
+          return @senders[[nil,id]] = Sender.new(request, data, @sock)
+        end
+
+        def close
+          super
+          @senders.each_key {|from, id|
+            DNS.free_request_id(@host, @port, id)
+          }
         end
 
         class Sender < Requester::Sender # :nodoc:
           def send
             @sock.send(@msg, 0)
           end
+          attr_reader :data
         end
       end
 
@@ -681,39 +733,25 @@
           super()
           @host = host
           @port = port
-          @sock = TCPSocket.new
-          @sock.connect(host, port)
-          @sock.fcntl(Fcntl::F_SETFD, 1) if defined? Fcntl::F_SETFD
-          @id = -1
+          @sock = TCPSocket.new(@host, @port)
+          @sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD
           @senders = {}
-          @thread = Thread.new {
-            DNSThreadGroup.add Thread.current
-            loop {
-              len = @sock.read(2).unpack('n')
-              reply = @sock.read(len)
-              msg = begin
-                Message.decode(reply)
-              rescue DecodeError
-                STDERR.print("DNS message decoding error: #{reply.inspect}")
-                next
               end
-              if s = @senders[msg.id]
-                s.push msg
-              else
-                #STDERR.print("non-handled DNS message: #{msg.inspect}")
-              end
-            }
-          }
+
+        def recv_reply
+          len = @sock.read(2).unpack('n')[0]
+          reply = @sock.read(len)
+          return reply, nil
         end
 
-        def sender(msg, data, queue, host=@host, port=@port)
+        def sender(msg, data, host=@host, port=@port)
           unless host == @host && port == @port
             raise RequestError.new("host/port don't match: #{host}:#{port}")
           end
-          id = Thread.exclusive { @id = (@id + 1) & 0xffff }
+          id = DNS.allocate_request_id(@host, @port)
           request = msg.encode
           request[0,2] = [request.length, id].pack('nn')
-          return @senders[id] = Sender.new(request, data, @sock, queue)
+          return @senders[[nil,id]] = Sender.new(request, data, @sock)
         end
 
         class Sender < Requester::Sender # :nodoc:
@@ -721,6 +759,14 @@
             @sock.print(@msg)
             @sock.flush
           end
+          attr_reader :data
+        end
+
+        def close
+          super
+          @senders.each_key {|from,id|
+            DNS.free_request_id(@host, @port, id)
+          }
         end
       end
 
diff -burN ruby-1.8.7-p22/lib/resolv-replace.rb ruby-1.8.7-p72/lib/resolv-replace.rb
--- ruby-1.8.7-p22/lib/resolv-replace.rb	2007-02-13 00:01:19.000000000 +0100
+++ ruby-1.8.7-p72/lib/resolv-replace.rb	2008-08-08 03:58:40.000000000 +0200
@@ -23,7 +23,8 @@
 class UDPSocket
   alias original_resolv_bind bind
   def bind(host, port)
-    original_resolv_bind(IPSocket.getaddress(host), port)
+    host = IPSocket.getaddress(host) if host != ""
+    original_resolv_bind(host, port)
   end
 
   alias original_resolv_connect connect
diff -burN ruby-1.8.7-p22/lib/singleton.rb ruby-1.8.7-p72/lib/singleton.rb
--- ruby-1.8.7-p22/lib/singleton.rb	2008-05-28 09:16:25.000000000 +0200
+++ ruby-1.8.7-p72/lib/singleton.rb	2008-07-03 13:14:50.000000000 +0200
@@ -71,7 +71,6 @@
     raise TypeError, "can't dup instance of singleton #{self.class}"
   end
 
-  private
   #  default marshalling strategy
   def _dump(depth=-1)
     ''
diff -burN ruby-1.8.7-p22/lib/tmpdir.rb ruby-1.8.7-p72/lib/tmpdir.rb
--- ruby-1.8.7-p22/lib/tmpdir.rb	2007-10-24 08:03:48.000000000 +0200
+++ ruby-1.8.7-p72/lib/tmpdir.rb	2008-07-02 11:23:13.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # tmpdir - retrieve temporary directory path
 #
-# $Id: tmpdir.rb 13762 2007-10-24 06:03:48Z akr $
+# $Id: tmpdir.rb 17801 2008-07-02 09:23:13Z shyouhei $
 #
 
 require 'fileutils'
@@ -12,16 +12,23 @@
 
   begin
     require 'Win32API'
+    CSIDL_LOCAL_APPDATA = 0x001c
     max_pathlen = 260
     windir = ' '*(max_pathlen+1)
     begin
+      getdir = Win32API.new('shell32', 'SHGetFolderPath', 'LLLLP', 'L')
+      raise RuntimeError if getdir.call(0, CSIDL_LOCAL_APPDATA, 0, 0, windir) != 0
+      windir = File.expand_path(windir.rstrip)
+    rescue RuntimeError
+      begin
       getdir = Win32API.new('kernel32', 'GetSystemWindowsDirectory', 'PL', 'L')
     rescue RuntimeError
       getdir = Win32API.new('kernel32', 'GetWindowsDirectory', 'PL', 'L')
     end
     len = getdir.call(windir, windir.size)
     windir = File.expand_path(windir[0, len])
-    temp = File.join(windir, 'temp')
+    end
+    temp = File.join(windir.untaint, 'temp')
     @@systmpdir = temp if File.directory?(temp) and File.writable?(temp)
   rescue LoadError
   end
@@ -41,9 +48,9 @@
 	  break
 	end
       end
-    end
     File.expand_path(tmp)
   end
+  end
 
   # Dir.mktmpdir creates a temporary directory.
   #
diff -burN ruby-1.8.7-p22/lib/webrick/httputils.rb ruby-1.8.7-p72/lib/webrick/httputils.rb
--- ruby-1.8.7-p22/lib/webrick/httputils.rb	2007-02-13 00:01:19.000000000 +0100
+++ ruby-1.8.7-p72/lib/webrick/httputils.rb	2008-08-04 07:21:05.000000000 +0200
@@ -23,16 +23,8 @@
       ret = path.dup
 
       ret.gsub!(%r{/+}o, '/')                    # //      => /
-      while ret.sub!(%r{/\.(/|\Z)}o, '/'); end   # /.      => /
-      begin                                      # /foo/.. => /foo
-        match = ret.sub!(%r{/([^/]+)/\.\.(/|\Z)}o){
-          if $1 == ".."
-            raise "abnormal path `#{path}'"
-          else
-            "/"
-          end
-        }
-      end while match
+      while ret.sub!(%r'/\.(?:/|\Z)', '/'); end  # /.      => /
+      while ret.sub!(%r'/(?!\.\./)[^/]+/\.\.(?:/|\Z)', '/'); end # /foo/.. => /foo
 
       raise "abnormal path `#{path}'" if %r{/\.\.(/|\Z)} =~ ret
       ret
@@ -154,8 +146,8 @@
     module_function :parse_header
 
     def split_header_value(str)
-      str.scan(/((?:"(?:\\.|[^"])+?"|[^",]+)+)
-                (?:,\s*|\Z)/xn).collect{|v| v[0] }
+      str.scan(%r'\G((?:"(?:\\.|[^"])+?"|[^",]+)+)
+                    (?:,\s*|\Z)'xn).flatten
     end
     module_function :split_header_value
 
diff -burN ruby-1.8.7-p22/lib/xmlrpc/client.rb ruby-1.8.7-p72/lib/xmlrpc/client.rb
--- ruby-1.8.7-p22/lib/xmlrpc/client.rb	2008-04-15 19:11:48.000000000 +0200
+++ ruby-1.8.7-p72/lib/xmlrpc/client.rb	2008-07-16 19:07:44.000000000 +0200
@@ -268,7 +268,7 @@
 
 
 = History
-    $Id: client.rb 16048 2008-04-15 17:11:48Z knu $
+    $Id: client.rb 18091 2008-07-16 17:07:44Z shyouhei $
 
 =end
 
@@ -567,6 +567,7 @@
 
       set_cookies = resp.get_fields("Set-Cookie")
       if set_cookies and !set_cookies.empty?
+        require 'webrick/cookie'
         @cookie = set_cookies.collect do |set_cookie|
           cookie = WEBrick::Cookie.parse_set_cookie(set_cookie)
           WEBrick::Cookie.new(cookie.name, cookie.value).to_s
diff -burN ruby-1.8.7-p22/marshal.c ruby-1.8.7-p72/marshal.c
--- ruby-1.8.7-p22/marshal.c	2008-06-06 12:39:57.000000000 +0200
+++ ruby-1.8.7-p72/marshal.c	2008-07-03 13:14:50.000000000 +0200
@@ -2,8 +2,8 @@
 
   marshal.c -
 
-  $Author: knu $
-  $Date: 2008-06-06 19:39:57 +0900 (Fri, 06 Jun 2008) $
+  $Author: shyouhei $
+  $Date: 2008-07-03 20:14:50 +0900 (Thu, 03 Jul 2008) $
   created at: Thu Apr 27 16:30:01 JST 1995
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -511,7 +511,7 @@
 	if (OBJ_TAINTED(obj)) arg->taint = Qtrue;
 
 	st_add_direct(arg->data, obj, arg->data->num_entries);
-	if (rb_obj_respond_to(obj, s_mdump, Qtrue)) {
+	if (rb_respond_to(obj, s_mdump)) {
 	    volatile VALUE v;
 
 	    v = rb_funcall(obj, s_mdump, 0, 0);
@@ -521,7 +521,7 @@
 	    if (ivtbl) w_ivar(0, &c_arg);
 	    return;
 	}
-	if (rb_obj_respond_to(obj, s_dump, Qtrue)) {
+	if (rb_respond_to(obj, s_dump)) {
 	    VALUE v;
 
 	    v = rb_funcall(obj, s_dump, 1, INT2NUM(limit));
@@ -664,7 +664,7 @@
 	    {
 		VALUE v;
 
-		if (!rb_obj_respond_to(obj, s_dump_data, Qtrue)) {
+		if (!rb_respond_to(obj, s_dump_data)) {
 		    rb_raise(rb_eTypeError,
 			     "no marshal_dump is defined for class %s",
 			     rb_obj_classname(obj));
@@ -765,12 +765,12 @@
     arg.str = rb_str_buf_new(0);
     RBASIC(arg.str)->klass = 0;
     if (!NIL_P(port)) {
-	if (!rb_obj_respond_to(port, s_write, Qtrue)) {
+	if (!rb_respond_to(port, s_write)) {
 	  type_error:
 	    rb_raise(rb_eTypeError, "instance of IO needed");
 	}
 	arg.dest = port;
-	if (rb_obj_respond_to(port, s_binmode, Qtrue)) {
+	if (rb_respond_to(port, s_binmode)) {
 	    rb_funcall2(port, s_binmode, 0, 0);
 	    reentrant_check(arg.str, s_dump_data);
 	}
@@ -1245,7 +1245,7 @@
 	    VALUE klass = path2class(r_unique(arg));
 	    VALUE data;
 
-	    if (!rb_obj_respond_to(klass, s_load, Qtrue)) {
+	    if (!rb_respond_to(klass, s_load)) {
 		rb_raise(rb_eTypeError, "class %s needs to have method `_load'",
 			 rb_class2name(klass));
 	    }
@@ -1272,7 +1272,7 @@
                     rb_extend_object(v, m);
                 }
             }
-	    if (!rb_obj_respond_to(v, s_mload, Qtrue)) {
+	    if (!rb_respond_to(v, s_mload)) {
 		rb_raise(rb_eTypeError, "instance of %s needs to have method `marshal_load'",
 			 rb_class2name(klass));
 	    }
@@ -1299,7 +1299,7 @@
       case TYPE_DATA:
        {
            VALUE klass = path2class(r_unique(arg));
-           if (rb_obj_respond_to(klass, s_alloc, Qtrue)) {
+           if (rb_respond_to(klass, s_alloc)) {
 	       static int warn = Qtrue;
 	       if (warn) {
 		   rb_warn("define `allocate' instead of `_alloc'");
@@ -1315,7 +1315,7 @@
                rb_raise(rb_eArgError, "dump format error");
            }
            r_entry(v, arg);
-           if (!rb_obj_respond_to(v, s_load_data, Qtrue)) {
+           if (!rb_respond_to(v, s_load_data)) {
                rb_raise(rb_eTypeError,
                         "class %s needs to have instance method `_load_data'",
                         rb_class2name(klass));
@@ -1420,8 +1420,8 @@
 	arg.taint = OBJ_TAINTED(port); /* original taintedness */
 	port = v;
     }
-    else if (rb_obj_respond_to(port, s_getc, Qtrue) && rb_obj_respond_to(port, s_read, Qtrue)) {
-	if (rb_obj_respond_to(port, s_binmode, Qtrue)) {
+    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;
diff -burN ruby-1.8.7-p22/math.c ruby-1.8.7-p72/math.c
--- ruby-1.8.7-p22/math.c	2008-01-25 14:34:13.000000000 +0100
+++ ruby-1.8.7-p72/math.c	2008-07-02 11:26:29.000000000 +0200
@@ -2,8 +2,8 @@
 
   math.c -
 
-  $Author: mame $
-  $Date: 2008-01-25 22:34:13 +0900 (Fri, 25 Jan 2008) $
+  $Author: shyouhei $
+  $Date: 2008-07-02 18:26:29 +0900 (Wed, 02 Jul 2008) $
   created at: Tue Jan 25 14:12:56 JST 1994
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -34,7 +34,7 @@
 	if (isnan(x)) {
 #if defined(EDOM)
 	    errno = EDOM;
-#elif define(ERANGE)
+#elif defined(ERANGE)
 	    errno = ERANGE;
 #endif
 	    continue;
diff -burN ruby-1.8.7-p22/node.h ruby-1.8.7-p72/node.h
--- ruby-1.8.7-p22/node.h	2008-05-22 18:07:42.000000000 +0200
+++ ruby-1.8.7-p72/node.h	2008-07-07 08:17:24.000000000 +0200
@@ -2,8 +2,8 @@
 
   node.h -
 
-  $Author: knu $
-  $Date: 2008-05-23 01:07:42 +0900 (Fri, 23 May 2008) $
+  $Author: shyouhei $
+  $Date: 2008-07-07 15:17:24 +0900 (Mon, 07 Jul 2008) $
   created at: Fri May 28 15:14:02 JST 1993
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -468,6 +468,19 @@
 extern rb_thread_t rb_curr_thread;
 extern rb_thread_t rb_main_thread;
 
+enum {
+    RAISED_EXCEPTION     = 0x1000,
+    RAISED_STACKOVERFLOW = 0x2000,
+    RAISED_NOMEMORY      = 0x4000,
+    RAISED_MASK          = 0xf000
+};
+int rb_thread_set_raised(rb_thread_t th);
+int rb_thread_reset_raised(rb_thread_t th);
+#define rb_thread_raised_set(th, f)   ((th)->flags |= (f))
+#define rb_thread_raised_reset(th, f) ((th)->flags &= ~(f))
+#define rb_thread_raised_p(th, f)     (((th)->flags & (f)) != 0)
+#define rb_thread_raised_clear(th)    ((th)->flags = 0)
+
 #if defined(__cplusplus)
 }  /* extern "C" { */
 #endif
diff -burN ruby-1.8.7-p22/numeric.c ruby-1.8.7-p72/numeric.c
--- ruby-1.8.7-p22/numeric.c	2008-05-31 13:44:49.000000000 +0200
+++ ruby-1.8.7-p72/numeric.c	2008-08-04 06:36:00.000000000 +0200
@@ -2,8 +2,8 @@
 
   numeric.c -
 
-  $Author: knu $
-  $Date: 2008-05-31 20:44:49 +0900 (Sat, 31 May 2008) $
+  $Author: shyouhei $
+  $Date: 2008-08-04 13:36:00 +0900 (Mon, 04 Aug 2008) $
   created at: Fri Aug 13 18:33:09 JST 1993
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -121,7 +121,9 @@
 {
     if (CLASS_OF(x) == CLASS_OF(y))
 	return rb_assoc_new(y, x);
-    return rb_assoc_new(rb_Float(y), rb_Float(x));
+    x = rb_Float(x);
+    y = rb_Float(y);
+    return rb_assoc_new(y, x);
 }
 
 static VALUE
@@ -1598,10 +1600,20 @@
 }
 
 static void
-check_uint(num)
+check_uint(num, sign)
     unsigned long num;
+    VALUE sign;
 {
-    if (num > UINT_MAX) {
+    static const unsigned long mask = ~(unsigned long)UINT_MAX;
+
+    if (RTEST(sign)) {
+	/* minus */
+	if ((num & mask) != mask || (num & ~mask) <= INT_MAX + 1UL)
+	    rb_raise(rb_eRangeError, "integer %ld too small to convert to `unsigned int'", num);
+    }
+    else {
+	/* plus */
+	if ((num & mask) != 0)
 	rb_raise(rb_eRangeError, "integer %lu too big to convert to `unsigned int'", num);
     }
 }
@@ -1632,9 +1644,7 @@
 {
     unsigned long num = rb_num2ulong(val);
 
-    if (RTEST(rb_funcall(INT2FIX(0), '<', 1, val))) {
-	check_uint(num);
-    }
+    check_uint(num, rb_funcall(val, '<', 1, INT2FIX(0)));
     return num;
 }
 
@@ -1648,9 +1658,8 @@
         return rb_num2uint(val);
     }
     num = FIX2ULONG(val);
-    if (FIX2LONG(val) > 0) {
-	check_uint(num);
-    }
+
+    check_uint(num, rb_funcall(val, '<', 1, INT2FIX(0)));
     return num;
 }
 #else
diff -burN ruby-1.8.7-p22/object.c ruby-1.8.7-p72/object.c
--- ruby-1.8.7-p22/object.c	2008-06-06 10:05:24.000000000 +0200
+++ ruby-1.8.7-p72/object.c	2008-07-03 13:14:50.000000000 +0200
@@ -2,8 +2,8 @@
 
   object.c -
 
-  $Author: knu $
-  $Date: 2008-06-06 17:05:24 +0900 (Fri, 06 Jun 2008) $
+  $Author: shyouhei $
+  $Date: 2008-07-03 20:14:50 +0900 (Thu, 03 Jul 2008) $
   created at: Thu Jul 15 12:01:24 JST 1993
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -2205,7 +2205,7 @@
     ID m;
 
     m = rb_intern(method);
-    if (!rb_obj_respond_to(val, m, Qtrue)) {
+    if (!rb_respond_to(val, m)) {
 	if (raise) {
 	    rb_raise(rb_eTypeError, "can't convert %s into %s",
 		     NIL_P(val) ? "nil" :
diff -burN ruby-1.8.7-p22/process.c ruby-1.8.7-p72/process.c
--- ruby-1.8.7-p22/process.c	2008-06-06 12:39:57.000000000 +0200
+++ ruby-1.8.7-p72/process.c	2008-06-29 11:34:43.000000000 +0200
@@ -2,8 +2,8 @@
 
   process.c -
 
-  $Author: knu $
-  $Date: 2008-06-06 19:39:57 +0900 (Fri, 06 Jun 2008) $
+  $Author: shyouhei $
+  $Date: 2008-06-29 18:34:43 +0900 (Sun, 29 Jun 2008) $
   created at: Tue Aug 10 14:30:50 JST 1993
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -42,7 +42,7 @@
 #ifdef HAVE_SYS_WAIT_H
 # include <sys/wait.h>
 #endif
-#ifdef HAVE_GETPRIORITY
+#ifdef HAVE_SYS_RESOURCE_H
 # include <sys/resource.h>
 #endif
 #include "st.h"
diff -burN ruby-1.8.7-p22/regex.c ruby-1.8.7-p72/regex.c
--- ruby-1.8.7-p22/regex.c	2008-06-06 12:39:57.000000000 +0200
+++ ruby-1.8.7-p72/regex.c	2008-08-04 07:15:15.000000000 +0200
@@ -50,6 +50,9 @@
 /* We need this for `regex.h', and perhaps for the Emacs include files.  */
 # include <sys/types.h>
 #endif
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
 
 #if !defined(__STDC__) && !defined(_MSC_VER)
 # define volatile
@@ -63,6 +66,10 @@
 
 #ifdef RUBY_PLATFORM
 #include "defines.h"
+#undef xmalloc
+#undef xrealloc
+#undef xcalloc
+#undef xfree
 
 # define RUBY
 extern int rb_prohibit_interrupt;
@@ -104,6 +111,11 @@
 # include <strings.h>
 #endif
 
+#define xmalloc     malloc
+#define xrealloc    realloc
+#define xcalloc     calloc
+#define xfree       free
+
 #ifdef C_ALLOCA
 #define FREE_VARIABLES() alloca(0)
 #else
@@ -127,10 +139,12 @@
   unsigned int xlen = stacke - stackb; 					\
   if (stackb == stacka) {						\
     stackx = (type*)xmalloc(2 * xlen * sizeof(type));			\
+    if (!stackx) goto memory_exhausted;					\
     memcpy(stackx, stackb, xlen * sizeof (type));			\
   }									\
   else {								\
     stackx = (type*)xrealloc(stackb, 2 * xlen * sizeof(type));		\
+    if (!stackx) goto memory_exhausted;					\
   }									\
   /* Rearrange the pointers. */						\
   stackp = stackx + (stackp - stackb);					\
@@ -2775,8 +2789,8 @@
    The caller must supply the address of a (1 << BYTEWIDTH)-byte data 
    area as bufp->fastmap.
    The other components of bufp describe the pattern to be used.  */
-void
-re_compile_fastmap(bufp)
+static int
+re_compile_fastmap0(bufp)
      struct re_pattern_buffer *bufp;
 {
   unsigned char *pattern = (unsigned char*)bufp->buffer;
@@ -2944,7 +2958,7 @@
 	    fastmap[j] = 1;
 	}
 	if (bufp->can_be_null) {
-	  FREE_AND_RETURN_VOID(stackb);
+	  FREE_AND_RETURN(stackb, 0);
 	}
 	/* Don't return; check the alternative paths
 	   so we can set can_be_null if appropriate.  */
@@ -3110,7 +3124,16 @@
     else
       break;
   }
-  FREE_AND_RETURN_VOID(stackb);
+  FREE_AND_RETURN(stackb, 0);
+ memory_exhausted:
+  FREE_AND_RETURN(stackb, -2);
+}
+
+void
+re_compile_fastmap(bufp)
+     struct re_pattern_buffer *bufp;
+{
+  (void)re_compile_fastmap0(bufp);
 }
 
 /* adjust startpos value to the position between characters. */
@@ -3144,7 +3167,8 @@
 {
   /* Update the fastmap now if not correct already.  */
   if (!bufp->fastmap_accurate) {
-    re_compile_fastmap(bufp);
+    int ret = re_compile_fastmap0(bufp);
+    if (ret) return ret;
   }
 
   /* Adjust startpos for mbc string */
@@ -3190,7 +3214,8 @@
 
   /* Update the fastmap now if not correct already.  */
   if (fastmap && !bufp->fastmap_accurate) {
-    re_compile_fastmap(bufp);
+    int ret = re_compile_fastmap0(bufp);
+    if (ret) return ret;
   }
 
 
@@ -3580,7 +3605,7 @@
      ``dummy''; if a failure happens and the failure point is a dummy, it
      gets discarded and the next next one is tried.  */
 
-  unsigned char **stacka;
+  unsigned char **const stacka = 0;
   unsigned char **stackb;
   unsigned char **stackp;
   unsigned char **stacke;
@@ -3629,8 +3654,7 @@
   }
 
   /* Initialize the stack. */
-  stacka = RE_TALLOC(MAX_NUM_FAILURE_ITEMS * NFAILURES, unsigned char*);
-  stackb = stacka;
+  stackb = TMALLOC(MAX_NUM_FAILURE_ITEMS * NFAILURES, unsigned char*);
   stackp = stackb;
   stacke = &stackb[MAX_NUM_FAILURE_ITEMS * NFAILURES];
 
@@ -4400,6 +4424,8 @@
     goto restore_best_regs;
 
   FREE_AND_RETURN(stackb,(-1)); 	/* Failure to match.  */
+ memory_exhausted:
+  FREE_AND_RETURN(stackb,(-2));
 }
 
 
@@ -4663,5 +4689,5 @@
   mode		 : C
   c-file-style	 : "gnu"
   tab-width	 : 8
-  End		 :
+  End
 */
diff -burN ruby-1.8.7-p22/ruby.c ruby-1.8.7-p72/ruby.c
--- ruby-1.8.7-p22/ruby.c	2008-06-06 12:39:57.000000000 +0200
+++ ruby-1.8.7-p72/ruby.c	2008-07-10 11:38:35.000000000 +0200
@@ -2,8 +2,8 @@
 
   ruby.c -
 
-  $Author: knu $
-  $Date: 2008-06-06 19:39:57 +0900 (Fri, 06 Jun 2008) $
+  $Author: shyouhei $
+  $Date: 2008-07-10 18:38:35 +0900 (Thu, 10 Jul 2008) $
   created at: Tue Aug 10 12:47:31 JST 1993
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -1039,15 +1039,50 @@
 #define set_arg0space() ((void)0)
 #endif
 
+static int
+get_arglen(int argc, char **argv)
+{
+    char *s = argv[0];
+    int i;
+
+    if (!argc) return 0;
+    s += strlen(s);
+    /* See if all the arguments are contiguous in memory */
+    for (i = 1; i < argc; i++) {
+	if (argv[i] == s + 1) {
+	    s++;
+	    s += strlen(s);	/* this one is ok too */
+	}
+	else {
+	    break;
+	}
+    }
+#if defined(USE_ENVSPACE_FOR_ARG0)
+    if (environ && (s == environ[0])) {
+	s += strlen(s);
+	for (i = 1; environ[i]; i++) {
+	    if (environ[i] == s + 1) {
+		s++;
+		s += strlen(s);	/* this one is ok too */
+	    }
+	}
+	ruby_setenv("", NULL); /* duplicate environ vars */
+    }
+#endif
+    return s - argv[0];
+}
+
 static void
 set_arg0(val, id)
     VALUE val;
     ID id;
 {
+    VALUE progname;
     char *s;
     long i;
+    int j;
 #if !defined(PSTAT_SETCMD) && !defined(HAVE_SETPROCTITLE)
-    static int len;
+    static int len = 0;
 #endif
 
     if (origargv == 0) rb_raise(rb_eRuntimeError, "$0 not initialized");
@@ -1068,33 +1103,13 @@
 	j.pst_command = s;
 	pstat(PSTAT_SETCMD, j, i, 0, 0);
     }
-    rb_progname = rb_tainted_str_new(s, i);
+    progname = rb_tainted_str_new(s, i);
 #elif defined(HAVE_SETPROCTITLE)
     setproctitle("%.*s", (int)i, s);
-    rb_progname = rb_tainted_str_new(s, i);
+    progname = rb_tainted_str_new(s, i);
 #else
     if (len == 0) {
-	char *s = origargv[0];
-	int i;
-
-	s += strlen(s);
-	/* See if all the arguments are contiguous in memory */
-	for (i = 1; i < origargc; i++) {
-	    if (origargv[i] == s + 1) {
-		s++;
-		s += strlen(s);	/* this one is ok too */
-	    }
-	    else {
-		break;
-	    }
-	}
-#if defined(USE_ENVSPACE_FOR_ARG0)
-	if (s + 1 == envspace.begin) {
-	    s = envspace.end;
-	    ruby_setenv("", NULL); /* duplicate environ vars */
-	}
-#endif
-	len = s - origargv[0];
+	len = get_arglen(origargc, origargv);
     }
 
     if (i >= len) {
@@ -1104,10 +1119,13 @@
     s = origargv[0] + i;
     *s = '\0';
     if (++i < len) memset(s + 1, ' ', len - i);
-    for (i = 1; i < origargc; i++)
-	origargv[i] = s;
-    rb_progname = rb_tainted_str_new2(origargv[0]);
+    for (i = len-1, j = origargc-1; j > 0 && i >= 0; --i, --j) {
+	origargv[j] = origargv[0] + i;
+	*origargv[j] = '\0';
+    }
+    progname = rb_tainted_str_new2(origargv[0]);
 #endif
+    rb_progname = rb_obj_freeze(progname);
 }
 
 void
@@ -1115,7 +1133,7 @@
     const char *name;
 {
     if (name) {
-	rb_progname = rb_tainted_str_new2(name);
+	rb_progname = rb_obj_freeze(rb_tainted_str_new2(name));
 	ruby_sourcefile = rb_source_filename(name);
     }
 }
diff -burN ruby-1.8.7-p22/ruby.h ruby-1.8.7-p72/ruby.h
--- ruby-1.8.7-p22/ruby.h	2008-05-31 13:44:49.000000000 +0200
+++ ruby-1.8.7-p72/ruby.h	2008-07-10 06:54:53.000000000 +0200
@@ -2,7 +2,7 @@
 
   ruby.h -
 
-  $Author: knu $
+  $Author: shyouhei $
   created at: Thu Jun 10 14:26:32 JST 1993
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -166,7 +166,7 @@
 #define FIX2LONG(x) RSHIFT((long)x,1)
 #define FIX2ULONG(x) (((unsigned long)(x))>>1)
 #define FIXNUM_P(f) (((long)(f))&FIXNUM_FLAG)
-#define POSFIXABLE(f) ((f) <= FIXNUM_MAX)
+#define POSFIXABLE(f) ((f) < FIXNUM_MAX+1)
 #define NEGFIXABLE(f) ((f) >= FIXNUM_MIN)
 #define FIXABLE(f) (POSFIXABLE(f) && NEGFIXABLE(f))
 
diff -burN ruby-1.8.7-p22/string.c ruby-1.8.7-p72/string.c
--- ruby-1.8.7-p22/string.c	2008-06-20 11:28:35.000000000 +0200
+++ ruby-1.8.7-p72/string.c	2008-07-17 14:33:59.000000000 +0200
@@ -3,7 +3,7 @@
   string.c -
 
   $Author: shyouhei $
-  $Date: 2008-06-20 18:28:35 +0900 (Fri, 20 Jun 2008) $
+  $Date: 2008-07-17 21:33:59 +0900 (Thu, 17 Jul 2008) $
   created at: Mon Aug  9 17:12:58 JST 1993
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -462,7 +462,7 @@
 rb_str_format_m(str, arg)
     VALUE str, arg;
 {
-    VALUE tmp = rb_check_array_type(arg);
+    volatile VALUE tmp = rb_check_array_type(arg);
 
     if (!NIL_P(tmp)) {
 	return rb_str_format(RARRAY_LEN(tmp), RARRAY_PTR(tmp), str);
@@ -708,9 +708,13 @@
     const char *ptr;
     long len;
 {
-    long capa, total;
+    long capa, total, off = -1;;
 
     rb_str_modify(str);
+    if (ptr >= RSTRING(str)->ptr && ptr <= RSTRING(str)->ptr + RSTRING(str)->len) {
+        off = ptr - RSTRING(str)->ptr;
+    }
+    if (len == 0) return 0;
     if (FL_TEST(str, STR_ASSOC)) {
 	FL_UNSET(str, STR_ASSOC);
 	capa = RSTRING(str)->aux.capa = RSTRING(str)->len;
@@ -732,6 +736,9 @@
 	}
 	RESIZE_CAPA(str, capa);
     }
+    if (off != -1) {
+        ptr = RSTRING(str)->ptr + off;
+    }
     memcpy(RSTRING(str)->ptr + RSTRING(str)->len, ptr, len);
     RSTRING(str)->len = total;
     RSTRING(str)->ptr[total] = '\0'; /* sentinel */
diff -burN ruby-1.8.7-p22/test/erb/test_erb.rb ruby-1.8.7-p72/test/erb/test_erb.rb
--- ruby-1.8.7-p22/test/erb/test_erb.rb	2008-06-03 03:18:47.000000000 +0200
+++ ruby-1.8.7-p72/test/erb/test_erb.rb	2008-07-10 11:43:07.000000000 +0200
@@ -209,11 +209,13 @@
 n.times do |i|%>
 %% %%><%%<%= i%><%
 end%>
+%%%
 EOS
     ans = <<EOS
 % 
 % %%><%0
 % %%><%1
+%%
 EOS
     assert_equal(ans, ERB.new(src, nil, '%').result)
   end
diff -burN ruby-1.8.7-p22/test/ruby/test_float.rb ruby-1.8.7-p72/test/ruby/test_float.rb
--- ruby-1.8.7-p22/test/ruby/test_float.rb	2007-02-13 00:01:19.000000000 +0100
+++ ruby-1.8.7-p72/test/ruby/test_float.rb	2008-07-10 06:54:53.000000000 +0200
@@ -110,4 +110,38 @@
     assert_equal(-3.5, (-11.5).remainder(4))
     assert_equal(-3.5, (-11.5).remainder(-4))
   end
+
+  def test_to_i
+    assert_operator(4611686018427387905.0.to_i, :>, 0)
+    assert_operator(4611686018427387904.0.to_i, :>, 0)
+    assert_operator(4611686018427387903.8.to_i, :>, 0)
+    assert_operator(4611686018427387903.5.to_i, :>, 0)
+    assert_operator(4611686018427387903.2.to_i, :>, 0)
+    assert_operator(4611686018427387903.0.to_i, :>, 0)
+    assert_operator(4611686018427387902.0.to_i, :>, 0)
+
+    assert_operator(1073741825.0.to_i, :>, 0)
+    assert_operator(1073741824.0.to_i, :>, 0)
+    assert_operator(1073741823.8.to_i, :>, 0)
+    assert_operator(1073741823.5.to_i, :>, 0)
+    assert_operator(1073741823.2.to_i, :>, 0)
+    assert_operator(1073741823.0.to_i, :>, 0)
+    assert_operator(1073741822.0.to_i, :>, 0)
+
+    assert_operator((-1073741823.0).to_i, :<, 0)
+    assert_operator((-1073741824.0).to_i, :<, 0)
+    assert_operator((-1073741824.2).to_i, :<, 0)
+    assert_operator((-1073741824.5).to_i, :<, 0)
+    assert_operator((-1073741824.8).to_i, :<, 0)
+    assert_operator((-1073741825.0).to_i, :<, 0)
+    assert_operator((-1073741826.0).to_i, :<, 0)
+
+    assert_operator((-4611686018427387903.0).to_i, :<, 0)
+    assert_operator((-4611686018427387904.0).to_i, :<, 0)
+    assert_operator((-4611686018427387904.2).to_i, :<, 0)
+    assert_operator((-4611686018427387904.5).to_i, :<, 0)
+    assert_operator((-4611686018427387904.8).to_i, :<, 0)
+    assert_operator((-4611686018427387905.0).to_i, :<, 0)
+    assert_operator((-4611686018427387906.0).to_i, :<, 0)
+  end
 end
diff -burN ruby-1.8.7-p22/test/ruby/test_time.rb ruby-1.8.7-p72/test/ruby/test_time.rb
--- ruby-1.8.7-p22/test/ruby/test_time.rb	2007-02-13 00:01:19.000000000 +0100
+++ ruby-1.8.7-p72/test/ruby/test_time.rb	2008-06-29 13:09:30.000000000 +0200
@@ -71,4 +71,25 @@
       assert_equal(Time.at(0x7fffffff), Time.at(-0x80000000) - (-0xffffffff))
     end
   end
+
+  def test_at
+    assert_equal(100000, Time.at(0.1).usec)
+    assert_equal(10000, Time.at(0.01).usec)
+    assert_equal(1000, Time.at(0.001).usec)
+    assert_equal(100, Time.at(0.0001).usec)
+    assert_equal(10, Time.at(0.00001).usec)
+    assert_equal(1, Time.at(0.000001).usec)
+    assert_equal(0, Time.at(1e-7).usec)
+    assert_equal(0, Time.at(4e-7).usec)
+    assert_equal(1, Time.at(6e-7).usec)
+    assert_equal(1, Time.at(14e-7).usec)
+    assert_equal(2, Time.at(16e-7).usec)
+    if negative_time_t?
+      assert_equal(0, Time.at(-1e-7).usec)
+      assert_equal(0, Time.at(-4e-7).usec)
+      assert_equal(999999, Time.at(-6e-7).usec)
+      assert_equal(999999, Time.at(-14e-7).usec)
+      assert_equal(999998, Time.at(-16e-7).usec)
+    end
+  end
 end
diff -burN ruby-1.8.7-p22/time.c ruby-1.8.7-p72/time.c
--- ruby-1.8.7-p22/time.c	2008-06-06 12:39:57.000000000 +0200
+++ ruby-1.8.7-p72/time.c	2008-06-29 13:09:30.000000000 +0200
@@ -2,8 +2,8 @@
 
   time.c -
 
-  $Author: knu $
-  $Date: 2008-06-06 19:39:57 +0900 (Fri, 06 Jun 2008) $
+  $Author: shyouhei $
+  $Date: 2008-06-29 20:09:30 +0900 (Sun, 29 Jun 2008) $
   created at: Tue Dec 28 14:31:59 JST 1993
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -192,6 +192,10 @@
 	    double f, d;
 
 	    d = modf(RFLOAT(time)->value, &f);
+            if (d < 0) {
+                d += 1;
+                f -= 1;
+            }
 	    t.tv_sec = (time_t)f;
 	    if (f != t.tv_sec) {
 		rb_raise(rb_eRangeError, "%f out of Time range", RFLOAT(time)->value);
diff -burN ruby-1.8.7-p22/util.c ruby-1.8.7-p72/util.c
--- ruby-1.8.7-p22/util.c	2008-06-06 12:39:57.000000000 +0200
+++ ruby-1.8.7-p72/util.c	2008-06-29 10:10:06.000000000 +0200
@@ -2,8 +2,8 @@
 
   util.c -
 
-  $Author: knu $
-  $Date: 2008-06-06 19:39:57 +0900 (Fri, 06 Jun 2008) $
+  $Author: shyouhei $
+  $Date: 2008-06-29 17:10:06 +0900 (Sun, 29 Jun 2008) $
   created at: Fri Mar 10 17:22:34 JST 1995
 
   Copyright (C) 1993-2008 Yukihiro Matsumoto
@@ -2171,6 +2171,8 @@
     }
 #endif
     if (c == '.') {
+        if (!ISDIGIT(s[1]))
+            goto dig_done;
         c = *++s;
         if (!nd) {
             for (; c == '0'; c = *++s)
diff -burN ruby-1.8.7-p22/variable.c ruby-1.8.7-p72/variable.c
--- ruby-1.8.7-p22/variable.c	2008-05-31 13:44:49.000000000 +0200
+++ ruby-1.8.7-p72/variable.c	2008-06-29 11:28:00.000000000 +0200
@@ -2,8 +2,8 @@
 
   variable.c -
 
-  $Author: knu $
-  $Date: 2008-05-31 20:44:49 +0900 (Sat, 31 May 2008) $
+  $Author: shyouhei $
+  $Date: 2008-06-29 18:28:00 +0900 (Sun, 29 Jun 2008) $
   created at: Tue Apr 19 23:55:15 JST 1994
 
   Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -647,6 +647,7 @@
     struct trace_var *trace;
     st_data_t data;
 
+    rb_secure(4);
     rb_scan_args(argc, argv, "11", &var, &cmd);
     id = rb_to_id(var);
     if (!st_lookup(rb_global_tbl, id, &data)) {
diff -burN ruby-1.8.7-p22/version.h ruby-1.8.7-p72/version.h
--- ruby-1.8.7-p22/version.h	2008-06-20 11:28:35.000000000 +0200
+++ ruby-1.8.7-p72/version.h	2008-08-11 02:37:21.000000000 +0200
@@ -1,15 +1,15 @@
 #define RUBY_VERSION "1.8.7"
-#define RUBY_RELEASE_DATE "2008-06-20"
+#define RUBY_RELEASE_DATE "2008-08-11"
 #define RUBY_VERSION_CODE 187
-#define RUBY_RELEASE_CODE 20080620
-#define RUBY_PATCHLEVEL 22
+#define RUBY_RELEASE_CODE 20080811
+#define RUBY_PATCHLEVEL 72
 
 #define RUBY_VERSION_MAJOR 1
 #define RUBY_VERSION_MINOR 8
 #define RUBY_VERSION_TEENY 7
 #define RUBY_RELEASE_YEAR 2008
-#define RUBY_RELEASE_MONTH 6
-#define RUBY_RELEASE_DAY 20
+#define RUBY_RELEASE_MONTH 8
+#define RUBY_RELEASE_DAY 11
 
 #ifdef RUBY_EXTERN
 RUBY_EXTERN const char ruby_version[];
@@ -27,3 +27,5 @@
 
 #define RUBY_RELEASE_STR "patchlevel"
 #define RUBY_RELEASE_NUM RUBY_PATCHLEVEL
+
+
