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

ruby-changes:23871

From: nobu <ko1@a...>
Date: Tue, 5 Jun 2012 20:13:56 +0900 (JST)
Subject: [ruby-changes:23871] nobu:r35922 (trunk): obj_init_copy

nobu	2012-06-05 20:13:18 +0900 (Tue, 05 Jun 2012)

  New Revision: 35922

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

  Log:
    obj_init_copy
    
    * object.c (rb_obj_init_copy): should check if trusted too.

  Modified files:
    trunk/ChangeLog
    trunk/enumerator.c
    trunk/file.c
    trunk/include/ruby/intern.h
    trunk/io.c
    trunk/object.c
    trunk/random.c
    trunk/re.c
    trunk/struct.c
    trunk/test/ruby/test_object.rb
    trunk/time.c

Index: time.c
===================================================================
--- time.c	(revision 35921)
+++ time.c	(revision 35922)
@@ -3425,8 +3425,7 @@
 {
     struct time_object *tobj, *tcopy;
 
-    if (copy == time) return copy;
-    time_modify(copy);
+    if (!OBJ_INIT_COPY(copy, time)) return copy;
     GetTimeval(time, tobj);
     GetTimeval(copy, tcopy);
     MEMCPY(tcopy, tobj, struct time_object, 1);
Index: include/ruby/intern.h
===================================================================
--- include/ruby/intern.h	(revision 35921)
+++ include/ruby/intern.h	(revision 35922)
@@ -252,6 +252,9 @@
 #define rb_check_trusted(obj) rb_check_trusted_inline(obj)
 #endif
 
+#define OBJ_INIT_COPY(obj, orig) \
+    ((obj) != (orig) && (rb_obj_init_copy((obj), (orig)), 1))
+
 /* eval.c */
 int rb_sourceline(void);
 const char *rb_sourcefile(void);
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 35921)
+++ ChangeLog	(revision 35922)
@@ -1,3 +1,7 @@
+Tue Jun  5 20:13:15 2012  Nobuyoshi Nakada  <nobu@r...>
+
+	* object.c (rb_obj_init_copy): should check if trusted too.
+
 Tue Jun  5 19:59:13 2012  Tanaka Akira  <akr@f...>
 
 	* process.c (strtok): declaration removed because it is not used.
Index: re.c
===================================================================
--- re.c	(revision 35921)
+++ re.c	(revision 35922)
@@ -939,11 +939,8 @@
 {
     struct rmatch *rm;
 
-    if (obj == orig) return obj;
+    if (!OBJ_INIT_COPY(obj, orig)) return obj;
 
-    if (!rb_obj_is_instance_of(orig, rb_obj_class(obj))) {
-	rb_raise(rb_eTypeError, "wrong argument class");
-    }
     RMATCH(obj)->str = RMATCH(orig)->str;
     RMATCH(obj)->regexp = RMATCH(orig)->regexp;
 
@@ -3260,12 +3257,7 @@
     const char *s;
     long len;
 
-    if (copy == re) return copy;
-    rb_check_frozen(copy);
-    /* need better argument type check */
-    if (!rb_obj_is_instance_of(re, rb_obj_class(copy))) {
-	rb_raise(rb_eTypeError, "wrong argument type");
-    }
+    if (!OBJ_INIT_COPY(copy, re)) return copy;
     rb_reg_check(re);
     s = RREGEXP_SRC_PTR(re);
     len = RREGEXP_SRC_LEN(re);
Index: enumerator.c
===================================================================
--- enumerator.c	(revision 35921)
+++ enumerator.c	(revision 35922)
@@ -373,6 +373,7 @@
 {
     struct enumerator *ptr0, *ptr1;
 
+    if (!OBJ_INIT_COPY(obj, orig)) return obj;
     ptr0 = enumerator_ptr(orig);
     if (ptr0->fib) {
 	/* Fibers cannot be copied */
@@ -1146,6 +1147,8 @@
 {
     struct generator *ptr0, *ptr1;
 
+    if (!OBJ_INIT_COPY(obj, orig)) return obj;
+
     ptr0 = generator_ptr(orig);
 
     TypedData_Get_Struct(obj, struct generator, &generator_data_type, ptr1);
Index: object.c
===================================================================
--- object.c	(revision 35921)
+++ object.c	(revision 35922)
@@ -342,6 +342,7 @@
 {
     if (obj == orig) return obj;
     rb_check_frozen(obj);
+    rb_check_trusted(obj);
     if (TYPE(obj) != TYPE(orig) || rb_obj_class(obj) != rb_obj_class(orig)) {
 	rb_raise(rb_eTypeError, "initialize_copy should take same class object");
     }
Index: io.c
===================================================================
--- io.c	(revision 35921)
+++ io.c	(revision 35922)
@@ -6387,7 +6387,7 @@
     off_t pos;
 
     io = rb_io_get_io(io);
-    if (dest == io) return dest;
+    if (!OBJ_INIT_COPY(dest, io)) return dest;
     GetOpenFile(io, orig);
     MakeOpenFile(dest, fptr);
 
@@ -7286,6 +7286,7 @@
 static VALUE
 argf_initialize_copy(VALUE argf, VALUE orig)
 {
+    if (!OBJ_INIT_COPY(argf, orig)) return argf;
     ARGF = argf_of(orig);
     ARGF.argv = rb_obj_dup(ARGF.argv);
     if (ARGF.inplace) {
Index: struct.c
===================================================================
--- struct.c	(revision 35921)
+++ struct.c	(revision 35922)
@@ -606,11 +606,7 @@
 VALUE
 rb_struct_init_copy(VALUE copy, VALUE s)
 {
-    if (copy == s) return copy;
-    rb_check_frozen(copy);
-    if (!rb_obj_is_instance_of(s, rb_obj_class(copy))) {
-	rb_raise(rb_eTypeError, "wrong argument class");
-    }
+    if (!OBJ_INIT_COPY(copy, s)) return copy;
     if (RSTRUCT_LEN(copy) != RSTRUCT_LEN(s)) {
 	rb_raise(rb_eTypeError, "struct size mismatch");
     }
Index: test/ruby/test_object.rb
===================================================================
--- test/ruby/test_object.rb	(revision 35921)
+++ test/ruby/test_object.rb	(revision 35922)
@@ -764,4 +764,36 @@
       assert_equal((eval("raise #{code}") rescue $!.inspect), out.chomp, bug5473)
     end
   end
+
+  def assert_not_initialize_copy
+    a = yield
+    b = yield
+    assert_nothing_raised("copy") {a.instance_eval {initialize_copy(b)}}
+    c = a.dup.freeze
+    assert_raise(RuntimeError, "frozen") {c.instance_eval {initialize_copy(b)}}
+    d = a.dup.trust
+    assert_raise(SecurityError, "untrust") do
+      proc {
+        $SAFE = 4
+        d.instance_eval {initialize_copy(b)}
+      }.call
+    end
+    [a, b, c, d]
+  end
+
+  def test_bad_initialize_copy
+    assert_not_initialize_copy {Object.new}
+    assert_not_initialize_copy {[].to_enum}
+    assert_not_initialize_copy {Enumerator::Generator.new {}}
+    assert_not_initialize_copy {Enumerator::Yielder.new {}}
+    assert_not_initialize_copy {File.stat(__FILE__)}
+    assert_not_initialize_copy {open(__FILE__)}.each(&:close)
+    assert_not_initialize_copy {ARGF.class.new}
+    assert_not_initialize_copy {Random.new}
+    assert_not_initialize_copy {//}
+    assert_not_initialize_copy {/.*/.match("foo")}
+    st = Struct.new(:foo)
+    assert_not_initialize_copy {st.new}
+    assert_not_initialize_copy {Time.now}
+  end
 end
Index: file.c
===================================================================
--- file.c	(revision 35921)
+++ file.c	(revision 35922)
@@ -4470,12 +4470,7 @@
 {
     struct stat *nst;
 
-    if (copy == orig) return orig;
-    rb_check_frozen(copy);
-    /* need better argument type check */
-    if (!rb_obj_is_instance_of(orig, rb_obj_class(copy))) {
-	rb_raise(rb_eTypeError, "wrong argument class");
-    }
+    if (!OBJ_INIT_COPY(copy, orig)) return copy;
     if (DATA_PTR(copy)) {
 	xfree(DATA_PTR(copy));
 	DATA_PTR(copy) = 0;
Index: random.c
===================================================================
--- random.c	(revision 35921)
+++ random.c	(revision 35922)
@@ -596,10 +596,15 @@
 static VALUE
 random_copy(VALUE obj, VALUE orig)
 {
-    rb_random_t *rnd1 = get_rnd(obj);
-    rb_random_t *rnd2 = get_rnd(orig);
-    struct MT *mt = &rnd1->mt;
+    rb_random_t *rnd1, *rnd2;
+    struct MT *mt;
 
+    if (!OBJ_INIT_COPY(obj, orig)) return obj;
+
+    rnd1 = get_rnd(obj);
+    rnd2 = get_rnd(orig);
+    mt = &rnd1->mt;
+
     *rnd1 = *rnd2;
     mt->next = mt->state + numberof(mt->state) - mt->left + 1;
     return obj;

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

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