mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* object.c (rb_obj_untrusted): new method Object#untrusted?.
(rb_obj_untrust): new method Object#untrust. (rb_obj_trust): new method Object#trust. * array.c, debug.c, time.c, include/ruby/ruby.h, re.c, variable.c, string.c, io.c, dir.c, vm_method.c, struct.c, class.c, hash.c, ruby.c, marshal.c: fixes for Object#untrusted?. * test/ruby/test_module.rb, test/ruby/test_array.rb, test/ruby/test_object.rb, test/ruby/test_string.rb, test/ruby/test_marshal.rb, test/ruby/test_hash.rb: added tests for Object#untrusted?. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18568 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
55c141c624
commit
f433d710d0
23 changed files with 364 additions and 88 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
Wed Aug 13 16:02:14 2008 Shugo Maeda <shugo@ruby-lang.org>
|
||||
|
||||
* object.c (rb_obj_untrusted): new method Object#untrusted?.
|
||||
(rb_obj_untrust): new method Object#untrust.
|
||||
(rb_obj_trust): new method Object#trust.
|
||||
|
||||
* array.c, debug.c, time.c, include/ruby/ruby.h, re.c, variable.c,
|
||||
string.c, io.c, dir.c, vm_method.c, struct.c, class.c, hash.c,
|
||||
ruby.c, marshal.c: fixes for Object#untrusted?.
|
||||
|
||||
* test/ruby/test_module.rb, test/ruby/test_array.rb,
|
||||
test/ruby/test_object.rb, test/ruby/test_string.rb,
|
||||
test/ruby/test_marshal.rb, test/ruby/test_hash.rb: added tests for
|
||||
Object#untrusted?.
|
||||
|
||||
Wed Aug 13 16:13:58 2008 NARUSE, Yui <naruse@ruby-lang.org>
|
||||
|
||||
* test/ruby/test_m17n.rb: follow EncodingCompatibilityError.
|
||||
|
|
11
array.c
11
array.c
|
@ -54,7 +54,7 @@ static inline void
|
|||
rb_ary_modify_check(VALUE ary)
|
||||
{
|
||||
if (OBJ_FROZEN(ary)) rb_error_frozen("array");
|
||||
if (!OBJ_TAINTED(ary) && rb_safe_level() >= 4)
|
||||
if (!OBJ_UNTRUSTED(ary) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify array");
|
||||
}
|
||||
|
||||
|
@ -1263,10 +1263,12 @@ rb_ary_join(VALUE ary, VALUE sep)
|
|||
{
|
||||
long len = 1, i;
|
||||
int taint = Qfalse;
|
||||
int untrust = Qfalse;
|
||||
VALUE result, tmp;
|
||||
|
||||
if (RARRAY_LEN(ary) == 0) return rb_str_new(0, 0);
|
||||
if (OBJ_TAINTED(ary) || OBJ_TAINTED(sep)) taint = Qtrue;
|
||||
if (OBJ_UNTRUSTED(ary) || OBJ_UNTRUSTED(sep)) untrust = Qtrue;
|
||||
|
||||
for (i=0; i<RARRAY_LEN(ary); i++) {
|
||||
tmp = rb_check_string_type(RARRAY_PTR(ary)[i]);
|
||||
|
@ -1298,9 +1300,11 @@ rb_ary_join(VALUE ary, VALUE sep)
|
|||
rb_str_buf_append(result, sep);
|
||||
rb_str_buf_append(result, tmp);
|
||||
if (OBJ_TAINTED(tmp)) taint = Qtrue;
|
||||
if (OBJ_UNTRUSTED(tmp)) untrust = Qtrue;
|
||||
}
|
||||
|
||||
if (taint) OBJ_TAINT(result);
|
||||
if (untrust) OBJ_UNTRUST(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1330,6 +1334,7 @@ static VALUE
|
|||
inspect_ary(VALUE ary, VALUE dummy, int recur)
|
||||
{
|
||||
int tainted = OBJ_TAINTED(ary);
|
||||
int untrust = OBJ_UNTRUSTED(ary);
|
||||
long i;
|
||||
VALUE s, str;
|
||||
|
||||
|
@ -1338,11 +1343,13 @@ inspect_ary(VALUE ary, VALUE dummy, int recur)
|
|||
for (i=0; i<RARRAY_LEN(ary); i++) {
|
||||
s = rb_inspect(RARRAY_PTR(ary)[i]);
|
||||
if (OBJ_TAINTED(s)) tainted = Qtrue;
|
||||
if (OBJ_UNTRUSTED(s)) untrust = Qtrue;
|
||||
if (i > 0) rb_str_buf_cat2(str, ", ");
|
||||
rb_str_buf_append(str, s);
|
||||
}
|
||||
rb_str_buf_cat2(str, "]");
|
||||
if (tainted) OBJ_TAINT(str);
|
||||
if (untrust) OBJ_UNTRUST(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -2952,7 +2959,7 @@ rb_ary_flatten(int argc, VALUE *argv, VALUE ary)
|
|||
if (level == 0) return ary;
|
||||
|
||||
result = flatten(ary, level, &mod);
|
||||
if (OBJ_TAINTED(ary)) OBJ_TAINT(result);
|
||||
OBJ_INFECT(result, ary);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
8
class.c
8
class.c
|
@ -383,7 +383,7 @@ rb_include_module(VALUE klass, VALUE module)
|
|||
int changed = 0;
|
||||
|
||||
rb_frozen_class_p(klass);
|
||||
if (!OBJ_TAINTED(klass)) {
|
||||
if (!OBJ_UNTRUSTED(klass)) {
|
||||
rb_secure(4);
|
||||
}
|
||||
|
||||
|
@ -833,6 +833,12 @@ rb_singleton_class(VALUE obj)
|
|||
else {
|
||||
FL_UNSET(klass, FL_TAINT);
|
||||
}
|
||||
if (OBJ_UNTRUSTED(obj)) {
|
||||
OBJ_UNTRUST(klass);
|
||||
}
|
||||
else {
|
||||
FL_UNSET(klass, FL_UNTRUSTED);
|
||||
}
|
||||
if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);
|
||||
ALLOW_INTS;
|
||||
|
||||
|
|
4
debug.c
4
debug.c
|
@ -35,6 +35,7 @@ static const union {
|
|||
RUBY_FL_RESERVED = FL_RESERVED,
|
||||
RUBY_FL_FINALIZE = FL_FINALIZE,
|
||||
RUBY_FL_TAINT = FL_TAINT,
|
||||
RUBY_FL_UNTRUSTED = FL_UNTRUSTED,
|
||||
RUBY_FL_EXIVAR = FL_EXIVAR,
|
||||
RUBY_FL_FREEZE = FL_FREEZE,
|
||||
RUBY_FL_SINGLETON = FL_SINGLETON,
|
||||
|
@ -57,7 +58,6 @@ static const union {
|
|||
RUBY_FL_USER16 = FL_USER16,
|
||||
RUBY_FL_USER17 = FL_USER17,
|
||||
RUBY_FL_USER18 = FL_USER18,
|
||||
RUBY_FL_USER19 = FL_USER19,
|
||||
RUBY_FL_USHIFT = FL_USHIFT,
|
||||
RUBY_NODE_TYPESHIFT = NODE_TYPESHIFT,
|
||||
RUBY_NODE_TYPEMASK = NODE_TYPEMASK,
|
||||
|
@ -67,7 +67,7 @@ static const union {
|
|||
} various;
|
||||
} dummy_gdb_enums;
|
||||
|
||||
const VALUE RUBY_FL_USER20 = FL_USER20;
|
||||
const VALUE RUBY_FL_USER19 = FL_USER19;
|
||||
|
||||
int
|
||||
ruby_debug_print_indent(int level, int debug_level, int indent_level)
|
||||
|
|
6
dir.c
6
dir.c
|
@ -414,8 +414,8 @@ dir_closed(void)
|
|||
static void
|
||||
dir_check(VALUE dir)
|
||||
{
|
||||
if (!OBJ_TAINTED(dir) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: operation on untainted Dir");
|
||||
if (!OBJ_UNTRUSTED(dir) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: operation on trusted Dir");
|
||||
rb_check_frozen(dir);
|
||||
}
|
||||
|
||||
|
@ -630,7 +630,7 @@ dir_rewind(VALUE dir)
|
|||
{
|
||||
struct dir_data *dirp;
|
||||
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(dir)) {
|
||||
if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(dir)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't close");
|
||||
}
|
||||
GetDIR(dir, dirp);
|
||||
|
|
4
hash.c
4
hash.c
|
@ -247,7 +247,7 @@ static void
|
|||
rb_hash_modify_check(VALUE hash)
|
||||
{
|
||||
if (OBJ_FROZEN(hash)) rb_error_frozen("hash");
|
||||
if (!OBJ_TAINTED(hash) && rb_safe_level() >= 4)
|
||||
if (!OBJ_UNTRUSTED(hash) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify hash");
|
||||
}
|
||||
|
||||
|
@ -1166,7 +1166,7 @@ rb_hash_to_a(VALUE hash)
|
|||
|
||||
ary = rb_ary_new();
|
||||
rb_hash_foreach(hash, to_a_i, ary);
|
||||
if (OBJ_TAINTED(hash)) OBJ_TAINT(ary);
|
||||
OBJ_INFECT(ary, hash);
|
||||
|
||||
return ary;
|
||||
}
|
||||
|
|
|
@ -432,7 +432,7 @@ VALUE rb_newobj(void);
|
|||
#define OBJSETUP(obj,c,t) do {\
|
||||
RBASIC(obj)->flags = (t);\
|
||||
RBASIC(obj)->klass = (c);\
|
||||
if (rb_safe_level() >= 3) FL_SET(obj, FL_TAINT);\
|
||||
if (rb_safe_level() >= 3) FL_SET(obj, FL_TAINT | FL_UNTRUSTED);\
|
||||
} while (0)
|
||||
#define CLONESETUP(clone,obj) do {\
|
||||
OBJSETUP(clone,rb_singleton_class_clone((VALUE)obj),RBASIC(obj)->flags);\
|
||||
|
@ -440,7 +440,7 @@ VALUE rb_newobj(void);
|
|||
if (FL_TEST(obj, FL_EXIVAR)) rb_copy_generic_ivar((VALUE)clone,(VALUE)obj);\
|
||||
} while (0)
|
||||
#define DUPSETUP(dup,obj) do {\
|
||||
OBJSETUP(dup,rb_obj_class(obj),(RBASIC(obj)->flags)&(T_MASK|FL_EXIVAR|FL_TAINT));\
|
||||
OBJSETUP(dup,rb_obj_class(obj),(RBASIC(obj)->flags)&(T_MASK|FL_EXIVAR|FL_TAINT|FL_UNTRUSTED));\
|
||||
if (FL_TEST(obj, FL_EXIVAR)) rb_copy_generic_ivar((VALUE)dup,(VALUE)obj);\
|
||||
} while (0)
|
||||
|
||||
|
@ -693,10 +693,11 @@ struct RBignum {
|
|||
#define FL_RESERVED (((VALUE)1)<<6) /* will be used in the future GC */
|
||||
#define FL_FINALIZE (((VALUE)1)<<7)
|
||||
#define FL_TAINT (((VALUE)1)<<8)
|
||||
#define FL_EXIVAR (((VALUE)1)<<9)
|
||||
#define FL_FREEZE (((VALUE)1)<<10)
|
||||
#define FL_UNTRUSTED (((VALUE)1)<<9)
|
||||
#define FL_EXIVAR (((VALUE)1)<<10)
|
||||
#define FL_FREEZE (((VALUE)1)<<11)
|
||||
|
||||
#define FL_USHIFT 11
|
||||
#define FL_USHIFT 12
|
||||
|
||||
#define FL_USER0 (((VALUE)1)<<(FL_USHIFT+0))
|
||||
#define FL_USER1 (((VALUE)1)<<(FL_USHIFT+1))
|
||||
|
@ -718,7 +719,6 @@ struct RBignum {
|
|||
#define FL_USER17 (((VALUE)1)<<(FL_USHIFT+17))
|
||||
#define FL_USER18 (((VALUE)1)<<(FL_USHIFT+18))
|
||||
#define FL_USER19 (((VALUE)1)<<(FL_USHIFT+19))
|
||||
#define FL_USER20 (((VALUE)1)<<(FL_USHIFT+20))
|
||||
|
||||
#define SPECIAL_CONST_P(x) (IMMEDIATE_P(x) || !RTEST(x))
|
||||
|
||||
|
@ -732,7 +732,9 @@ struct RBignum {
|
|||
|
||||
#define OBJ_TAINTED(x) FL_TEST((x), FL_TAINT)
|
||||
#define OBJ_TAINT(x) FL_SET((x), FL_TAINT)
|
||||
#define OBJ_INFECT(x,s) do {if (FL_ABLE(x) && FL_ABLE(s)) RBASIC(x)->flags |= RBASIC(s)->flags & FL_TAINT;} while (0)
|
||||
#define OBJ_UNTRUSTED(x) FL_TEST((x), FL_UNTRUSTED)
|
||||
#define OBJ_UNTRUST(x) FL_SET((x), FL_UNTRUSTED)
|
||||
#define OBJ_INFECT(x,s) do {if (FL_ABLE(x) && FL_ABLE(s)) RBASIC(x)->flags |= RBASIC(s)->flags & (FL_TAINT | FL_UNTRUSTED);} while (0)
|
||||
|
||||
#define OBJ_FROZEN(x) FL_TEST((x), FL_FREEZE)
|
||||
#define OBJ_FREEZE(x) FL_SET((x), FL_FREEZE)
|
||||
|
|
13
io.c
13
io.c
|
@ -227,8 +227,8 @@ rb_eof_error(void)
|
|||
VALUE
|
||||
rb_io_taint_check(VALUE io)
|
||||
{
|
||||
if (!OBJ_TAINTED(io) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: operation on untainted IO");
|
||||
if (!OBJ_UNTRUSTED(io) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: operation on trusted IO");
|
||||
rb_check_frozen(io);
|
||||
return io;
|
||||
}
|
||||
|
@ -2819,7 +2819,7 @@ rb_io_close(VALUE io)
|
|||
static VALUE
|
||||
rb_io_close_m(VALUE io)
|
||||
{
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) {
|
||||
if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(io)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't close");
|
||||
}
|
||||
rb_io_check_closed(RFILE(io)->fptr);
|
||||
|
@ -2902,7 +2902,7 @@ rb_io_close_read(VALUE io)
|
|||
rb_io_t *fptr;
|
||||
VALUE write_io;
|
||||
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) {
|
||||
if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(io)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't close");
|
||||
}
|
||||
GetOpenFile(io, fptr);
|
||||
|
@ -2962,7 +2962,7 @@ rb_io_close_write(VALUE io)
|
|||
rb_io_t *fptr;
|
||||
VALUE write_io;
|
||||
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) {
|
||||
if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(io)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't close");
|
||||
}
|
||||
write_io = GetWriteIO(io);
|
||||
|
@ -4430,7 +4430,8 @@ io_reopen(VALUE io, VALUE nfile)
|
|||
off_t pos = 0;
|
||||
|
||||
nfile = rb_io_get_io(nfile);
|
||||
if (rb_safe_level() >= 4 && (!OBJ_TAINTED(io) || !OBJ_TAINTED(nfile))) {
|
||||
if (rb_safe_level() >= 4 &&
|
||||
(!OBJ_UNTRUSTED(io) || !OBJ_UNTRUSTED(nfile))) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't reopen");
|
||||
}
|
||||
GetOpenFile(io, fptr);
|
||||
|
|
14
marshal.c
14
marshal.c
|
@ -137,6 +137,7 @@ struct dump_arg {
|
|||
st_table *symbols;
|
||||
st_table *data;
|
||||
int taint;
|
||||
int untrust;
|
||||
st_table *compat_tbl;
|
||||
VALUE wrapper;
|
||||
st_table *encodings;
|
||||
|
@ -192,6 +193,7 @@ w_nbyte(const char *s, int n, struct dump_arg *arg)
|
|||
rb_str_buf_cat(buf, s, n);
|
||||
if (arg->dest && RSTRING_LEN(buf) >= BUFSIZ) {
|
||||
if (arg->taint) OBJ_TAINT(buf);
|
||||
if (arg->untrust) OBJ_UNTRUST(buf);
|
||||
rb_io_write(arg->dest, buf);
|
||||
rb_str_resize(buf, 0);
|
||||
}
|
||||
|
@ -581,6 +583,7 @@ w_object(VALUE obj, struct dump_arg *arg, int limit)
|
|||
}
|
||||
else {
|
||||
if (OBJ_TAINTED(obj)) arg->taint = Qtrue;
|
||||
if (OBJ_UNTRUSTED(obj)) arg->untrust = Qtrue;
|
||||
|
||||
if (rb_respond_to(obj, s_mdump)) {
|
||||
volatile VALUE v;
|
||||
|
@ -809,6 +812,9 @@ dump_ensure(struct dump_arg *arg)
|
|||
if (arg->taint) {
|
||||
OBJ_TAINT(arg->str);
|
||||
}
|
||||
if (arg->untrust) {
|
||||
OBJ_UNTRUST(arg->str);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -878,6 +884,7 @@ marshal_dump(int argc, VALUE *argv)
|
|||
arg.symbols = st_init_numtable();
|
||||
arg.data = st_init_numtable();
|
||||
arg.taint = Qfalse;
|
||||
arg.untrust = Qfalse;
|
||||
arg.compat_tbl = st_init_numtable();
|
||||
arg.wrapper = Data_Wrap_Struct(rb_cData, mark_dump_arg, 0, &arg);
|
||||
arg.encodings = 0;
|
||||
|
@ -900,6 +907,7 @@ struct load_arg {
|
|||
VALUE data;
|
||||
VALUE proc;
|
||||
int taint;
|
||||
int untrust;
|
||||
st_table *compat_tbl;
|
||||
VALUE compat_tbl_wrapper;
|
||||
};
|
||||
|
@ -1014,6 +1022,7 @@ r_bytes0(long len, struct load_arg *arg)
|
|||
StringValue(str);
|
||||
if (RSTRING_LEN(str) != len) goto too_short;
|
||||
if (OBJ_TAINTED(str)) arg->taint = Qtrue;
|
||||
if (OBJ_UNTRUSTED(str)) arg->untrust = Qtrue;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
@ -1084,6 +1093,11 @@ r_entry(VALUE v, struct load_arg *arg)
|
|||
if ((VALUE)real_obj != Qundef)
|
||||
OBJ_TAINT((VALUE)real_obj);
|
||||
}
|
||||
if (arg->untrust) {
|
||||
OBJ_UNTRUST(v);
|
||||
if ((VALUE)real_obj != Qundef)
|
||||
OBJ_UNTRUST((VALUE)real_obj);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
|
67
object.c
67
object.c
|
@ -161,7 +161,7 @@ init_copy(VALUE dest, VALUE obj)
|
|||
rb_raise(rb_eTypeError, "[bug] frozen object (%s) allocated", rb_obj_classname(dest));
|
||||
}
|
||||
RBASIC(dest)->flags &= ~(T_MASK|FL_EXIVAR);
|
||||
RBASIC(dest)->flags |= RBASIC(obj)->flags & (T_MASK|FL_EXIVAR|FL_TAINT);
|
||||
RBASIC(dest)->flags |= RBASIC(obj)->flags & (T_MASK|FL_EXIVAR|FL_TAINT|FL_UNTRUSTED);
|
||||
rb_copy_generic_ivar(dest, obj);
|
||||
rb_gc_copy_finalizer(dest, obj);
|
||||
switch (TYPE(obj)) {
|
||||
|
@ -234,7 +234,7 @@ rb_obj_clone(VALUE obj)
|
|||
}
|
||||
clone = rb_obj_alloc(rb_obj_class(obj));
|
||||
RBASIC(clone)->klass = rb_singleton_class_clone(obj);
|
||||
RBASIC(clone)->flags = (RBASIC(obj)->flags | FL_TEST(clone, FL_TAINT)) & ~(FL_FREEZE|FL_FINALIZE);
|
||||
RBASIC(clone)->flags = (RBASIC(obj)->flags | FL_TEST(clone, FL_TAINT) | FL_TEST(clone, FL_UNTRUSTED)) & ~(FL_FREEZE|FL_FINALIZE);
|
||||
init_copy(clone, obj);
|
||||
RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE;
|
||||
|
||||
|
@ -302,7 +302,7 @@ rb_any_to_s(VALUE obj)
|
|||
VALUE str;
|
||||
|
||||
str = rb_sprintf("#<%s:%p>", cname, (void*)obj);
|
||||
if (OBJ_TAINTED(obj)) OBJ_TAINT(str);
|
||||
OBJ_INFECT(str, obj);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
@ -692,6 +692,62 @@ rb_obj_untaint(VALUE obj)
|
|||
return obj;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* obj.untrusted? => true or false
|
||||
*
|
||||
* Returns <code>true</code> if the object is untrusted.
|
||||
*/
|
||||
|
||||
VALUE
|
||||
rb_obj_untrusted(VALUE obj)
|
||||
{
|
||||
if (OBJ_UNTRUSTED(obj))
|
||||
return Qtrue;
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* obj.untrust -> obj
|
||||
*
|
||||
* Marks <i>obj</i> as untrusted.
|
||||
*/
|
||||
|
||||
VALUE
|
||||
rb_obj_untrust(VALUE obj)
|
||||
{
|
||||
rb_secure(4);
|
||||
if (!OBJ_UNTRUSTED(obj)) {
|
||||
if (OBJ_FROZEN(obj)) {
|
||||
rb_error_frozen("object");
|
||||
}
|
||||
OBJ_UNTRUST(obj);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* obj.trust => obj
|
||||
*
|
||||
* Removes the untrusted mark from <i>obj</i>.
|
||||
*/
|
||||
|
||||
VALUE
|
||||
rb_obj_trust(VALUE obj)
|
||||
{
|
||||
rb_secure(3);
|
||||
if (OBJ_UNTRUSTED(obj)) {
|
||||
if (OBJ_FROZEN(obj)) {
|
||||
rb_error_frozen("object");
|
||||
}
|
||||
FL_UNSET(obj, FL_UNTRUSTED);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
void
|
||||
rb_obj_infect(VALUE obj1, VALUE obj2)
|
||||
{
|
||||
|
@ -723,7 +779,7 @@ VALUE
|
|||
rb_obj_freeze(VALUE obj)
|
||||
{
|
||||
if (!OBJ_FROZEN(obj)) {
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(obj)) {
|
||||
if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(obj)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't freeze object");
|
||||
}
|
||||
OBJ_FREEZE(obj);
|
||||
|
@ -2419,6 +2475,9 @@ Init_Object(void)
|
|||
rb_define_method(rb_mKernel, "taint", rb_obj_taint, 0);
|
||||
rb_define_method(rb_mKernel, "tainted?", rb_obj_tainted, 0);
|
||||
rb_define_method(rb_mKernel, "untaint", rb_obj_untaint, 0);
|
||||
rb_define_method(rb_mKernel, "untrust", rb_obj_untrust, 0);
|
||||
rb_define_method(rb_mKernel, "untrusted?", rb_obj_untrusted, 0);
|
||||
rb_define_method(rb_mKernel, "trust", rb_obj_trust, 0);
|
||||
rb_define_method(rb_mKernel, "freeze", rb_obj_freeze, 0);
|
||||
rb_define_method(rb_mKernel, "frozen?", rb_obj_frozen_p, 0);
|
||||
|
||||
|
|
2
re.c
2
re.c
|
@ -2299,7 +2299,7 @@ rb_reg_initialize(VALUE obj, const char *s, int len, rb_encoding *enc,
|
|||
rb_encoding *fixed_enc = 0;
|
||||
rb_encoding *a_enc = rb_ascii8bit_encoding();
|
||||
|
||||
if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
|
||||
if (!OBJ_UNTRUSTED(obj) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify regexp");
|
||||
rb_check_frozen(obj);
|
||||
if (FL_TEST(obj, REG_LITERAL))
|
||||
|
|
4
ruby.c
4
ruby.c
|
@ -1069,12 +1069,12 @@ process_options(VALUE arg)
|
|||
#endif
|
||||
opt->script_name = rb_str_new4(rb_progname);
|
||||
opt->script = RSTRING_PTR(opt->script_name);
|
||||
safe = rb_safe_level();
|
||||
rb_set_safe_level_force(0);
|
||||
ruby_set_argv(argc, argv);
|
||||
process_sflag(opt);
|
||||
|
||||
ruby_init_loadpath();
|
||||
safe = rb_safe_level();
|
||||
rb_set_safe_level_force(0);
|
||||
ruby_init_gems(!(opt->disable & DISABLE_BIT(gems)));
|
||||
lenc = rb_locale_encoding();
|
||||
for (i = 0; i < RARRAY_LEN(rb_argv); i++) {
|
||||
|
|
6
string.c
6
string.c
|
@ -1027,7 +1027,7 @@ str_modifiable(VALUE str)
|
|||
rb_raise(rb_eRuntimeError, "can't modify string; temporarily locked");
|
||||
}
|
||||
if (OBJ_FROZEN(str)) rb_error_frozen("string");
|
||||
if (!OBJ_TAINTED(str) && rb_safe_level() >= 4)
|
||||
if (!OBJ_UNTRUSTED(str) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify string");
|
||||
}
|
||||
|
||||
|
@ -3170,6 +3170,7 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
|
|||
VALUE pat, repl, hash = Qnil;
|
||||
int iter = 0;
|
||||
int tainted = 0;
|
||||
int untrusted = 0;
|
||||
long plen;
|
||||
|
||||
if (argc == 1 && rb_block_given_p()) {
|
||||
|
@ -3182,6 +3183,7 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
|
|||
StringValue(repl);
|
||||
}
|
||||
if (OBJ_TAINTED(repl)) tainted = 1;
|
||||
if (OBJ_UNTRUSTED(repl)) untrusted = 1;
|
||||
}
|
||||
else {
|
||||
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc);
|
||||
|
@ -3227,6 +3229,7 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
|
|||
rb_str_modify(str);
|
||||
rb_enc_associate(str, enc);
|
||||
if (OBJ_TAINTED(repl)) tainted = 1;
|
||||
if (OBJ_UNTRUSTED(repl)) untrusted = 1;
|
||||
if (ENC_CODERANGE_UNKNOWN < cr && cr < ENC_CODERANGE_BROKEN) {
|
||||
int cr2 = ENC_CODERANGE(repl);
|
||||
if (cr2 == ENC_CODERANGE_UNKNOWN || cr2 > cr) cr = cr2;
|
||||
|
@ -3246,6 +3249,7 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
|
|||
RSTRING_PTR(str)[RSTRING_LEN(str)] = '\0';
|
||||
ENC_CODERANGE_SET(str, cr);
|
||||
if (tainted) OBJ_TAINT(str);
|
||||
if (untrusted) OBJ_UNTRUST(str);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
|
2
struct.c
2
struct.c
|
@ -144,7 +144,7 @@ static void
|
|||
rb_struct_modify(VALUE s)
|
||||
{
|
||||
if (OBJ_FROZEN(s)) rb_error_frozen("Struct");
|
||||
if (!OBJ_TAINTED(s) && rb_safe_level() >= 4)
|
||||
if (!OBJ_UNTRUSTED(s) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify Struct");
|
||||
}
|
||||
|
||||
|
|
|
@ -451,16 +451,20 @@ class TestArray < Test::Unit::TestCase
|
|||
|
||||
def test_clone
|
||||
for taint in [ false, true ]
|
||||
for frozen in [ false, true ]
|
||||
a = @cls[*(0..99).to_a]
|
||||
a.taint if taint
|
||||
a.freeze if frozen
|
||||
b = a.clone
|
||||
for untrust in [ false, true ]
|
||||
for frozen in [ false, true ]
|
||||
a = @cls[*(0..99).to_a]
|
||||
a.taint if taint
|
||||
a.untrust if untrust
|
||||
a.freeze if frozen
|
||||
b = a.clone
|
||||
|
||||
assert_equal(a, b)
|
||||
assert(a.__id__ != b.__id__)
|
||||
assert_equal(a.frozen?, b.frozen?)
|
||||
assert_equal(a.tainted?, b.tainted?)
|
||||
assert_equal(a, b)
|
||||
assert(a.__id__ != b.__id__)
|
||||
assert_equal(a.frozen?, b.frozen?)
|
||||
assert_equal(a.untrusted?, b.untrusted?)
|
||||
assert_equal(a.tainted?, b.tainted?)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -708,6 +712,13 @@ class TestArray < Test::Unit::TestCase
|
|||
@cls[@cls[@cls[@cls[],@cls[]],@cls[@cls[]],@cls[]],@cls[@cls[@cls[]]]].flatten)
|
||||
|
||||
assert_raise(TypeError, "[ruby-dev:31197]") { [[]].flatten("") }
|
||||
|
||||
a6 = @cls[[1, 2], 3]
|
||||
a6.taint
|
||||
a6.untrust
|
||||
a7 = a6.flatten
|
||||
assert_equal(true, a7.tainted?)
|
||||
assert_equal(true, a7.untrusted?)
|
||||
end
|
||||
|
||||
def test_flatten!
|
||||
|
@ -797,6 +808,12 @@ class TestArray < Test::Unit::TestCase
|
|||
assert_equal("1,2,3", a.join(','))
|
||||
|
||||
$, = ""
|
||||
a = @cls[1, 2, 3]
|
||||
a.taint
|
||||
a.untrust
|
||||
s = a.join
|
||||
assert_equal(true, s.tainted?)
|
||||
assert_equal(true, s.untrusted?)
|
||||
end
|
||||
|
||||
def test_last
|
||||
|
@ -1574,4 +1591,13 @@ class TestArray < Test::Unit::TestCase
|
|||
def test_array_subclass
|
||||
assert_equal(Array2, Array2[1,2,3].uniq.class, "[ruby-dev:34581]")
|
||||
end
|
||||
|
||||
def test_inspect
|
||||
a = @cls[1, 2, 3]
|
||||
a.taint
|
||||
a.untrust
|
||||
s = a.inspect
|
||||
assert_equal(true, s.tainted?)
|
||||
assert_equal(true, s.untrusted?)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -206,16 +206,20 @@ class TestHash < Test::Unit::TestCase
|
|||
|
||||
def test_clone
|
||||
for taint in [ false, true ]
|
||||
for frozen in [ false, true ]
|
||||
a = @h.clone
|
||||
a.taint if taint
|
||||
a.freeze if frozen
|
||||
b = a.clone
|
||||
for untrust in [ false, true ]
|
||||
for frozen in [ false, true ]
|
||||
a = @h.clone
|
||||
a.taint if taint
|
||||
a.untrust if untrust
|
||||
a.freeze if frozen
|
||||
b = a.clone
|
||||
|
||||
assert_equal(a, b)
|
||||
assert(a.__id__ != b.__id__)
|
||||
assert_equal(a.frozen?, b.frozen?)
|
||||
assert_equal(a.tainted?, b.tainted?)
|
||||
assert_equal(a, b)
|
||||
assert(a.__id__ != b.__id__)
|
||||
assert_equal(a.frozen?, b.frozen?)
|
||||
assert_equal(a.untrusted?, b.untrusted?)
|
||||
assert_equal(a.tainted?, b.tainted?)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -288,16 +292,19 @@ class TestHash < Test::Unit::TestCase
|
|||
|
||||
def test_dup
|
||||
for taint in [ false, true ]
|
||||
for frozen in [ false, true ]
|
||||
a = @h.dup
|
||||
a.taint if taint
|
||||
a.freeze if frozen
|
||||
b = a.dup
|
||||
for untrust in [ false, true ]
|
||||
for frozen in [ false, true ]
|
||||
a = @h.dup
|
||||
a.taint if taint
|
||||
a.freeze if frozen
|
||||
b = a.dup
|
||||
|
||||
assert_equal(a, b)
|
||||
assert(a.__id__ != b.__id__)
|
||||
assert_equal(false, b.frozen?)
|
||||
assert_equal(a.tainted?, b.tainted?)
|
||||
assert_equal(a, b)
|
||||
assert(a.__id__ != b.__id__)
|
||||
assert_equal(false, b.frozen?)
|
||||
assert_equal(a.tainted?, b.tainted?)
|
||||
assert_equal(a.untrusted?, b.untrusted?)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -599,6 +606,13 @@ class TestHash < Test::Unit::TestCase
|
|||
assert_equal([3,4], a.delete([3,4]))
|
||||
assert_equal([5,6], a.delete([5,6]))
|
||||
assert_equal(0, a.length)
|
||||
|
||||
h = @cls[ 1=>2, 3=>4, 5=>6 ]
|
||||
h.taint
|
||||
h.untrust
|
||||
a = h.to_a
|
||||
assert_equal(true, a.tainted?)
|
||||
assert_equal(true, a.untrusted?)
|
||||
end
|
||||
|
||||
def test_to_hash
|
||||
|
|
|
@ -179,4 +179,16 @@ class TestMarshal < Test::Unit::TestCase
|
|||
Marshal.dump((0..1000).map {|x| C4.new(x % 50 == 25) })
|
||||
end
|
||||
end
|
||||
|
||||
def test_taint_and_untrust
|
||||
x = Object.new
|
||||
x.taint
|
||||
x.untrust
|
||||
s = Marshal.dump(x)
|
||||
assert_equal(true, s.tainted?)
|
||||
assert_equal(true, s.untrusted?)
|
||||
y = Marshal.load(s)
|
||||
assert_equal(true, y.tainted?)
|
||||
assert_equal(true, y.untrusted?)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -699,4 +699,22 @@ class TestModule < Test::Unit::TestCase
|
|||
assert_equal(true, c2.include?(m))
|
||||
assert_equal(false, m.include?(m))
|
||||
end
|
||||
|
||||
def test_include_under_safe4
|
||||
m = Module.new
|
||||
c1 = Class.new
|
||||
assert_raise(SecurityError) do
|
||||
lambda {
|
||||
$SAFE = 4
|
||||
c1.instance_eval { include(m) }
|
||||
}.call
|
||||
end
|
||||
assert_nothing_raised do
|
||||
lambda {
|
||||
$SAFE = 4
|
||||
c2 = Class.new
|
||||
c2.instance_eval { include(m) }
|
||||
}.call
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -320,4 +320,82 @@ class TestObject < Test::Unit::TestCase
|
|||
1.extend
|
||||
end
|
||||
end
|
||||
|
||||
def test_untrusted
|
||||
obj = lambda {
|
||||
$SAFE = 4
|
||||
x = Object.new
|
||||
x.instance_eval { @foo = 1 }
|
||||
x
|
||||
}.call
|
||||
assert_equal(true, obj.untrusted?)
|
||||
assert_equal(true, obj.tainted?)
|
||||
|
||||
x = Object.new
|
||||
assert_equal(false, x.untrusted?)
|
||||
assert_raise(SecurityError) do
|
||||
lambda {
|
||||
$SAFE = 4
|
||||
x.instance_eval { @foo = 1 }
|
||||
}.call
|
||||
end
|
||||
|
||||
x = Object.new
|
||||
x.taint
|
||||
assert_raise(SecurityError) do
|
||||
lambda {
|
||||
$SAFE = 4
|
||||
x.instance_eval { @foo = 1 }
|
||||
}.call
|
||||
end
|
||||
|
||||
x.untrust
|
||||
assert_equal(true, x.untrusted?)
|
||||
assert_nothing_raised do
|
||||
lambda {
|
||||
$SAFE = 4
|
||||
x.instance_eval { @foo = 1 }
|
||||
}.call
|
||||
end
|
||||
|
||||
x.trust
|
||||
assert_equal(false, x.untrusted?)
|
||||
assert_raise(SecurityError) do
|
||||
lambda {
|
||||
$SAFE = 4
|
||||
x.instance_eval { @foo = 1 }
|
||||
}.call
|
||||
end
|
||||
|
||||
a = Object.new
|
||||
a.untrust
|
||||
assert_equal(true, a.untrusted?)
|
||||
b = a.dup
|
||||
assert_equal(true, b.untrusted?)
|
||||
c = a.clone
|
||||
assert_equal(true, c.untrusted?)
|
||||
|
||||
a = Object.new
|
||||
b = lambda {
|
||||
$SAFE = 4
|
||||
a.dup
|
||||
}.call
|
||||
assert_equal(true, b.untrusted?)
|
||||
|
||||
a = Object.new
|
||||
b = lambda {
|
||||
$SAFE = 4
|
||||
a.clone
|
||||
}.call
|
||||
assert_equal(true, b.untrusted?)
|
||||
end
|
||||
|
||||
def test_to_s
|
||||
x = Object.new
|
||||
x.taint
|
||||
x.untrust
|
||||
s = x.to_s
|
||||
assert_equal(true, s.untrusted?)
|
||||
assert_equal(true, s.tainted?)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -427,16 +427,20 @@ class TestString < Test::Unit::TestCase
|
|||
|
||||
def test_clone
|
||||
for taint in [ false, true ]
|
||||
for frozen in [ false, true ]
|
||||
a = S("Cool")
|
||||
a.taint if taint
|
||||
a.freeze if frozen
|
||||
b = a.clone
|
||||
for untrust in [ false, true ]
|
||||
for frozen in [ false, true ]
|
||||
a = S("Cool")
|
||||
a.taint if taint
|
||||
a.untrust if untrust
|
||||
a.freeze if frozen
|
||||
b = a.clone
|
||||
|
||||
assert_equal(a, b)
|
||||
assert(a.__id__ != b.__id__)
|
||||
assert_equal(a.frozen?, b.frozen?)
|
||||
assert_equal(a.tainted?, b.tainted?)
|
||||
assert_equal(a, b)
|
||||
assert(a.__id__ != b.__id__)
|
||||
assert_equal(a.frozen?, b.frozen?)
|
||||
assert_equal(a.untrusted?, b.untrusted?)
|
||||
assert_equal(a.tainted?, b.tainted?)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -532,16 +536,20 @@ class TestString < Test::Unit::TestCase
|
|||
|
||||
def test_dup
|
||||
for taint in [ false, true ]
|
||||
for frozen in [ false, true ]
|
||||
a = S("hello")
|
||||
a.taint if taint
|
||||
a.freeze if frozen
|
||||
b = a.dup
|
||||
for untrust in [ false, true ]
|
||||
for frozen in [ false, true ]
|
||||
a = S("hello")
|
||||
a.taint if taint
|
||||
a.untrust if untrust
|
||||
a.freeze if frozen
|
||||
b = a.dup
|
||||
|
||||
assert_equal(a, b)
|
||||
assert(a.__id__ != b.__id__)
|
||||
assert(!b.frozen?)
|
||||
assert_equal(a.tainted?, b.tainted?)
|
||||
assert_equal(a, b)
|
||||
assert(a.__id__ != b.__id__)
|
||||
assert(!b.frozen?)
|
||||
assert_equal(a.tainted?, b.tainted?)
|
||||
assert_equal(a.untrusted?, b.untrusted?)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -623,7 +631,9 @@ class TestString < Test::Unit::TestCase
|
|||
|
||||
a = S("hello")
|
||||
a.taint
|
||||
a.untrust
|
||||
assert(a.gsub(/./, S('X')).tainted?)
|
||||
assert(a.gsub(/./, S('X')).untrusted?)
|
||||
|
||||
assert_equal("z", "abc".gsub(/./, "a" => "z"), "moved from btest/knownbug")
|
||||
|
||||
|
@ -651,8 +661,10 @@ class TestString < Test::Unit::TestCase
|
|||
|
||||
r = S('X')
|
||||
r.taint
|
||||
r.untrust
|
||||
a.gsub!(/./, r)
|
||||
assert(a.tainted?)
|
||||
assert(a.untrusted?)
|
||||
|
||||
a = S("hello")
|
||||
assert_nil(a.sub!(S('X'), S('Y')))
|
||||
|
@ -823,9 +835,11 @@ class TestString < Test::Unit::TestCase
|
|||
|
||||
a = S("foo")
|
||||
a.taint
|
||||
a.untrust
|
||||
b = a.replace(S("xyz"))
|
||||
assert_equal(S("xyz"), b)
|
||||
assert(b.tainted?)
|
||||
assert(b.untrusted?)
|
||||
|
||||
s = "foo" * 100
|
||||
s2 = ("bar" * 100).dup
|
||||
|
@ -1170,7 +1184,10 @@ class TestString < Test::Unit::TestCase
|
|||
|
||||
a = S("hello")
|
||||
a.taint
|
||||
assert(a.sub(/./, S('X')).tainted?)
|
||||
a.untrust
|
||||
x = a.sub(/./, S('X'))
|
||||
assert(x.tainted?)
|
||||
assert(x.untrusted?)
|
||||
|
||||
o = Object.new
|
||||
def o.to_str; "bar"; end
|
||||
|
@ -1211,8 +1228,10 @@ class TestString < Test::Unit::TestCase
|
|||
|
||||
r = S('X')
|
||||
r.taint
|
||||
r.untrust
|
||||
a.sub!(/./, r)
|
||||
assert(a.tainted?)
|
||||
assert(a.untrusted?)
|
||||
end
|
||||
|
||||
def test_succ
|
||||
|
|
2
time.c
2
time.c
|
@ -60,7 +60,7 @@ static void
|
|||
time_modify(VALUE time)
|
||||
{
|
||||
rb_check_frozen(time);
|
||||
if (!OBJ_TAINTED(time) && rb_safe_level() >= 4)
|
||||
if (!OBJ_UNTRUSTED(time) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify Time");
|
||||
}
|
||||
|
||||
|
|
10
variable.c
10
variable.c
|
@ -995,7 +995,7 @@ rb_ivar_set(VALUE obj, ID id, VALUE val)
|
|||
long i, len;
|
||||
int ivar_extended;
|
||||
|
||||
if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
|
||||
if (!OBJ_UNTRUSTED(obj) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
|
||||
if (OBJ_FROZEN(obj)) rb_error_frozen("object");
|
||||
switch (TYPE(obj)) {
|
||||
|
@ -1216,7 +1216,7 @@ rb_obj_remove_instance_variable(VALUE obj, VALUE name)
|
|||
struct st_table *iv_index_tbl;
|
||||
st_data_t index;
|
||||
|
||||
if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
|
||||
if (!OBJ_UNTRUSTED(obj) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
|
||||
if (OBJ_FROZEN(obj)) rb_error_frozen("object");
|
||||
if (!rb_is_instance_id(id)) {
|
||||
|
@ -1505,7 +1505,7 @@ rb_mod_remove_const(VALUE mod, VALUE name)
|
|||
if (!rb_is_const_id(id)) {
|
||||
rb_name_error(id, "`%s' is not allowed as a constant name", rb_id2name(id));
|
||||
}
|
||||
if (!OBJ_TAINTED(mod) && rb_safe_level() >= 4)
|
||||
if (!OBJ_UNTRUSTED(mod) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't remove constant");
|
||||
if (OBJ_FROZEN(mod)) rb_error_frozen("class/module");
|
||||
|
||||
|
@ -1667,7 +1667,7 @@ mod_av_set(VALUE klass, ID id, VALUE val, int isconst)
|
|||
{
|
||||
const char *dest = isconst ? "constant" : "class variable";
|
||||
|
||||
if (!OBJ_TAINTED(klass) && rb_safe_level() >= 4)
|
||||
if (!OBJ_UNTRUSTED(klass) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't set %s", dest);
|
||||
if (OBJ_FROZEN(klass)) {
|
||||
if (BUILTIN_TYPE(klass) == T_MODULE) {
|
||||
|
@ -1922,7 +1922,7 @@ rb_mod_remove_cvar(VALUE mod, VALUE name)
|
|||
if (!rb_is_class_id(id)) {
|
||||
rb_name_error(id, "wrong class variable name %s", rb_id2name(id));
|
||||
}
|
||||
if (!OBJ_TAINTED(mod) && rb_safe_level() >= 4)
|
||||
if (!OBJ_UNTRUSTED(mod) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't remove class variable");
|
||||
if (OBJ_FROZEN(mod)) rb_error_frozen("class/module");
|
||||
|
||||
|
|
|
@ -108,7 +108,8 @@ rb_add_method(VALUE klass, ID mid, NODE * node, int noex)
|
|||
if (NIL_P(klass)) {
|
||||
klass = rb_cObject;
|
||||
}
|
||||
if (rb_safe_level() >= 4 && (klass == rb_cObject || !OBJ_TAINTED(klass))) {
|
||||
if (rb_safe_level() >= 4 &&
|
||||
(klass == rb_cObject || !OBJ_UNTRUSTED(klass))) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't define method");
|
||||
}
|
||||
if (!FL_TEST(klass, FL_SINGLETON) &&
|
||||
|
@ -307,7 +308,7 @@ remove_method(VALUE klass, ID mid)
|
|||
if (klass == rb_cObject) {
|
||||
rb_secure(4);
|
||||
}
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
|
||||
if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(klass)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't remove method");
|
||||
}
|
||||
if (OBJ_FROZEN(klass))
|
||||
|
@ -474,7 +475,7 @@ rb_undef(VALUE klass, ID id)
|
|||
if (rb_vm_cbase() == rb_cObject && klass == rb_cObject) {
|
||||
rb_secure(4);
|
||||
}
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
|
||||
if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(klass)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'",
|
||||
rb_id2name(id));
|
||||
}
|
||||
|
@ -810,7 +811,7 @@ rb_mod_alias_method(VALUE mod, VALUE newname, VALUE oldname)
|
|||
static void
|
||||
secure_visibility(VALUE self)
|
||||
{
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(self)) {
|
||||
if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(self)) {
|
||||
rb_raise(rb_eSecurityError,
|
||||
"Insecure: can't change method visibility");
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue