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

ruby-changes:27590

From: nobu <ko1@a...>
Date: Sat, 9 Mar 2013 00:26:59 +0900 (JST)
Subject: [ruby-changes:27590] nobu:r39642 (trunk): marshal.c: prepended objects

nobu	2013-03-09 00:26:08 +0900 (Sat, 09 Mar 2013)

  New Revision: 39642

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

  Log:
    marshal.c: prepended objects
    
    * marshal.c (r_object0): load prepended objects.  treat the class of
      extended object in the included modules as prepended singleton
      class. [ruby-core:53202] [Bug #8041]

  Modified files:
    trunk/ChangeLog
    trunk/marshal.c
    trunk/test/ruby/marshaltestlib.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 39641)
+++ ChangeLog	(revision 39642)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Mar  9 00:25:57 2013  Nobuyoshi Nakada  <nobu@r...>
+
+	* marshal.c (r_object0): load prepended objects.  treat the class of
+	  extended object in the included modules as prepended singleton
+	  class. [ruby-core:53202] [Bug #8041]
+
 Fri Mar  8 19:44:00 2013  Akinori MUSHA  <knu@i...>
 
 	* man/rake.1, man/ruby.1: Use the Pa macro to make URLs stand out.
Index: marshal.c
===================================================================
--- marshal.c	(revision 39641)
+++ marshal.c	(revision 39642)
@@ -1387,11 +1387,11 @@ path2class(VALUE path) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1387
     return v;
 }
 
+#define path2module(path) must_be_module(rb_path_to_class(path), path)
+
 static VALUE
-path2module(VALUE path)
+must_be_module(VALUE v, VALUE path)
 {
-    VALUE v = rb_path_to_class(path);
-
     if (!RB_TYPE_P(v, T_MODULE)) {
 	rb_raise(rb_eArgError, "%"PRIsVALUE" does not refer to module", path);
     }
@@ -1473,16 +1473,36 @@ r_object0(struct load_arg *arg, int *ivp https://github.com/ruby/ruby/blob/trunk/marshal.c#L1473
 
       case TYPE_EXTENDED:
 	{
-	    VALUE m = path2module(r_unique(arg));
+	    VALUE path = r_unique(arg);
+	    VALUE m = rb_path_to_class(path);
 
-            if (NIL_P(extmod)) extmod = rb_ary_tmp_new(0);
-            rb_ary_push(extmod, m);
+	    if (RB_TYPE_P(m, T_CLASS)) { /* prepended */
+		VALUE c;
 
-	    v = r_object0(arg, 0, extmod);
-            while (RARRAY_LEN(extmod) > 0) {
-                m = rb_ary_pop(extmod);
-                rb_extend_object(v, m);
-            }
+		v = r_object0(arg, 0, Qnil);
+		c = CLASS_OF(v);
+		if (c != m || FL_TEST(c, FL_SINGLETON)) {
+		    rb_raise(rb_eArgError,
+			     "prepended class %"PRIsVALUE" differs from class %"PRIsVALUE,
+			     path, rb_class_name(c));
+		}
+		c = rb_singleton_class(v);
+		while (RARRAY_LEN(extmod) > 0) {
+		    m = rb_ary_pop(extmod);
+		    rb_prepend_module(c, m);
+		}
+	    }
+	    else {
+		must_be_module(m, path);
+		if (NIL_P(extmod)) extmod = rb_ary_tmp_new(0);
+		rb_ary_push(extmod, m);
+
+		v = r_object0(arg, 0, extmod);
+		while (RARRAY_LEN(extmod) > 0) {
+		    m = rb_ary_pop(extmod);
+		    rb_extend_object(v, m);
+		}
+	    }
 	}
 	break;
 
Index: test/ruby/marshaltestlib.rb
===================================================================
--- test/ruby/marshaltestlib.rb	(revision 39641)
+++ test/ruby/marshaltestlib.rb	(revision 39642)
@@ -75,6 +75,16 @@ module MarshalTestLib https://github.com/ruby/ruby/blob/trunk/test/ruby/marshaltestlib.rb#L75
     marshal_equal_with_ancestry(o1)
   end
 
+  def test_object_prepend
+    bug8041 = '[ruby-core:53202] [Bug #8041]'
+
+    o1 = MyObject.new(42)
+    o1.singleton_class.class_eval {prepend Mod1}
+    assert_nothing_raised(ArgumentError, bug8041) {
+      marshal_equal_with_ancestry(o1, bug8041)
+    }
+  end
+
   class MyArray < Array
     def initialize(v, *args)
       super(args)

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

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