[前][次][番号順一覧][スレッド一覧]

ruby-changes:28927

From: ko1 <ko1@a...>
Date: Wed, 29 May 2013 10:39:09 +0900 (JST)
Subject: [ruby-changes:28927] ko1:r40979 (trunk): * hash.c: fix WB bug.

ko1	2013-05-29 10:38:52 +0900 (Wed, 29 May 2013)

  New Revision: 40979

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=40979

  Log:
    * hash.c: fix WB bug.
      (1) Hash's key also needs WB.
      (2) callback parameter *key and *value of st_update() is not a
      storage of st_table itself (only local variable). So that
      OBJ_WRITE() is not suitable, especially for `!exsinting'.
      OBJ_WRITTEN() is used instead of OBJ_WRITE().

  Modified files:
    trunk/ChangeLog
    trunk/hash.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 40978)
+++ ChangeLog	(revision 40979)
@@ -1,3 +1,12 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Wed May 29 10:33:27 2013  Koichi Sasada  <ko1@a...>
+
+	* hash.c: fix WB bug.
+	  (1) Hash's key also needs WB.
+	  (2) callback parameter *key and *value of st_update() is not a
+	      storage of st_table itself (only local variable). So that
+	      OBJ_WRITE() is not suitable, especially for `!exsinting'.
+	      OBJ_WRITTEN() is used instead of OBJ_WRITE().
+
 Tue May 28 12:31:21 2013  Koichi Sasada  <ko1@a...>
 
 	* ext/objspace/object_tracing.c: fix a bug reported at
Index: hash.c
===================================================================
--- hash.c	(revision 40978)
+++ hash.c	(revision 40979)
@@ -1193,14 +1193,23 @@ rb_hash_clear(VALUE hash) https://github.com/ruby/ruby/blob/trunk/hash.c#L1193
 static int
 hash_aset(VALUE hash, st_data_t *key, st_data_t *val, st_data_t arg, int existing)
 {
-    OBJ_WRITE(hash, (VALUE *)val, arg);
+    if (existing) {
+	OBJ_WRITTEN(hash, *val, arg);
+    }
+    else {
+	OBJ_WRITTEN(hash, Qundef, *key);
+	OBJ_WRITTEN(hash, Qundef, arg);
+    }
+    *val = arg;
     return ST_CONTINUE;
 }
 
 static int
 hash_aset_str(VALUE hash, st_data_t *key, st_data_t *val, st_data_t arg, int existing)
 {
-    OBJ_WRITE(hash, (VALUE *)key, rb_str_new_frozen((VALUE)*key));
+    if (!existing) {
+	*key = rb_str_new_frozen((VALUE)*key);
+    }
     return hash_aset(hash, key, val, arg, existing);
 }
 
@@ -1879,7 +1888,14 @@ rb_hash_invert(VALUE hash) https://github.com/ruby/ruby/blob/trunk/hash.c#L1888
 static int
 rb_hash_update_callback(VALUE hash, st_data_t *key, st_data_t *value, st_data_t arg, int existing)
 {
-    OBJ_WRITE(hash, (VALUE *)value, (VALUE)arg);
+    if (existing) {
+	OBJ_WRITTEN(hash, *value, arg);
+    }
+    else {
+	OBJ_WRITTEN(hash, Qundef, *key);
+	OBJ_WRITTEN(hash, Qundef, arg);
+    }
+    *value = arg;
     return ST_CONTINUE;
 }
 
@@ -1896,10 +1912,16 @@ static int https://github.com/ruby/ruby/blob/trunk/hash.c#L1912
 rb_hash_update_block_callback(VALUE hash, st_data_t *key, st_data_t *value, st_data_t arg, int existing)
 {
     VALUE newvalue = (VALUE)arg;
+
     if (existing) {
 	newvalue = rb_yield_values(3, (VALUE)*key, (VALUE)*value, newvalue);
+	OBJ_WRITTEN(hash, *value, newvalue);
     }
-    OBJ_WRITE(hash, (VALUE *)value, newvalue);
+    else {
+	OBJ_WRITTEN(hash, Qundef, *key);
+	OBJ_WRITTEN(hash, Qundef, newvalue);
+    }
+    *value = newvalue;
     return ST_CONTINUE;
 }
 
@@ -1962,8 +1984,13 @@ rb_hash_update_func_callback(VALUE hash, https://github.com/ruby/ruby/blob/trunk/hash.c#L1984
     VALUE newvalue = arg->value;
     if (existing) {
 	newvalue = (*arg->func)((VALUE)*key, (VALUE)*value, newvalue);
+	OBJ_WRITTEN(hash, *value, newvalue);
+    }
+    else {
+	OBJ_WRITTEN(hash, Qundef, *key);
+	OBJ_WRITTEN(hash, Qundef, newvalue);
     }
-    OBJ_WRITE(hash, (VALUE *)value, (VALUE)newvalue);
+    *value = newvalue;
     return ST_CONTINUE;
 }
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]