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

ruby-changes:39858

From: nobu <ko1@a...>
Date: Fri, 25 Sep 2015 21:45:36 +0900 (JST)
Subject: [ruby-changes:39858] nobu:r51939 (trunk): marshal.c: reentrant checks

nobu	2015-09-25 21:45:10 +0900 (Fri, 25 Sep 2015)

  New Revision: 51939

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

  Log:
    marshal.c: reentrant checks
    
    * marshal.c (dump_funcall, dump_check_funcall, load_funcall):
      function calls with reentrant check.  always show names
      corresponding to the called methods.

  Modified files:
    trunk/marshal.c
Index: marshal.c
===================================================================
--- marshal.c	(revision 51938)
+++ marshal.c	(revision 51939)
@@ -165,15 +165,19 @@ struct dump_call_arg { https://github.com/ruby/ruby/blob/trunk/marshal.c#L165
     int limit;
 };
 
-static void
-check_dump_arg(struct dump_arg *arg, const char *name)
+static VALUE
+check_dump_arg(VALUE ret, struct dump_arg *arg, const char *name)
 {
     if (!arg->symbols) {
         rb_raise(rb_eRuntimeError, "Marshal.dump reentered at %s",
 		 name);
     }
+    return ret;
 }
-#define check_dump_arg(arg, sym) check_dump_arg(arg, name_##sym)
+#define dump_funcall(arg, obj, sym, argc, argv) \
+    check_dump_arg(rb_funcallv(obj, sym, argc, argv), arg, name_##sym)
+#define dump_check_funcall(arg, obj, sym, argc, argv) \
+    check_dump_arg(rb_check_funcall(obj, sym, argc, argv), arg, name_##sym)
 
 static void clear_dump_arg(struct dump_arg *arg);
 
@@ -712,8 +716,7 @@ w_object(VALUE obj, struct dump_arg *arg https://github.com/ruby/ruby/blob/trunk/marshal.c#L716
 	if (rb_obj_respond_to(obj, s_mdump, TRUE)) {
 	    st_add_direct(arg->data, obj, arg->data->num_entries);
 
-	    v = rb_funcall2(obj, s_mdump, 0, 0);
-	    check_dump_arg(arg, s_mdump);
+	    v = dump_funcall(arg, obj, s_mdump, 0, 0);
 	    w_class(TYPE_USRMARSHAL, obj, arg, FALSE);
 	    w_object(v, arg, limit);
 	    return;
@@ -724,8 +727,7 @@ w_object(VALUE obj, struct dump_arg *arg https://github.com/ruby/ruby/blob/trunk/marshal.c#L727
 	    VALUE encname2;
 
 	    v = INT2NUM(limit);
-	    v = rb_funcall2(obj, s_dump, 1, &v);
-	    check_dump_arg(arg, s_dump);
+	    v = dump_funcall(arg, obj, s_dump, 1, &v);
 	    if (!RB_TYPE_P(v, T_STRING)) {
 		rb_raise(rb_eTypeError, "_dump() must return string");
 	    }
@@ -907,8 +909,7 @@ w_object(VALUE obj, struct dump_arg *arg https://github.com/ruby/ruby/blob/trunk/marshal.c#L909
 			     "no _dump_data is defined for class %"PRIsVALUE,
 			     rb_obj_class(obj));
 		}
-		v = rb_funcall2(obj, s_dump_data, 0, 0);
-		check_dump_arg(arg, s_dump_data);
+		v = dump_funcall(arg, obj, s_dump_data, 0, 0);
 		w_class(TYPE_DATA, obj, arg, TRUE);
 		w_object(v, arg, limit);
 	    }
@@ -1018,9 +1019,7 @@ marshal_dump(int argc, VALUE *argv) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1019
 	    io_needed();
 	}
 	arg->dest = port;
-	if (rb_check_funcall(port, s_binmode, 0, 0) != Qundef) {
-	    check_dump_arg(arg, s_binmode);
-	}
+	dump_check_funcall(arg, port, s_binmode, 0, 0);
     }
     else {
 	port = arg->str;
@@ -1053,15 +1052,17 @@ struct load_arg { https://github.com/ruby/ruby/blob/trunk/marshal.c#L1052
     int infection;
 };
 
-static void
-check_load_arg(struct load_arg *arg, const char *name)
+static VALUE
+check_load_arg(VALUE ret, struct load_arg *arg, const char *name)
 {
     if (!arg->symbols) {
         rb_raise(rb_eRuntimeError, "Marshal.load reentered at %s",
 		 name);
     }
+    return ret;
 }
-#define check_load_arg(arg, sym) check_load_arg(arg, name_##sym)
+#define load_funcall(arg, obj, sym, argc, argv) \
+    check_load_arg(rb_funcallv(obj, sym, argc, argv), arg, name_##sym)
 
 static void clear_load_arg(struct load_arg *arg);
 
@@ -1124,9 +1125,7 @@ r_byte1_buffered(struct load_arg *arg) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1125
 	long readable = arg->readable < BUFSIZ ? arg->readable : BUFSIZ;
 	VALUE str, n = LONG2NUM(readable);
 
-	str = rb_funcall2(arg->src, s_read, 1, &n);
-
-	check_load_arg(arg, s_read);
+	str = load_funcall(arg, arg->src, s_read, 1, &n);
 	if (NIL_P(str)) too_short();
 	StringValue(str);
 	arg->infection |= (int)FL_TEST(str, MARSHAL_INFECTION);
@@ -1156,8 +1155,7 @@ r_byte(struct load_arg *arg) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1155
 	    c = r_byte1_buffered(arg);
 	}
 	else {
-	    VALUE v = rb_funcall2(arg->src, s_getbyte, 0, 0);
-	    check_load_arg(arg, s_getbyte);
+	    VALUE v = load_funcall(arg, arg->src, s_getbyte, 0, 0);
 	    if (NIL_P(v)) rb_eof_error();
 	    c = (unsigned char)NUM2CHR(v);
 	}
@@ -1218,8 +1216,7 @@ r_bytes1(long len, struct load_arg *arg) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1216
 {
     VALUE str, n = LONG2NUM(len);
 
-    str = rb_funcall2(arg->src, s_read, 1, &n);
-    check_load_arg(arg, s_read);
+    str = load_funcall(arg, arg->src, s_read, 1, &n);
     if (NIL_P(str)) too_short();
     StringValue(str);
     if (RSTRING_LEN(str) != len) too_short();
@@ -1247,9 +1244,7 @@ r_bytes1_buffered(long len, struct load_ https://github.com/ruby/ruby/blob/trunk/marshal.c#L1244
 	readable = readable < BUFSIZ ? readable : BUFSIZ;
 	read_len = need_len > readable ? need_len : readable;
 	n = LONG2NUM(read_len);
-	tmp = rb_funcall2(arg->src, s_read, 1, &n);
-
-	check_load_arg(arg, s_read);
+	tmp = load_funcall(arg, arg->src, s_read, 1, &n);
 	if (NIL_P(tmp)) too_short();
 	StringValue(tmp);
 
@@ -1434,8 +1429,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/marshal.c#L1429
 r_post_proc(VALUE v, struct load_arg *arg)
 {
     if (arg->proc) {
-	v = rb_funcall(arg->proc, s_call, 1, v);
-	check_load_arg(arg, s_call);
+	v = load_funcall(arg, arg->proc, s_call, 1, &v);
     }
     return v;
 }
@@ -1839,8 +1833,7 @@ r_object0(struct load_arg *arg, int *ivp https://github.com/ruby/ruby/blob/trunk/marshal.c#L1833
 		r_ivar(data, NULL, arg);
 		*ivp = FALSE;
 	    }
-	    v = rb_funcall2(klass, s_load, 1, &data);
-	    check_load_arg(arg, s_load);
+	    v = load_funcall(arg, klass, s_load, 1, &data);
 	    v = r_entry(v, arg);
             v = r_leave(v, arg);
 	}
@@ -1864,8 +1857,7 @@ r_object0(struct load_arg *arg, int *ivp https://github.com/ruby/ruby/blob/trunk/marshal.c#L1857
 	    }
 	    v = r_entry(v, arg);
 	    data = r_object(arg);
-	    rb_funcall2(v, s_mload, 1, &data);
-	    check_load_arg(arg, s_mload);
+	    load_funcall(arg, v, s_mload, 1, &data);
 	    v = r_fixup_compat(v, arg);
 	    v = r_copy_ivar(v, data);
 	    v = r_post_proc(v, arg);
@@ -1907,8 +1899,7 @@ r_object0(struct load_arg *arg, int *ivp https://github.com/ruby/ruby/blob/trunk/marshal.c#L1899
 			 name);
 	    }
 	    r = r_object0(arg, 0, extmod);
-	    rb_funcall2(v, s_load_data, 1, &r);
-	    check_load_arg(arg, s_load_data);
+	    load_funcall(arg, v, s_load_data, 1, &r);
 	    v = r_leave(v, arg);
 	}
 	break;

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

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