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

ruby-changes:68327

From: nagachika <ko1@a...>
Date: Sat, 9 Oct 2021 15:37:21 +0900 (JST)
Subject: [ruby-changes:68327] fe9d33beb7 (ruby_3_0): merge revision(s) 89242279e61b023a81c58065c62a82de8829d0b3,529fc204af84f825f98f83c34b004acbaa802615: [Backport #18141]

https://git.ruby-lang.org/ruby.git/commit/?id=fe9d33beb7

From fe9d33beb78d5c7932a5c2ca3953045c0ae751d5 Mon Sep 17 00:00:00 2001
From: nagachika <nagachika@r...>
Date: Sat, 9 Oct 2021 15:05:24 +0900
Subject: merge revision(s)
 89242279e61b023a81c58065c62a82de8829d0b3,529fc204af84f825f98f83c34b004acbaa802615:
 [Backport #18141]

	Marshal.load: do not call the proc until strings have their encoding

	Ref: https://bugs.ruby-lang.org/issues/18141
	---
	 marshal.c                             |  7 +++-
	 spec/ruby/core/marshal/shared/load.rb | 62 +++++++++++++++++++++++------------
	 test/ruby/test_marshal.rb             | 17 ++++++++++
	 3 files changed, 64 insertions(+), 22 deletions(-)

	marshal.c: don't call the proc with partially initialized objects.
	 (#4866)

	For cyclic objects, it requires to keep a st_table of the partially
	initialized objects.
	---
	 marshal.c                             | 75 ++++++++++++++++++++---------------
	 spec/ruby/core/marshal/shared/load.rb | 75 ++++++++++++++++++++---------------
	 test/ruby/test_marshal.rb             | 12 ++++++
	 3 files changed, 97 insertions(+), 65 deletions(-)
---
 marshal.c                             |  70 +++++++++++--------
 spec/ruby/core/marshal/shared/load.rb | 127 +++++++++++++++++++++-------------
 test/ruby/test_marshal.rb             |  29 ++++++++
 version.h                             |   4 +-
 4 files changed, 152 insertions(+), 78 deletions(-)

diff --git a/marshal.c b/marshal.c
index 5f0ac7e7bb..ed096f52fe 100644
--- a/marshal.c
+++ b/marshal.c
@@ -1137,6 +1137,7 @@ struct load_arg { https://github.com/ruby/ruby/blob/trunk/marshal.c#L1137
     long offset;
     st_table *symbols;
     st_table *data;
+    st_table *partial_objects;
     VALUE proc;
     st_table *compat_tbl;
 };
@@ -1163,6 +1164,7 @@ mark_load_arg(void *ptr) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1164
         return;
     rb_mark_tbl(p->symbols);
     rb_mark_tbl(p->data);
+    rb_mark_tbl(p->partial_objects);
     rb_mark_hash(p->compat_tbl);
 }
 
@@ -1516,6 +1518,7 @@ r_entry0(VALUE v, st_index_t num, struct load_arg *arg) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1518
         st_lookup(arg->compat_tbl, v, &real_obj);
     }
     st_insert(arg->data, num, real_obj);
+    st_insert(arg->partial_objects, (st_data_t)real_obj, Qtrue);
     return v;
 }
 
@@ -1546,10 +1549,15 @@ r_post_proc(VALUE v, struct load_arg *arg) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1549
 }
 
 static VALUE
-r_leave(VALUE v, struct load_arg *arg)
+r_leave(VALUE v, struct load_arg *arg, bool partial)
 {
     v = r_fixup_compat(v, arg);
-    v = r_post_proc(v, arg);
+    if (!partial) {
+	st_data_t data;
+	st_data_t key = (st_data_t)v;
+	st_delete(arg->partial_objects, &key, &data);
+	v = r_post_proc(v, arg);
+    }
     return v;
 }
 
@@ -1676,7 +1684,7 @@ append_extmod(VALUE obj, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1684
     } while (0)
 
 static VALUE
-r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
+r_object0(struct load_arg *arg, bool partial, int *ivp, VALUE extmod)
 {
     VALUE v = Qnil;
     int type = r_byte(arg);
@@ -1690,15 +1698,18 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1698
 	    rb_raise(rb_eArgError, "dump format error (unlinked)");
 	}
 	v = (VALUE)link;
-	v = r_post_proc(v, arg);
+	if (!st_lookup(arg->partial_objects, (st_data_t)v, &link)) {
+	    v = r_post_proc(v, arg);
+	}
 	break;
 
       case TYPE_IVAR:
         {
 	    int ivar = TRUE;
 
-	    v = r_object0(arg, &ivar, extmod);
+	    v = r_object0(arg, true, &ivar, extmod);
 	    if (ivar) r_ivar(v, NULL, arg);
+	    v = r_leave(v, arg, partial);
 	}
 	break;
 
@@ -1711,7 +1722,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1722
 	    if (RB_TYPE_P(m, T_CLASS)) { /* prepended */
 		VALUE c;
 
-		v = r_object0(arg, 0, Qnil);
+		v = r_object0(arg, true, 0, Qnil);
 		c = CLASS_OF(v);
 		if (c != m || FL_TEST(c, FL_SINGLETON)) {
 		    rb_raise(rb_eArgError,
@@ -1728,7 +1739,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1739
 		must_be_module(m, path);
 		rb_ary_push(extmod, m);
 
-		v = r_object0(arg, 0, extmod);
+		v = r_object0(arg, true, 0, extmod);
 		while (RARRAY_LEN(extmod) > 0) {
 		    m = rb_ary_pop(extmod);
 		    rb_extend_object(v, m);
@@ -1744,7 +1755,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1755
 	    if (FL_TEST(c, FL_SINGLETON)) {
 		rb_raise(rb_eTypeError, "singleton can't be loaded");
 	    }
-	    v = r_object0(arg, 0, extmod);
+	    v = r_object0(arg, partial, 0, extmod);
 	    if (rb_special_const_p(v) || RB_TYPE_P(v, T_OBJECT) || RB_TYPE_P(v, T_CLASS)) {
                 goto format_error;
 	    }
@@ -1762,17 +1773,17 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1773
 
       case TYPE_NIL:
 	v = Qnil;
-	v = r_leave(v, arg);
+	v = r_leave(v, arg, false);
 	break;
 
       case TYPE_TRUE:
 	v = Qtrue;
-	v = r_leave(v, arg);
+	v = r_leave(v, arg, false);
 	break;
 
       case TYPE_FALSE:
 	v = Qfalse;
-	v = r_leave(v, arg);
+	v = r_leave(v, arg, false);
 	break;
 
       case TYPE_FIXNUM:
@@ -1780,7 +1791,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1791
 	    long i = r_long(arg);
 	    v = LONG2FIX(i);
 	}
-	v = r_leave(v, arg);
+	v = r_leave(v, arg, false);
 	break;
 
       case TYPE_FLOAT:
@@ -1805,7 +1816,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1816
 	    }
 	    v = DBL2NUM(d);
 	    v = r_entry(v, arg);
-            v = r_leave(v, arg);
+            v = r_leave(v, arg, false);
 	}
 	break;
 
@@ -1822,13 +1833,13 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1833
                 INTEGER_PACK_LITTLE_ENDIAN | (sign == '-' ? INTEGER_PACK_NEGATIVE : 0));
 	    rb_str_resize(data, 0L);
 	    v = r_entry(v, arg);
-            v = r_leave(v, arg);
+            v = r_leave(v, arg, false);
 	}
 	break;
 
       case TYPE_STRING:
 	v = r_entry(r_string(arg), arg);
-        v = r_leave(v, arg);
+	v = r_leave(v, arg, partial);
 	break;
 
       case TYPE_REGEXP:
@@ -1863,7 +1874,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1874
 		rb_str_set_len(str, dst - ptr);
 	    }
 	    v = r_entry0(rb_reg_new_str(str, options), idx, arg);
-	    v = r_leave(v, arg);
+	    v = r_leave(v, arg, partial);
 	}
 	break;
 
@@ -1878,7 +1889,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1889
 		rb_ary_push(v, r_object(arg));
 		arg->readable--;
 	    }
-            v = r_leave(v, arg);
+            v = r_leave(v, arg, partial);
 	    arg->readable++;
 	}
 	break;
@@ -1901,7 +1912,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1912
 	    if (type == TYPE_HASH_DEF) {
 		RHASH_SET_IFNONE(v, r_object(arg));
 	    }
-            v = r_leave(v, arg);
+            v = r_leave(v, arg, partial);
 	}
 	break;
 
@@ -1953,7 +1964,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1964
 		}
 	    }
             rb_struct_initialize(v, values);
-            v = r_leave(v, arg);
+            v = r_leave(v, arg, partial);
 	    arg->readable += 2;
 	}
 	break;
@@ -1980,7 +1991,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1991
 		marshal_compat_t *compat = (marshal_compat_t*)d;
 		v = compat->loader(klass, v);
 	    }
-	    v = r_post_proc(v, arg);
+	    if (!partial) v = r_post_proc(v, arg);
 	}
         break;
 
@@ -2022,7 +2033,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L2033
 	    }
 	    v = r_entry0(v, idx, arg);
 	    r_ivar(v, NULL, arg);
-	    v = r_leave(v, arg);
+	    v = r_leave(v, arg, partial);
 	}
 	break;
 
@@ -2043,9 +2054,9 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L2054
 			 "class %"PRIsVALUE" needs to have instance method `_load_data'",
 			 name);
 	    }
-	    r = r_object0(arg, 0, extmod);
+	    r = r_object0(arg, partial, 0, extmod);
 	    load_funcall(arg, v, s_load_data, 1, &r);
-	    v = r_leave(v, arg);
+	    v = r_leave(v, arg, partial);
 	}
 	break;
 
@@ -2056,7 +2067,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L2067
 	    v = rb_path_to_class(str);
 	    prohibit_ivar("class/module", str);
 	    v = r_entry(v, arg);
-            v = r_leave(v, arg);
+            v = r_leave(v, arg, partial);
 	}
 	break;
 
@@ -2067,7 +2078,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L2078
 	    v = path2class(str);
 	    prohibit_ivar("class", str);
 	    v = r_entry(v, arg);
-            v = r_leave(v, arg);
+            v = r_leave(v, arg, partial);
 	}
 	break;
 
@@ -2078,7 +2089,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L2089
 	    v = path2module(str);
 	    prohibit_ivar("module", str);
 	    v = r_entry(v, arg);
-            v = r_leave(v, arg);
+            v = r_leave(v, arg, partial);
 	}
 	break;
 
@@ -2091,7 +2102,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) https://github.com/ruby/ruby/blob/trunk/marshal.c#L2102
 	    v = r_symreal(arg, 0);
 	}
 	v = rb_str_intern(v);
-	v = r_leave(v, arg);
+	v = r_leave(v, arg, partial);
 	break;
 
       case TYPE_SYMLINK:
@@ -2113,7 +2124,7 @@ r_object0(struct lo (... truncated)

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

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