<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -383,7 +383,7 @@ rb_ary_store(VALUE ary, long idx, VALUE val)
 	if (new_capa &lt; ARY_DEFAULT_SIZE) {
 	    new_capa = ARY_DEFAULT_SIZE;
 	}
-	else if (new_capa &gt;= ARY_MAX_SIZE - idx) {
+	if (new_capa &gt;= ARY_MAX_SIZE - idx) {
 	    new_capa = (ARY_MAX_SIZE - idx) / 2;
 	}
 	new_capa += idx;
@@ -986,10 +986,10 @@ rb_ary_splice(VALUE ary, long beg, long len, VALUE rpl)
     }
     rb_ary_modify(ary);
     if (beg &gt;= RARRAY_LEN(ary)) {
-	len = beg + rlen;
-	if (len &lt; 0 || len &gt; ARY_MAX_SIZE) {
+	if (beg &gt; ARY_MAX_SIZE - rlen) {
 	    rb_raise(rb_eIndexError, &quot;index %ld too big&quot;, beg);
 	}
+	len = beg + rlen;
 	if (len &gt;= ARY_CAPA(ary)) {
 	    RESIZE_CAPA(ary, len);
 	}</diff>
      <filename>array.c</filename>
    </modified>
    <modified>
      <diff>@@ -475,6 +475,7 @@ VALUE rb_range_beg_len(VALUE, long*, long*, long, int);
 /* random.c */
 unsigned long rb_genrand_int32(void);
 double rb_genrand_real(void);
+void rb_reset_random_seed(void);
 /* re.c */
 #define rb_memcmp memcmp
 int rb_memcicmp(const void*,const void*,long);</diff>
      <filename>include/ruby/intern.h</filename>
    </modified>
    <modified>
      <diff>@@ -38,6 +38,7 @@ void Init_Precision(void);
 void Init_sym(void);
 void Init_id(void);
 void Init_process(void);
+void Init_RandomSeed(void);
 void Init_Random(void);
 void Init_Range(void);
 void Init_Rational(void);
@@ -58,6 +59,7 @@ void Init_Encoding(void);
 void
 rb_call_inits()
 {
+    Init_RandomSeed();
     Init_sym();
     Init_id();
     Init_var_tables();</diff>
      <filename>inits.c</filename>
    </modified>
    <modified>
      <diff>@@ -66,7 +66,6 @@ module Open3
 
     pid = spawn(*cmd, STDIN=&gt;pw[0], STDOUT=&gt;pr[1], STDERR=&gt;pe[1])
     wait_thr = Process.detach(pid)
-    wait_thr[:pid] = pid
     pw[0].close
     pr[1].close
     pe[1].close</diff>
      <filename>lib/open3.rb</filename>
    </modified>
    <modified>
      <diff>@@ -885,6 +885,20 @@ proc_waitall(void)
     return result;
 }
 
+static inline ID
+id_pid(void)
+{
+    ID pid;
+    CONST_ID(pid, &quot;pid&quot;);
+    return pid;
+}
+
+static VALUE
+detach_process_pid(VALUE thread)
+{
+    return rb_thread_local_aref(thread, id_pid());
+}
+
 static VALUE
 detach_process_watcher(void *arg)
 {
@@ -900,7 +914,10 @@ detach_process_watcher(void *arg)
 VALUE
 rb_detach_process(rb_pid_t pid)
 {
-    return rb_thread_create(detach_process_watcher, (void*)(VALUE)pid);
+    VALUE watcher = rb_thread_create(detach_process_watcher, (void*)(VALUE)pid);
+    rb_thread_local_aset(watcher, id_pid(), PIDT2NUM(pid));
+    rb_define_singleton_method(watcher, &quot;pid&quot;, detach_process_pid, 0);
+    return watcher;
 }
 
 </diff>
      <filename>process.c</filename>
    </modified>
    <modified>
      <diff>@@ -199,6 +199,7 @@ rb_genrand_real(void)
     return genrand_real();
 }
 
+static int seed_initialized = 0;
 static VALUE saved_seed = INT2FIX(0);
 
 static VALUE
@@ -259,27 +260,21 @@ rand_init(VALUE vseed)
     return old;
 }
 
-static VALUE
-random_seed(void)
+#define DEFAULT_SEED_LEN (4 * sizeof(long))
+
+static void
+fill_random_seed(char *ptr)
 {
     static int n = 0;
+    unsigned long *seed;
     struct timeval tv;
     int fd;
     struct stat statbuf;
+    char *buf = (char*)ptr;
 
-    int seed_len;
-    BDIGIT *digits;
-    unsigned long *seed;
-    NEWOBJ(big, struct RBignum);
-    OBJSETUP(big, rb_cBignum, T_BIGNUM);
+    seed = (unsigned long *)buf;
 
-    seed_len = 4 * sizeof(long);
-    RBIGNUM_SET_SIGN(big, 1);
-    rb_big_resize((VALUE)big, seed_len / SIZEOF_BDIGITS + 1);
-    digits = RBIGNUM_DIGITS(big);
-    seed = (unsigned long *)RBIGNUM_DIGITS(big);
-
-    memset(digits, 0, RBIGNUM_LEN(big) * SIZEOF_BDIGITS);
+    memset(buf, 0, DEFAULT_SEED_LEN);
 
 #ifdef S_ISCHR
     if ((fd = open(&quot;/dev/urandom&quot;, O_RDONLY
@@ -294,7 +289,7 @@ random_seed(void)
 #endif
             )) &gt;= 0) {
         if (fstat(fd, &amp;statbuf) == 0 &amp;&amp; S_ISCHR(statbuf.st_mode)) {
-            read(fd, seed, seed_len);
+            read(fd, seed, DEFAULT_SEED_LEN);
         }
         close(fd);
     }
@@ -305,6 +300,20 @@ random_seed(void)
     seed[1] ^= tv.tv_sec;
     seed[2] ^= getpid() ^ (n++ &lt;&lt; 16);
     seed[3] ^= (unsigned long)&amp;seed;
+}
+
+static VALUE
+make_seed_value(char *ptr)
+{
+    BDIGIT *digits;
+    NEWOBJ(big, struct RBignum);
+    OBJSETUP(big, rb_cBignum, T_BIGNUM);
+
+    RBIGNUM_SET_SIGN(big, 1);
+    rb_big_resize((VALUE)big, DEFAULT_SEED_LEN / SIZEOF_BDIGITS + 1);
+    digits = RBIGNUM_DIGITS(big);
+
+    MEMCPY((char *)RBIGNUM_DIGITS(big), ptr, char, DEFAULT_SEED_LEN);
 
     /* set leading-zero-guard if need. */
     digits[RBIGNUM_LEN(big)-1] = digits[RBIGNUM_LEN(big)-2] &lt;= 1 ? 1 : 0;
@@ -312,6 +321,14 @@ random_seed(void)
     return rb_big_norm((VALUE)big);
 }
 
+static VALUE
+random_seed(void)
+{
+    char buf[DEFAULT_SEED_LEN];
+    fill_random_seed(buf);
+    return make_seed_value(buf);
+}
+
 /*
  *  call-seq:
  *     srand(number=0)    =&gt; old_seed
@@ -453,6 +470,9 @@ rb_f_rand(int argc, VALUE *argv, VALUE obj)
     long val, max;
 
     rb_scan_args(argc, argv, &quot;01&quot;, &amp;vmax);
+    if (!seed_initialized) {
+       rand_init(random_seed());
+    }
     switch (TYPE(vmax)) {
       case T_FLOAT:
 	if (RFLOAT_VALUE(vmax) &lt;= LONG_MAX &amp;&amp; RFLOAT_VALUE(vmax) &gt;= LONG_MIN) {
@@ -499,10 +519,34 @@ rb_f_rand(int argc, VALUE *argv, VALUE obj)
     return LONG2NUM(val);
 }
 
+static char initial_seed[DEFAULT_SEED_LEN];
+
+void
+Init_RandomSeed(void)
+{
+    fill_random_seed(initial_seed);
+    init_by_array((unsigned long*)initial_seed, DEFAULT_SEED_LEN/sizeof(unsigned long));
+    seed_initialized = 1;
+}
+
+static void
+Init_RandomSeed2(void)
+{
+    saved_seed = make_seed_value(initial_seed);
+    memset(initial_seed, 0, DEFAULT_SEED_LEN);
+}
+
+void
+rb_reset_random_seed(void)
+{
+    seed_initialized = 0;
+    saved_seed = INT2FIX(0);
+}
+
 void
 Init_Random(void)
 {
-    rand_init(random_seed());
+    Init_RandomSeed2();
     rb_define_global_function(&quot;srand&quot;, rb_f_srand, -1);
     rb_define_global_function(&quot;rand&quot;, rb_f_rand, -1);
     rb_global_variable(&amp;saved_seed);</diff>
      <filename>random.c</filename>
    </modified>
    <modified>
      <diff>@@ -1394,16 +1394,16 @@ rb_str_resize(VALUE str, long len)
     return str;
 }
 
-VALUE
-rb_str_buf_cat(VALUE str, const char *ptr, long len)
+static long
+str_buf_cat(VALUE str, const char *ptr, long len)
 {
-    long capa, total;
+    long capa, total, off = -1;
 
-    if (len == 0) return str;
-    if (len &lt; 0) {
-	rb_raise(rb_eArgError, &quot;negative string size (or size too big)&quot;);
+    if (ptr &gt;= RSTRING_PTR(str) &amp;&amp; ptr &lt;= RSTRING_END(str)) {
+        off = ptr - RSTRING_PTR(str);
     }
     rb_str_modify(str);
+    if (len == 0) return 0;
     if (STR_ASSOC_P(str)) {
 	FL_UNSET(str, STR_ASSOC);
 	capa = RSTRING(str)-&gt;as.heap.aux.capa = RSTRING_LEN(str);
@@ -1414,13 +1414,23 @@ rb_str_buf_cat(VALUE str, const char *ptr, long len)
     else {
 	capa = RSTRING(str)-&gt;as.heap.aux.capa;
     }
+    if (RSTRING_LEN(str) &gt;= LONG_MAX - len) {
+	rb_raise(rb_eArgError, &quot;string sizes too big&quot;);
+    }
     total = RSTRING_LEN(str)+len;
     if (capa &lt;= total) {
 	while (total &gt; capa) {
+	    if (capa + 1 &gt;= LONG_MAX / 2) {
+		capa = (total + 4095) / 4096;
+		break;
+	    }
 	    capa = (capa + 1) * 2;
 	}
 	RESIZE_CAPA(str, capa);
     }
+    if (off != -1) {
+        ptr = RSTRING_PTR(str) + off;
+    }
     memcpy(RSTRING_PTR(str) + RSTRING_LEN(str), ptr, len);
     STR_SET_LEN(str, total);
     RSTRING_PTR(str)[total] = '\0'; /* sentinel */
@@ -1429,6 +1439,16 @@ rb_str_buf_cat(VALUE str, const char *ptr, long len)
 }
 
 VALUE
+rb_str_buf_cat(VALUE str, const char *ptr, long len)
+{
+    if (len == 0) return str;
+    if (len &lt; 0) {
+	rb_raise(rb_eArgError, &quot;negative string size (or size too big)&quot;);
+    }
+    return str_buf_cat(str, ptr, len);
+}
+
+VALUE
 rb_str_buf_cat2(VALUE str, const char *ptr)
 {
     return rb_str_buf_cat(str, ptr, strlen(ptr));
@@ -1463,8 +1483,6 @@ static VALUE
 rb_enc_cr_str_buf_cat(VALUE str, const char *ptr, long len,
     int ptr_encindex, int ptr_cr, int *ptr_cr_ret)
 {
-    long capa, total, off = -1;
-
     int str_encindex = ENCODING_GET(str);
     int res_encindex;
     int str_cr, res_cr;
@@ -1543,41 +1561,7 @@ rb_enc_cr_str_buf_cat(VALUE str, const char *ptr, long len,
     if (len &lt; 0) {
 	rb_raise(rb_eArgError, &quot;negative string size (or size too big)&quot;);
     }
-    if (ptr &gt;= RSTRING_PTR(str) &amp;&amp; ptr &lt;= RSTRING_END(str)) {
-        off = ptr - RSTRING_PTR(str);
-    }
-    rb_str_modify(str);
-    if (len == 0) {
-        ENCODING_CODERANGE_SET(str, res_encindex, res_cr);
-        return str;
-    }
-    if (STR_ASSOC_P(str)) {
-	FL_UNSET(str, STR_ASSOC);
-	capa = RSTRING(str)-&gt;as.heap.aux.capa = RSTRING_LEN(str);
-    }
-    else if (STR_EMBED_P(str)) {
-	capa = RSTRING_EMBED_LEN_MAX;
-    }
-    else {
-	capa = RSTRING(str)-&gt;as.heap.aux.capa;
-    }
-    total = RSTRING_LEN(str)+len;
-    if (total &lt; 0 || capa + 1 &gt; LONG_MAX / 2) {
-	rb_raise(rb_eArgError, &quot;string sizes too big&quot;);
-    }
-    if (capa &lt;= total) {
-	while (total &gt; capa) {
-	    capa = (capa + 1) * 2;
-	}
-	RESIZE_CAPA(str, capa);
-    }
-    if (off != -1) {
-        ptr = RSTRING_PTR(str) + off;
-    }
-    memcpy(RSTRING_PTR(str) + RSTRING_LEN(str), ptr, len);
-    STR_SET_LEN(str, total);
-    RSTRING_PTR(str)[total] = '\0'; /* sentinel */
-
+    str_buf_cat(str, ptr, len);
     ENCODING_CODERANGE_SET(str, res_encindex, res_cr);
     return str;
 }
@@ -1820,13 +1804,21 @@ hash(const unsigned char * data, int len, unsigned int h)
 int
 rb_memhash(const void *ptr, long len)
 {
-    return hash(ptr, len, 0);
+    static int hashseed_init = 0;
+    static unsigned int hashseed;
+
+    if (!hashseed_init) {
+        hashseed = rb_genrand_int32();
+        hashseed_init = 1;
+    }
+
+    return hash(ptr, len, hashseed);
 }
 
 int
 rb_str_hash(VALUE str)
 {
-    return hash((const void *)RSTRING_PTR(str), RSTRING_LEN(str), 0);
+    return rb_memhash((const void *)RSTRING_PTR(str), RSTRING_LEN(str));
 }
 
 int
@@ -3113,6 +3105,8 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
 	int cr = ENC_CODERANGE(str);
 	VALUE match = rb_backref_get();
 	struct re_registers *regs = RMATCH_REGS(match);
+	long beg0 = BEG(0);
+	long end0 = END(0);
 
 	if (iter || !NIL_P(hash)) {
 	    char *p = RSTRING_PTR(str); long len = RSTRING_LEN(str);
@@ -3121,7 +3115,7 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
                 repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
             }
             else {
-                repl = rb_hash_aref(hash, rb_str_subseq(str, BEG(0), END(0) - BEG(0)));
+                repl = rb_hash_aref(hash, rb_str_subseq(str, beg0, end0 - beg0));
                 repl = rb_obj_as_string(repl);
             }
 	    str_mod_check(str, p, len);
@@ -3133,9 +3127,9 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
         enc = rb_enc_compatible(str, repl);
         if (!enc) {
             rb_encoding *str_enc = STR_ENC_GET(str);
-            if (coderange_scan(RSTRING_PTR(str), BEG(0), str_enc) != ENC_CODERANGE_7BIT ||
-                coderange_scan(RSTRING_PTR(str)+END(0),
-			       RSTRING_LEN(str)-END(0), str_enc) != ENC_CODERANGE_7BIT) {
+            if (coderange_scan(RSTRING_PTR(str), beg0, str_enc) != ENC_CODERANGE_7BIT ||
+                coderange_scan(RSTRING_PTR(str)+end0,
+			       RSTRING_LEN(str)-end0, str_enc) != ENC_CODERANGE_7BIT) {
                 rb_raise(rb_eArgError, &quot;character encodings differ: %s and %s&quot;,
 			 rb_enc_name(str_enc),
 			 rb_enc_name(STR_ENC_GET(repl)));
@@ -3149,16 +3143,16 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
 	    int cr2 = ENC_CODERANGE(repl);
 	    if (cr2 == ENC_CODERANGE_UNKNOWN || cr2 &gt; cr) cr = cr2;
 	}
-	plen = END(0) - BEG(0);
+	plen = end0 - beg0;
 	if (RSTRING_LEN(repl) &gt; plen) {
 	    RESIZE_CAPA(str, RSTRING_LEN(str) + RSTRING_LEN(repl) - plen);
 	}
 	if (RSTRING_LEN(repl) != plen) {
-	    memmove(RSTRING_PTR(str) + BEG(0) + RSTRING_LEN(repl),
-		    RSTRING_PTR(str) + BEG(0) + plen,
-		    RSTRING_LEN(str) - BEG(0) - plen);
+	    memmove(RSTRING_PTR(str) + beg0 + RSTRING_LEN(repl),
+		    RSTRING_PTR(str) + beg0 + plen,
+		    RSTRING_LEN(str) - beg0 - plen);
 	}
-	memcpy(RSTRING_PTR(str) + BEG(0),
+	memcpy(RSTRING_PTR(str) + beg0,
 	       RSTRING_PTR(repl), RSTRING_LEN(repl));
 	STR_SET_LEN(str, RSTRING_LEN(str) + RSTRING_LEN(repl) - plen);
 	RSTRING_PTR(str)[RSTRING_LEN(str)] = '\0';</diff>
      <filename>string.c</filename>
    </modified>
    <modified>
      <diff>@@ -683,6 +683,17 @@ class TestString &lt; Test::Unit::TestCase
     assert(S(&quot;hello&quot;).hash != S(&quot;helLO&quot;).hash)
   end
 
+  def test_hash_random
+    str = 'abc'
+    a = [str.hash.to_s]
+    3.times {
+      EnvUtil.rubyexec(&quot;-e&quot;, &quot;print #{str.dump}.hash&quot;) {|i,o,e|
+        a &lt;&lt; o.read
+      }
+    }
+    assert_not_equal([str.hash.to_s], a.uniq)
+  end
+
   def test_hex
     assert_equal(255,  S(&quot;0xff&quot;).hex)
     assert_equal(-255, S(&quot;-0xff&quot;).hex)</diff>
      <filename>test/ruby/test_string.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2124,6 +2124,7 @@ rb_thread_atfork(void)
     st_clear(vm-&gt;living_threads);
     st_insert(vm-&gt;living_threads, thval, (st_data_t) th-&gt;thread_id);
     vm-&gt;sleeper = 0;
+    rb_reset_random_seed();
 }
 
 static int</diff>
      <filename>thread.c</filename>
    </modified>
    <modified>
      <diff>@@ -34,9 +34,10 @@ for rev; do
     tag=
     case &quot;$rev&quot; in
 	trunk | branches/* | tags/*)
-	    url=$SVNURL/rev;;
+	    url=$SVNURL/$rev;;
 	stable)
-	    url=$SVNURL/brances/$(svn ls $SVNURL/branches | grep '^ruby_[0-9]_[0-9]/' | tail -1);;
+	    url=$SVNURL/branches
+	    url=/$(svn ls $url | grep '^ruby_[0-9]_[0-9]/' | tail -1);;
 	*.*.*-p* | *.*.*-*)
 	    tag=${rev##*-}; url=${rev/-p/_}; url=${url/-/_}; url=$SVNURL/tags/v${url//./_};;
 	*.*)</diff>
      <filename>tool/make-snapshot</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>60998fe2b0ee4347ee948b5096bcf108798fbb2e</id>
    </parent>
    <parent>
      <id>a524decfa111f8674da42664313837b12f7428d3</id>
    </parent>
  </parents>
  <author>
    <name>shyouhei</name>
    <email>shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e</email>
  </author>
  <url>http://github.com/rubyspec/matzruby/commit/4bdbd17f42090cf83b6e3e1bfebd58f3e8c9d056</url>
  <id>4bdbd17f42090cf83b6e3e1bfebd58f3e8c9d056</id>
  <committed-date>2008-06-20T00:39:32-07:00</committed-date>
  <authored-date>2008-06-20T00:39:32-07:00</authored-date>
  <message>add tag v1_9_0_2

git-svn-id: http://svn.ruby-lang.org/repos/ruby/tags/v1_9_0_2@17482 b2dd03c8-39d4-4d8f-98ff-823fe69b080e</message>
  <tree>a957464b0296925ad853bef9e9ed67a612ae9774</tree>
  <committer>
    <name>shyouhei</name>
    <email>shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e</email>
  </committer>
</commit>
