зеркало из https://github.com/github/ruby.git
* 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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32569 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
18f0a65018
Коммит
e2fd80b3d3
|
@ -1,3 +1,11 @@
|
|||
Sun Jul 17 16:26:40 2011 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* 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@ruby-lang.org>
|
||||
|
||||
* error.c (rb_warn_m): accept multiple args in like puts. rdoc
|
||||
|
|
16
error.c
16
error.c
|
@ -1714,6 +1714,22 @@ rb_check_frozen(VALUE obj)
|
|||
rb_check_frozen_internal(obj);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -215,15 +215,24 @@ PRINTF_ARGS(void rb_compile_error_with_enc(const char*, int, void *, const char*
|
|||
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_inline(VALUE obj)
|
|||
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 */
|
||||
|
|
3
struct.c
3
struct.c
|
@ -153,8 +153,7 @@ static void
|
|||
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
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#! /usr/bin/ruby
|
||||
tc = Class.new(Time)
|
||||
tc.inspect
|
||||
t = tc.now
|
||||
proc do
|
||||
$SAFE=4
|
||||
t.gmtime
|
||||
end.call
|
|
@ -1,5 +1,6 @@
|
|||
require 'test/unit'
|
||||
require 'timeout'
|
||||
require_relative 'envutil'
|
||||
|
||||
class TestStruct < Test::Unit::TestCase
|
||||
def test_struct
|
||||
|
@ -249,4 +250,17 @@ class TestStruct < Test::Unit::TestCase
|
|||
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
|
||||
|
|
|
@ -3,6 +3,7 @@ require 'rational'
|
|||
require 'delegate'
|
||||
require 'timeout'
|
||||
require 'delegate'
|
||||
require_relative 'envutil'
|
||||
|
||||
class TestTime < Test::Unit::TestCase
|
||||
def setup
|
||||
|
@ -702,7 +703,7 @@ class TestTime < Test::Unit::TestCase
|
|||
bug5012 = "[ruby-dev:44071]"
|
||||
|
||||
t0 = Time.now
|
||||
class <<t0; end
|
||||
class << t0; end
|
||||
t1 = t0.getlocal
|
||||
|
||||
def t0.m
|
||||
|
@ -711,4 +712,18 @@ class TestTime < Test::Unit::TestCase
|
|||
|
||||
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
|
||||
|
|
3
time.c
3
time.c
|
@ -1876,8 +1876,7 @@ static void
|
|||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче