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

ruby-changes:20521

From: nobu <ko1@a...>
Date: Sun, 17 Jul 2011 16:26:56 +0900 (JST)
Subject: [ruby-changes:20521] nobu:r32569 (trunk): * error.c (rb_check_trusted): new function to check an object is

nobu	2011-07-17 16:26:45 +0900 (Sun, 17 Jul 2011)

  New Revision: 32569

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

  Log:
    * error.c (rb_check_trusted): new function to check an object is
      trusted.
    * struct.c (rb_struct_modify), time.c (time_modify): check by the
      above function to show proper class names.  [Bug #5036]

  Added files:
    trunk/t.rb
  Modified files:
    trunk/ChangeLog
    trunk/error.c
    trunk/include/ruby/intern.h
    trunk/struct.c
    trunk/test/ruby/test_struct.rb
    trunk/test/ruby/test_time.rb
    trunk/time.c

Index: time.c
===================================================================
--- time.c	(revision 32568)
+++ time.c	(revision 32569)
@@ -1876,8 +1876,7 @@
 time_modify(VALUE time)
 {
     rb_check_frozen(time);
-    if (!OBJ_UNTRUSTED(time) && rb_safe_level() >= 4)
-	rb_raise(rb_eSecurityError, "Insecure: can't modify Time");
+    rb_check_trusted(time);
 }
 
 static wideval_t
Index: include/ruby/intern.h
===================================================================
--- include/ruby/intern.h	(revision 32568)
+++ include/ruby/intern.h	(revision 32569)
@@ -215,15 +215,24 @@
 PRINTF_ARGS(void rb_compile_error_append(const char*, ...), 1, 2);
 NORETURN(void rb_load_fail(const char*));
 NORETURN(void rb_error_frozen(const char*));
+void rb_error_untrusted(VALUE);
 void rb_check_frozen(VALUE);
+void rb_check_trusted(VALUE);
 #define rb_check_frozen_internal(obj) do { \
 	VALUE frozen_obj = (obj); \
 	if (OBJ_FROZEN(frozen_obj)) { \
 	    rb_error_frozen(rb_obj_classname(frozen_obj)); \
 	} \
     } while (0)
+#define rb_check_trusted_internal(obj) do { \
+	VALUE untrusted_obj = (obj); \
+	if (!OBJ_UNTRUSTED(untrusted_obj)) { \
+	    rb_error_untrusted(untrusted_obj); \
+	} \
+    } while (0)
 #ifdef __GNUC__
 #define rb_check_frozen(obj) __extension__({rb_check_frozen_internal(obj);})
+#define rb_check_trusted(obj) __extension__({rb_check_trusted_internal(obj);})
 #else
 static inline void
 rb_check_frozen_inline(VALUE obj)
@@ -231,6 +240,12 @@
     rb_check_frozen_internal(obj);
 }
 #define rb_check_frozen(obj) rb_check_frozen_inline(obj)
+static inline void
+rb_check_trusted_inline(VALUE obj)
+{
+    rb_check_trusted_internal(obj);
+}
+#define rb_check_trusted(obj) rb_check_trusted_inline(obj)
 #endif
 
 /* eval.c */
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 32568)
+++ ChangeLog	(revision 32569)
@@ -1,3 +1,11 @@
+Sun Jul 17 16:26:40 2011  Nobuyoshi Nakada  <nobu@r...>
+
+	* error.c (rb_check_trusted): new function to check an object is
+	  trusted.
+
+	* struct.c (rb_struct_modify), time.c (time_modify): check by the
+	  above function to show proper class names.  [Bug #5036]
+
 Sun Jul 17 15:30:04 2011  Nobuyoshi Nakada  <nobu@r...>
 
 	* error.c (rb_warn_m): accept multiple args in like puts.  rdoc
Index: struct.c
===================================================================
--- struct.c	(revision 32568)
+++ struct.c	(revision 32569)
@@ -153,8 +153,7 @@
 rb_struct_modify(VALUE s)
 {
     rb_check_frozen(s);
-    if (!OBJ_UNTRUSTED(s) && rb_safe_level() >= 4)
-       rb_raise(rb_eSecurityError, "Insecure: can't modify Struct");
+    rb_check_trusted(s);
 }
 
 static VALUE
Index: error.c
===================================================================
--- error.c	(revision 32568)
+++ error.c	(revision 32569)
@@ -1715,6 +1715,22 @@
 }
 
 void
+rb_error_untrusted(VALUE obj)
+{
+    if (rb_safe_level() >= 4) {
+	rb_raise(rb_eSecurityError, "Insecure: can't modify %s",
+		 rb_obj_classname(obj));
+    }
+}
+
+#undef rb_check_trusted
+void
+rb_check_trusted(VALUE obj)
+{
+    rb_check_trusted_internal(obj);
+}
+
+void
 Init_syserr(void)
 {
     rb_eNOERROR = set_syserr(0, "NOERROR");
Index: t.rb
===================================================================
--- t.rb	(revision 0)
+++ t.rb	(revision 32569)
@@ -0,0 +1,8 @@
+#! /usr/bin/ruby
+tc = Class.new(Time)
+tc.inspect
+t = tc.now
+proc do
+  $SAFE=4
+  t.gmtime
+end.call

Property changes on: t.rb
___________________________________________________________________
Added: svn:eol-style
   + LF
Added: svn:executable
   + *

Index: test/ruby/test_struct.rb
===================================================================
--- test/ruby/test_struct.rb	(revision 32568)
+++ test/ruby/test_struct.rb	(revision 32569)
@@ -1,5 +1,6 @@
 require 'test/unit'
 require 'timeout'
+require_relative 'envutil'
 
 class TestStruct < Test::Unit::TestCase
   def test_struct
@@ -249,4 +250,17 @@
       assert !x.eql?(z)
     }
   end
+
+  def test_struct_subclass
+    bug5036 = '[ruby-dev:44122]'
+    st = Class.new(Struct)
+    s = st.new("S", :m).new
+    error = assert_raise(SecurityError) do
+      proc do
+        $SAFE = 4
+        s.m = 1
+      end.call
+    end
+    assert_equal("Insecure: can't modify #{st}::S", error.message, bug5036)
+  end
 end
Index: test/ruby/test_time.rb
===================================================================
--- test/ruby/test_time.rb	(revision 32568)
+++ test/ruby/test_time.rb	(revision 32569)
@@ -3,6 +3,7 @@
 require 'delegate'
 require 'timeout'
 require 'delegate'
+require_relative 'envutil'
 
 class TestTime < Test::Unit::TestCase
   def setup
@@ -702,7 +703,7 @@
     bug5012 = "[ruby-dev:44071]"
 
     t0 = Time.now
-    class <<t0; end
+    class << t0; end
     t1 = t0.getlocal
 
     def t0.m
@@ -711,4 +712,18 @@
 
     assert_raise(NoMethodError, bug5012) { t1.m }
   end
+
+  def test_time_subclass
+    bug5036 = '[ruby-dev:44122]'
+    tc = Class.new(Time)
+    tc.inspect
+    t = tc.now
+    error = assert_raise(SecurityError) do
+      proc do
+        $SAFE = 4
+        t.gmtime
+      end.call
+    end
+    assert_equal("Insecure: can't modify #{tc}", error.message, bug5036)
+  end
 end

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

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