1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Deprecate taint/trust and related methods, and make the methods no-ops

This removes the related tests, and puts the related specs behind
version guards.  This affects all code in lib, including some
libraries that may want to support older versions of Ruby.
This commit is contained in:
Jeremy Evans 2019-09-24 20:59:12 -07:00
parent c5c05460ac
commit ffd0820ab3
Notes: git 2019-11-18 08:01:15 +09:00
201 changed files with 2292 additions and 2874 deletions

11
array.c
View file

@ -2285,7 +2285,6 @@ ary_join_0(VALUE ary, VALUE sep, long max, VALUE result)
if (i > 0 && !NIL_P(sep)) if (i > 0 && !NIL_P(sep))
rb_str_buf_append(result, sep); rb_str_buf_append(result, sep);
rb_str_buf_append(result, val); rb_str_buf_append(result, val);
if (OBJ_TAINTED(val)) OBJ_TAINT(result);
} }
} }
@ -2346,11 +2345,9 @@ VALUE
rb_ary_join(VALUE ary, VALUE sep) rb_ary_join(VALUE ary, VALUE sep)
{ {
long len = 1, i; long len = 1, i;
int taint = FALSE;
VALUE val, tmp, result; VALUE val, tmp, result;
if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new(0, 0); if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new(0, 0);
if (OBJ_TAINTED(ary)) taint = TRUE;
if (!NIL_P(sep)) { if (!NIL_P(sep)) {
StringValue(sep); StringValue(sep);
@ -2364,7 +2361,6 @@ rb_ary_join(VALUE ary, VALUE sep)
int first; int first;
result = rb_str_buf_new(len + (RARRAY_LEN(ary)-i)*10); result = rb_str_buf_new(len + (RARRAY_LEN(ary)-i)*10);
rb_enc_associate(result, rb_usascii_encoding()); rb_enc_associate(result, rb_usascii_encoding());
if (taint) OBJ_TAINT(result);
ary_join_0(ary, sep, i, result); ary_join_0(ary, sep, i, result);
first = i == 0; first = i == 0;
ary_join_1(ary, ary, sep, i, result, &first); ary_join_1(ary, ary, sep, i, result, &first);
@ -2377,7 +2373,6 @@ rb_ary_join(VALUE ary, VALUE sep)
result = rb_str_new(0, len); result = rb_str_new(0, len);
rb_str_set_len(result, 0); rb_str_set_len(result, 0);
if (taint) OBJ_TAINT(result);
ary_join_0(ary, sep, RARRAY_LEN(ary), result); ary_join_0(ary, sep, RARRAY_LEN(ary), result);
return result; return result;
@ -2419,7 +2414,6 @@ rb_ary_join_m(int argc, VALUE *argv, VALUE ary)
static VALUE static VALUE
inspect_ary(VALUE ary, VALUE dummy, int recur) inspect_ary(VALUE ary, VALUE dummy, int recur)
{ {
int tainted = OBJ_TAINTED(ary);
long i; long i;
VALUE s, str; VALUE s, str;
@ -2427,13 +2421,11 @@ inspect_ary(VALUE ary, VALUE dummy, int recur)
str = rb_str_buf_new2("["); str = rb_str_buf_new2("[");
for (i=0; i<RARRAY_LEN(ary); i++) { for (i=0; i<RARRAY_LEN(ary); i++) {
s = rb_inspect(RARRAY_AREF(ary, i)); s = rb_inspect(RARRAY_AREF(ary, i));
if (OBJ_TAINTED(s)) tainted = TRUE;
if (i > 0) rb_str_buf_cat2(str, ", "); if (i > 0) rb_str_buf_cat2(str, ", ");
else rb_enc_copy(str, s); else rb_enc_copy(str, s);
rb_str_buf_append(str, s); rb_str_buf_append(str, s);
} }
rb_str_buf_cat2(str, "]"); rb_str_buf_cat2(str, "]");
if (tainted) OBJ_TAINT(str);
return str; return str;
} }
@ -4135,8 +4127,6 @@ rb_ary_times(VALUE ary, VALUE times)
} }
} }
out: out:
OBJ_INFECT(ary2, ary);
return ary2; return ary2;
} }
@ -5315,7 +5305,6 @@ rb_ary_flatten(int argc, VALUE *argv, VALUE ary)
if (result == ary) { if (result == ary) {
result = ary_make_shared_copy(ary); result = ary_make_shared_copy(ary);
} }
OBJ_INFECT(result, ary);
return result; return result;
} }

View file

@ -128,10 +128,10 @@ EOU
exit 2 unless src exit 2 unless src
trim = trim_mode_opt(trim_mode, disable_percent) trim = trim_mode_opt(trim_mode, disable_percent)
if safe_level.nil? if safe_level.nil?
erb = factory.new(src.untaint, trim_mode: trim) erb = factory.new(src, trim_mode: trim)
else else
# [deprecated] This will be removed at Ruby 2.7. # [deprecated] This will be removed at Ruby 2.7.
erb = factory.new(src.untaint, safe_level, trim_mode: trim) erb = factory.new(src, safe_level, trim_mode: trim)
end end
erb.filename = filename erb.filename = filename
if output if output
@ -143,7 +143,7 @@ EOU
puts erb.src puts erb.src
end end
else else
bind = TOPLEVEL_BINDING.taint bind = TOPLEVEL_BINDING
if variables if variables
enc = erb.encoding enc = erb.encoding
for var, val in variables do for var, val in variables do

12
class.c
View file

@ -205,7 +205,6 @@ rb_class_boot(VALUE super)
RCLASS_SET_SUPER(klass, super); RCLASS_SET_SUPER(klass, super);
RCLASS_M_TBL_INIT(klass); RCLASS_M_TBL_INIT(klass);
OBJ_INFECT(klass, super);
return (VALUE)klass; return (VALUE)klass;
} }
@ -511,8 +510,6 @@ make_metaclass(VALUE klass)
while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super); while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super);
RCLASS_SET_SUPER(metaclass, super ? ENSURE_EIGENCLASS(super) : rb_cClass); RCLASS_SET_SUPER(metaclass, super ? ENSURE_EIGENCLASS(super) : rb_cClass);
OBJ_INFECT(metaclass, RCLASS_SUPER(metaclass));
return metaclass; return metaclass;
} }
@ -851,8 +848,6 @@ rb_include_class_new(VALUE module, VALUE super)
else { else {
RBASIC_SET_CLASS(klass, module); RBASIC_SET_CLASS(klass, module);
} }
OBJ_INFECT(klass, module);
OBJ_INFECT(klass, super);
return (VALUE)klass; return (VALUE)klass;
} }
@ -867,7 +862,6 @@ ensure_includable(VALUE klass, VALUE module)
if (!NIL_P(rb_refinement_module_get_refined_class(module))) { if (!NIL_P(rb_refinement_module_get_refined_class(module))) {
rb_raise(rb_eArgError, "refinement module is not allowed"); rb_raise(rb_eArgError, "refinement module is not allowed");
} }
OBJ_INFECT(klass, module);
} }
void void
@ -1660,12 +1654,6 @@ singleton_class_of(VALUE obj)
RCLASS_SERIAL(klass) = serial; RCLASS_SERIAL(klass) = serial;
} }
if (OBJ_TAINTED(obj)) {
OBJ_TAINT(klass);
}
else {
FL_UNSET(klass, FL_TAINT);
}
RB_FL_SET_RAW(klass, RB_OBJ_FROZEN_RAW(obj)); RB_FL_SET_RAW(klass, RB_OBJ_FROZEN_RAW(obj));
return klass; return klass;

4
dir.c
View file

@ -1129,9 +1129,8 @@ rb_dir_getwd_ospath(void)
DATA_PTR(path_guard) = path; DATA_PTR(path_guard) = path;
#ifdef __APPLE__ #ifdef __APPLE__
cwd = rb_str_normalize_ospath(path, strlen(path)); cwd = rb_str_normalize_ospath(path, strlen(path));
OBJ_TAINT(cwd);
#else #else
cwd = rb_tainted_str_new2(path); cwd = rb_str_new2(path);
#endif #endif
DATA_PTR(path_guard) = 0; DATA_PTR(path_guard) = 0;
@ -2564,7 +2563,6 @@ push_pattern(const char *path, VALUE ary, void *enc)
#if defined _WIN32 || defined __APPLE__ #if defined _WIN32 || defined __APPLE__
VALUE name = rb_utf8_str_new_cstr(path); VALUE name = rb_utf8_str_new_cstr(path);
rb_encoding *eenc = rb_default_internal_encoding(); rb_encoding *eenc = rb_default_internal_encoding();
OBJ_TAINT(name);
name = rb_str_conv_enc(name, NULL, eenc ? eenc : enc); name = rb_str_conv_enc(name, NULL, eenc ? eenc : enc);
#else #else
VALUE name = rb_external_str_new_with_enc(path, strlen(path), enc); VALUE name = rb_external_str_new_with_enc(path, strlen(path), enc);

View file

@ -649,7 +649,6 @@ load_encoding(const char *name)
else if (ISUPPER(*s)) *s = (char)TOLOWER(*s); else if (ISUPPER(*s)) *s = (char)TOLOWER(*s);
++s; ++s;
} }
FL_UNSET(enclib, FL_TAINT);
enclib = rb_fstring(enclib); enclib = rb_fstring(enclib);
ruby_verbose = Qfalse; ruby_verbose = Qfalse;
ruby_debug = Qfalse; ruby_debug = Qfalse;

4
enum.c
View file

@ -647,7 +647,6 @@ enum_to_a(int argc, VALUE *argv, VALUE obj)
VALUE ary = rb_ary_new(); VALUE ary = rb_ary_new();
rb_block_call(obj, id_each, argc, argv, collect_all, ary); rb_block_call(obj, id_each, argc, argv, collect_all, ary);
OBJ_INFECT(ary, obj);
return ary; return ary;
} }
@ -657,7 +656,6 @@ enum_hashify(VALUE obj, int argc, const VALUE *argv, rb_block_call_func *iter)
{ {
VALUE hash = rb_hash_new(); VALUE hash = rb_hash_new();
rb_block_call(obj, id_each, argc, argv, iter, hash); rb_block_call(obj, id_each, argc, argv, iter, hash);
OBJ_INFECT(hash, obj);
return hash; return hash;
} }
@ -1245,7 +1243,6 @@ enum_sort_by(VALUE obj)
buf = rb_ary_tmp_new(SORT_BY_BUFSIZE*2); buf = rb_ary_tmp_new(SORT_BY_BUFSIZE*2);
rb_ary_store(buf, SORT_BY_BUFSIZE*2-1, Qnil); rb_ary_store(buf, SORT_BY_BUFSIZE*2-1, Qnil);
memo = MEMO_NEW(0, 0, 0); memo = MEMO_NEW(0, 0, 0);
OBJ_INFECT(memo, obj);
data = (struct sort_by_data *)&memo->v1; data = (struct sort_by_data *)&memo->v1;
RB_OBJ_WRITE(memo, &data->ary, ary); RB_OBJ_WRITE(memo, &data->ary, ary);
RB_OBJ_WRITE(memo, &data->buf, buf); RB_OBJ_WRITE(memo, &data->buf, buf);
@ -1270,7 +1267,6 @@ enum_sort_by(VALUE obj)
} }
rb_ary_resize(ary, RARRAY_LEN(ary)/2); rb_ary_resize(ary, RARRAY_LEN(ary)/2);
RBASIC_SET_CLASS_RAW(ary, rb_cArray); RBASIC_SET_CLASS_RAW(ary, rb_cArray);
OBJ_INFECT(ary, memo);
return ary; return ary;
} }

View file

@ -1077,7 +1077,6 @@ inspect_enumerator(VALUE obj, VALUE dummy, int recur)
if (recur) { if (recur) {
str = rb_sprintf("#<%"PRIsVALUE": ...>", rb_class_path(cname)); str = rb_sprintf("#<%"PRIsVALUE": ...>", rb_class_path(cname));
OBJ_TAINT(str);
return str; return str;
} }
@ -1172,7 +1171,6 @@ append_method(VALUE obj, VALUE str, ID default_method, VALUE default_args)
rb_str_append(str, rb_inspect(arg)); rb_str_append(str, rb_inspect(arg));
rb_str_buf_cat2(str, ", "); rb_str_buf_cat2(str, ", ");
OBJ_INFECT(str, arg);
} }
if (!NIL_P(kwds)) { if (!NIL_P(kwds)) {
rb_hash_foreach(kwds, kwd_append, str); rb_hash_foreach(kwds, kwd_append, str);
@ -3609,7 +3607,6 @@ arith_seq_inspect(VALUE self)
rb_str_append(str, rb_inspect(arg)); rb_str_append(str, rb_inspect(arg));
rb_str_buf_cat2(str, ", "); rb_str_buf_cat2(str, ", ");
OBJ_INFECT(str, arg);
} }
if (!NIL_P(kwds)) { if (!NIL_P(kwds)) {
rb_hash_foreach(kwds, kwd_append, str); rb_hash_foreach(kwds, kwd_append, str);

17
error.c
View file

@ -2018,7 +2018,6 @@ syserr_initialize(int argc, VALUE *argv, VALUE self)
if (!NIL_P(func)) rb_str_catf(errmsg, " @ %"PRIsVALUE, func); if (!NIL_P(func)) rb_str_catf(errmsg, " @ %"PRIsVALUE, func);
rb_str_catf(errmsg, " - %"PRIsVALUE, str); rb_str_catf(errmsg, " - %"PRIsVALUE, str);
OBJ_INFECT(errmsg, mesg);
} }
mesg = errmsg; mesg = errmsg;
@ -2319,19 +2318,7 @@ syserr_eqq(VALUE self, VALUE exc)
/* /*
* Document-class: SecurityError * Document-class: SecurityError
* *
* Raised when attempting a potential unsafe operation, typically when * No longer used by internal code.
* the $SAFE level is raised above 0.
*
* foo = "bar"
* proc = Proc.new do
* $SAFE = 3
* foo.untaint
* end
* proc.call
*
* <em>raises the exception:</em>
*
* SecurityError: Insecure: Insecure operation `untaint' at level 3
*/ */
/* /*
@ -2971,12 +2958,14 @@ rb_check_frozen(VALUE obj)
void void
rb_error_untrusted(VALUE obj) rb_error_untrusted(VALUE obj)
{ {
rb_warning("rb_error_untrusted is deprecated and will be removed in Ruby 3.2.");
} }
#undef rb_check_trusted #undef rb_check_trusted
void void
rb_check_trusted(VALUE obj) rb_check_trusted(VALUE obj)
{ {
rb_warning("rb_check_trusted is deprecated and will be removed in Ruby 3.2.");
} }
void void

View file

@ -30,8 +30,6 @@ static inline void
preserve_original_state(VALUE orig, VALUE dest) preserve_original_state(VALUE orig, VALUE dest)
{ {
rb_enc_associate(dest, rb_enc_get(orig)); rb_enc_associate(dest, rb_enc_get(orig));
RB_OBJ_INFECT_RAW(dest, orig);
} }
static VALUE static VALUE

View file

@ -219,6 +219,7 @@ etc_getpwnam(VALUE obj, VALUE nam)
struct passwd *pwd; struct passwd *pwd;
const char *p = StringValueCStr(nam); const char *p = StringValueCStr(nam);
rb_check_safe_obj(nam);
pwd = getpwnam(p); pwd = getpwnam(p);
if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %"PRIsVALUE, nam); if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %"PRIsVALUE, nam);
return setup_passwd(pwd); return setup_passwd(pwd);
@ -462,6 +463,7 @@ etc_getgrnam(VALUE obj, VALUE nam)
struct group *grp; struct group *grp;
const char *p = StringValueCStr(nam); const char *p = StringValueCStr(nam);
rb_check_safe_obj(nam);
grp = getgrnam(p); grp = getgrnam(p);
if (grp == 0) rb_raise(rb_eArgError, "can't find group for %"PRIsVALUE, nam); if (grp == 0) rb_raise(rb_eArgError, "can't find group for %"PRIsVALUE, nam);
return setup_group(grp); return setup_group(grp);

View file

@ -1483,6 +1483,7 @@ prompt(int argc, VALUE *argv, VALUE io)
if (argc > 0 && !NIL_P(argv[0])) { if (argc > 0 && !NIL_P(argv[0])) {
VALUE str = argv[0]; VALUE str = argv[0];
StringValueCStr(str); StringValueCStr(str);
rb_check_safe_obj(str);
rb_io_write(io, str); rb_io_write(io, str);
} }
} }

View file

@ -168,7 +168,6 @@ rb_nkf_convert(VALUE obj, VALUE opt, VALUE src)
/* use _result_ end */ /* use _result_ end */
rb_str_set_len(tmp, output_ctr); rb_str_set_len(tmp, output_ctr);
OBJ_INFECT(tmp, src);
if (mimeout_f) if (mimeout_f)
rb_enc_associate(tmp, rb_usascii_encoding()); rb_enc_associate(tmp, rb_usascii_encoding());

View file

@ -67,6 +67,8 @@ ossl_rand_add(VALUE self, VALUE str, VALUE entropy)
static VALUE static VALUE
ossl_rand_load_file(VALUE self, VALUE filename) ossl_rand_load_file(VALUE self, VALUE filename)
{ {
rb_check_safe_obj(filename);
if(!RAND_load_file(StringValueCStr(filename), -1)) { if(!RAND_load_file(StringValueCStr(filename), -1)) {
ossl_raise(eRandomError, NULL); ossl_raise(eRandomError, NULL);
} }
@ -84,6 +86,8 @@ ossl_rand_load_file(VALUE self, VALUE filename)
static VALUE static VALUE
ossl_rand_write_file(VALUE self, VALUE filename) ossl_rand_write_file(VALUE self, VALUE filename)
{ {
rb_check_safe_obj(filename);
if (RAND_write_file(StringValueCStr(filename)) == -1) { if (RAND_write_file(StringValueCStr(filename)) == -1) {
ossl_raise(eRandomError, NULL); ossl_raise(eRandomError, NULL);
} }
@ -160,6 +164,8 @@ ossl_rand_pseudo_bytes(VALUE self, VALUE len)
static VALUE static VALUE
ossl_rand_egd(VALUE self, VALUE filename) ossl_rand_egd(VALUE self, VALUE filename)
{ {
rb_check_safe_obj(filename);
if (RAND_egd(StringValueCStr(filename)) == -1) { if (RAND_egd(StringValueCStr(filename)) == -1) {
ossl_raise(eRandomError, NULL); ossl_raise(eRandomError, NULL);
} }
@ -180,6 +186,8 @@ ossl_rand_egd_bytes(VALUE self, VALUE filename, VALUE len)
{ {
int n = NUM2INT(len); int n = NUM2INT(len);
rb_check_safe_obj(filename);
if (RAND_egd_bytes(StringValueCStr(filename), n) == -1) { if (RAND_egd_bytes(StringValueCStr(filename), n) == -1) {
ossl_raise(eRandomError, NULL); ossl_raise(eRandomError, NULL);
} }

View file

@ -304,6 +304,7 @@ ossl_x509store_add_file(VALUE self, VALUE file)
char *path = NULL; char *path = NULL;
if(file != Qnil){ if(file != Qnil){
rb_check_safe_obj(file);
path = StringValueCStr(file); path = StringValueCStr(file);
} }
GetX509Store(self, store); GetX509Store(self, store);
@ -339,6 +340,7 @@ ossl_x509store_add_path(VALUE self, VALUE dir)
char *path = NULL; char *path = NULL;
if(dir != Qnil){ if(dir != Qnil){
rb_check_safe_obj(dir);
path = StringValueCStr(dir); path = StringValueCStr(dir);
} }
GetX509Store(self, store); GetX509Store(self, store);

View file

@ -110,7 +110,6 @@ path_initialize(VALUE self, VALUE arg)
str = rb_obj_dup(str); str = rb_obj_dup(str);
set_strpath(self, str); set_strpath(self, str);
OBJ_INFECT(self, str);
return self; return self;
} }
@ -134,15 +133,12 @@ path_freeze(VALUE self)
* call-seq: * call-seq:
* pathname.taint -> obj * pathname.taint -> obj
* *
* Taints this Pathname. * Returns pathname. This method is deprecated and will be removed in Ruby 3.2.
*
* See Object.taint.
*/ */
static VALUE static VALUE
path_taint(VALUE self) path_taint(VALUE self)
{ {
rb_call_super(0, 0); rb_warning("Pathname#taint is deprecated and will be removed in Ruby 3.2.");
rb_obj_taint(get_strpath(self));
return self; return self;
} }
@ -150,15 +146,12 @@ path_taint(VALUE self)
* call-seq: * call-seq:
* pathname.untaint -> obj * pathname.untaint -> obj
* *
* Untaints this Pathname. * Returns pathname. This method is deprecated and will be removed in Ruby 3.2.
*
* See Object.untaint.
*/ */
static VALUE static VALUE
path_untaint(VALUE self) path_untaint(VALUE self)
{ {
rb_call_super(0, 0); rb_warning("Pathname#untaint is deprecated and will be removed in Ruby 3.2.");
rb_obj_untaint(get_strpath(self));
return self; return self;
} }
@ -308,7 +301,6 @@ path_sub_ext(VALUE self, VALUE repl)
} }
str2 = rb_str_subseq(str, 0, ext-p); str2 = rb_str_subseq(str, 0, ext-p);
rb_str_append(str2, repl); rb_str_append(str2, repl);
OBJ_INFECT(str2, str);
return rb_class_new_instance(1, &str2, rb_obj_class(self)); return rb_class_new_instance(1, &str2, rb_obj_class(self));
} }

View file

@ -1631,10 +1631,9 @@ bsock_recvmsg_internal(VALUE sock,
} }
if (NIL_P(dat_str)) if (NIL_P(dat_str))
dat_str = rb_tainted_str_new(datbuf, ss); dat_str = rb_str_new(datbuf, ss);
else { else {
rb_str_resize(dat_str, ss); rb_str_resize(dat_str, ss);
OBJ_TAINT(dat_str);
rb_obj_reveal(dat_str, rb_cString); rb_obj_reveal(dat_str, rb_cString);
} }
@ -1660,7 +1659,7 @@ bsock_recvmsg_internal(VALUE sock,
} }
ctl_end = (char*)cmh + cmh->cmsg_len; ctl_end = (char*)cmh + cmh->cmsg_len;
clen = (ctl_end <= msg_end ? ctl_end : msg_end) - (char*)CMSG_DATA(cmh); clen = (ctl_end <= msg_end ? ctl_end : msg_end) - (char*)CMSG_DATA(cmh);
ctl = ancdata_new(family, cmh->cmsg_level, cmh->cmsg_type, rb_tainted_str_new((char*)CMSG_DATA(cmh), clen)); ctl = ancdata_new(family, cmh->cmsg_level, cmh->cmsg_type, rb_str_new((char*)CMSG_DATA(cmh), clen));
if (request_scm_rights) if (request_scm_rights)
make_io_for_unix_rights(ctl, cmh, msg_end); make_io_for_unix_rights(ctl, cmh, msg_end);
else else

View file

@ -143,7 +143,7 @@ rsock_strbuf(VALUE str, long buflen)
{ {
long len; long len;
if (NIL_P(str)) return rb_tainted_str_new(0, buflen); if (NIL_P(str)) return rb_str_new(0, buflen);
StringValue(str); StringValue(str);
len = RSTRING_LEN(str); len = RSTRING_LEN(str);
@ -201,7 +201,6 @@ rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from)
if (slen != RSTRING_LEN(str)) { if (slen != RSTRING_LEN(str)) {
rb_str_set_len(str, slen); rb_str_set_len(str, slen);
} }
rb_obj_taint(str);
switch (from) { switch (from) {
case RECV_RECV: case RECV_RECV:
return str; return str;
@ -282,7 +281,6 @@ rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str,
if (slen != RSTRING_LEN(str)) { if (slen != RSTRING_LEN(str)) {
rb_str_set_len(str, slen); rb_str_set_len(str, slen);
} }
rb_obj_taint(str);
switch (from) { switch (from) {
case RECV_RECV: case RECV_RECV:
return str; return str;
@ -329,7 +327,6 @@ rsock_read_nonblock(VALUE sock, VALUE length, VALUE buf, VALUE ex)
VALUE str = rsock_strbuf(buf, len); VALUE str = rsock_strbuf(buf, len);
char *ptr; char *ptr;
OBJ_TAINT(str);
GetOpenFile(sock, fptr); GetOpenFile(sock, fptr);
if (len == 0) { if (len == 0) {

View file

@ -969,7 +969,7 @@ init_addrinfo_getaddrinfo(rb_addrinfo_t *rai, VALUE node, VALUE service,
canonname = Qnil; canonname = Qnil;
if (res->ai->ai_canonname) { if (res->ai->ai_canonname) {
canonname = rb_tainted_str_new_cstr(res->ai->ai_canonname); canonname = rb_str_new_cstr(res->ai->ai_canonname);
OBJ_FREEZE(canonname); OBJ_FREEZE(canonname);
} }
@ -1019,8 +1019,6 @@ make_inspectname(VALUE node, VALUE service, struct addrinfo *res)
rb_str_catf(inspectname, ":%d", FIX2INT(service)); rb_str_catf(inspectname, ":%d", FIX2INT(service));
} }
if (!NIL_P(inspectname)) { if (!NIL_P(inspectname)) {
OBJ_INFECT(inspectname, node);
OBJ_INFECT(inspectname, service);
OBJ_FREEZE(inspectname); OBJ_FREEZE(inspectname);
} }
return inspectname; return inspectname;
@ -1039,7 +1037,7 @@ addrinfo_firstonly_new(VALUE node, VALUE service, VALUE family, VALUE socktype,
canonname = Qnil; canonname = Qnil;
if (res->ai->ai_canonname) { if (res->ai->ai_canonname) {
canonname = rb_tainted_str_new_cstr(res->ai->ai_canonname); canonname = rb_str_new_cstr(res->ai->ai_canonname);
OBJ_FREEZE(canonname); OBJ_FREEZE(canonname);
} }
@ -1069,7 +1067,7 @@ addrinfo_list_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE
VALUE canonname = Qnil; VALUE canonname = Qnil;
if (r->ai_canonname) { if (r->ai_canonname) {
canonname = rb_tainted_str_new_cstr(r->ai_canonname); canonname = rb_str_new_cstr(r->ai_canonname);
OBJ_FREEZE(canonname); OBJ_FREEZE(canonname);
} }
@ -1908,7 +1906,6 @@ addrinfo_to_sockaddr(VALUE self)
rb_addrinfo_t *rai = get_addrinfo(self); rb_addrinfo_t *rai = get_addrinfo(self);
VALUE ret; VALUE ret;
ret = rb_str_new((char*)&rai->addr, rai->sockaddr_len); ret = rb_str_new((char*)&rai->addr, rai->sockaddr_len);
OBJ_INFECT(ret, self);
return ret; return ret;
} }
@ -2591,7 +2588,6 @@ addrinfo_s_unix(int argc, VALUE *argv, VALUE self)
addr = addrinfo_s_allocate(rb_cAddrinfo); addr = addrinfo_s_allocate(rb_cAddrinfo);
DATA_PTR(addr) = rai = alloc_addrinfo(); DATA_PTR(addr) = rai = alloc_addrinfo();
init_unix_addrinfo(rai, path, socktype); init_unix_addrinfo(rai, path, socktype);
OBJ_INFECT(addr, path);
return addr; return addr;
} }

View file

@ -1164,7 +1164,7 @@ sock_s_getservbyport(int argc, VALUE *argv, VALUE _)
if (!sp) { if (!sp) {
rb_raise(rb_eSocket, "no such service for port %d/%s", (int)portnum, protoname); rb_raise(rb_eSocket, "no such service for port %d/%s", (int)portnum, protoname);
} }
return rb_tainted_str_new2(sp->s_name); return rb_str_new2(sp->s_name);
} }
/* /*
@ -1414,8 +1414,6 @@ sock_s_pack_sockaddr_in(VALUE self, VALUE port, VALUE host)
VALUE addr = rb_str_new((char*)res->ai->ai_addr, res->ai->ai_addrlen); VALUE addr = rb_str_new((char*)res->ai->ai_addr, res->ai->ai_addrlen);
rb_freeaddrinfo(res); rb_freeaddrinfo(res);
OBJ_INFECT(addr, port);
OBJ_INFECT(addr, host);
return addr; return addr;
} }
@ -1457,7 +1455,6 @@ sock_s_unpack_sockaddr_in(VALUE self, VALUE addr)
#endif #endif
} }
host = rsock_make_ipaddr((struct sockaddr*)sockaddr, RSTRING_SOCKLEN(addr)); host = rsock_make_ipaddr((struct sockaddr*)sockaddr, RSTRING_SOCKLEN(addr));
OBJ_INFECT(host, addr);
return rb_assoc_new(INT2NUM(ntohs(sockaddr->sin_port)), host); return rb_assoc_new(INT2NUM(ntohs(sockaddr->sin_port)), host);
} }
@ -1487,7 +1484,6 @@ sock_s_pack_sockaddr_un(VALUE self, VALUE path)
} }
memcpy(sockaddr.sun_path, RSTRING_PTR(path), RSTRING_LEN(path)); memcpy(sockaddr.sun_path, RSTRING_PTR(path), RSTRING_LEN(path));
addr = rb_str_new((char*)&sockaddr, rsock_unix_sockaddr_len(path)); addr = rb_str_new((char*)&sockaddr, rsock_unix_sockaddr_len(path));
OBJ_INFECT(addr, path);
return addr; return addr;
} }
@ -1524,7 +1520,6 @@ sock_s_unpack_sockaddr_un(VALUE self, VALUE addr)
RSTRING_LEN(addr), (int)sizeof(struct sockaddr_un)); RSTRING_LEN(addr), (int)sizeof(struct sockaddr_un));
} }
path = rsock_unixpath_str(sockaddr, RSTRING_SOCKLEN(addr)); path = rsock_unixpath_str(sockaddr, RSTRING_SOCKLEN(addr));
OBJ_INFECT(path, addr);
return path; return path;
} }
#endif #endif

16
file.c
View file

@ -160,8 +160,6 @@ VALUE rb_cFile;
VALUE rb_mFileTest; VALUE rb_mFileTest;
VALUE rb_cStat; VALUE rb_cStat;
#define insecure_obj_p(obj, level) ((level) > 0 && OBJ_TAINTED(obj))
static VALUE static VALUE
file_path_convert(VALUE name) file_path_convert(VALUE name)
{ {
@ -1074,7 +1072,6 @@ rb_stat_inspect(VALUE self)
} }
} }
rb_str_buf_cat2(str, ">"); rb_str_buf_cat2(str, ">");
OBJ_INFECT(str, self);
return str; return str;
} }
@ -3651,18 +3648,15 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
const char *s, *b, *fend; const char *s, *b, *fend;
char *buf, *p, *pend, *root; char *buf, *p, *pend, *root;
size_t buflen, bdiff; size_t buflen, bdiff;
int tainted;
rb_encoding *enc, *fsenc = rb_filesystem_encoding(); rb_encoding *enc, *fsenc = rb_filesystem_encoding();
s = StringValuePtr(fname); s = StringValuePtr(fname);
fend = s + RSTRING_LEN(fname); fend = s + RSTRING_LEN(fname);
enc = rb_enc_get(fname); enc = rb_enc_get(fname);
BUFINIT(); BUFINIT();
tainted = OBJ_TAINTED(fname);
if (s[0] == '~' && abs_mode == 0) { /* execute only if NOT absolute_path() */ if (s[0] == '~' && abs_mode == 0) { /* execute only if NOT absolute_path() */
long userlen = 0; long userlen = 0;
tainted = 1;
if (isdirsep(s[1]) || s[1] == '\0') { if (isdirsep(s[1]) || s[1] == '\0') {
buf = 0; buf = 0;
b = 0; b = 0;
@ -3720,7 +3714,6 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
} }
if (!same) { if (!same) {
char *e = append_fspath(result, fname, getcwdofdrv(*s), &enc, fsenc); char *e = append_fspath(result, fname, getcwdofdrv(*s), &enc, fsenc);
tainted = 1;
BUFINIT(); BUFINIT();
p = e; p = e;
} }
@ -3742,7 +3735,6 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
} }
else { else {
char *e = append_fspath(result, fname, ruby_getcwd(), &enc, fsenc); char *e = append_fspath(result, fname, ruby_getcwd(), &enc, fsenc);
tainted = 1;
BUFINIT(); BUFINIT();
p = e; p = e;
} }
@ -3993,7 +3985,6 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
} }
#endif #endif
if (tainted) OBJ_TAINT(result);
rb_str_set_len(result, p - buf); rb_str_set_len(result, p - buf);
rb_enc_check(fname, result); rb_enc_check(fname, result);
ENC_CODERANGE_CLEAR(result); ENC_CODERANGE_CLEAR(result);
@ -4340,7 +4331,6 @@ rb_check_realpath_emulate(VALUE basedir, VALUE path, enum rb_realpath_mode mode)
} }
} }
rb_obj_taint(resolved);
RB_GC_GUARD(unresolved_path); RB_GC_GUARD(unresolved_path);
RB_GC_GUARD(curdir); RB_GC_GUARD(curdir);
return resolved; return resolved;
@ -4409,7 +4399,6 @@ rb_check_realpath_internal(VALUE basedir, VALUE path, enum rb_realpath_mode mode
} }
} }
rb_obj_taint(resolved);
RB_GC_GUARD(unresolved_path); RB_GC_GUARD(unresolved_path);
return resolved; return resolved;
#else #else
@ -4631,7 +4620,6 @@ rb_file_s_basename(int argc, VALUE *argv, VALUE _)
basename = rb_str_new(p, f); basename = rb_str_new(p, f);
rb_enc_copy(basename, fname); rb_enc_copy(basename, fname);
OBJ_INFECT(basename, fname);
return basename; return basename;
} }
@ -4693,7 +4681,6 @@ rb_file_dirname(VALUE fname)
rb_str_cat(dirname, ".", 1); rb_str_cat(dirname, ".", 1);
#endif #endif
rb_enc_copy(dirname, fname); rb_enc_copy(dirname, fname);
OBJ_INFECT(dirname, fname);
return dirname; return dirname;
} }
@ -4802,7 +4789,6 @@ rb_file_s_extname(VALUE klass, VALUE fname)
if (len < 1) if (len < 1)
return rb_str_new(0, 0); return rb_str_new(0, 0);
extname = rb_str_subseq(fname, e - name, len); /* keep the dot, too! */ extname = rb_str_subseq(fname, e - name, len); /* keep the dot, too! */
OBJ_INFECT(extname, fname);
return extname; return extname;
} }
@ -4873,7 +4859,6 @@ rb_file_join(VALUE ary)
len += RARRAY_LEN(ary) - 1; len += RARRAY_LEN(ary) - 1;
result = rb_str_buf_new(len); result = rb_str_buf_new(len);
RBASIC_CLEAR_CLASS(result); RBASIC_CLEAR_CLASS(result);
OBJ_INFECT(result, ary);
for (i=0; i<RARRAY_LEN(ary); i++) { for (i=0; i<RARRAY_LEN(ary); i++) {
tmp = RARRAY_AREF(ary, i); tmp = RARRAY_AREF(ary, i);
switch (OBJ_BUILTIN_TYPE(tmp)) { switch (OBJ_BUILTIN_TYPE(tmp)) {
@ -6333,7 +6318,6 @@ rb_find_file_ext(VALUE *filep, const char *const *ext)
*filep = copy_path_class(tmp, *filep); *filep = copy_path_class(tmp, *filep);
return (int)(j+1); return (int)(j+1);
} }
FL_UNSET(tmp, FL_TAINT);
} }
rb_str_set_len(fname, fnlen); rb_str_set_len(fname, fnlen);
} }

5
gc.c
View file

@ -3288,9 +3288,6 @@ static VALUE
run_single_final(VALUE final, VALUE objid) run_single_final(VALUE final, VALUE objid)
{ {
const VALUE cmd = RARRAY_AREF(final, 1); const VALUE cmd = RARRAY_AREF(final, 1);
const int level = OBJ_TAINTED(cmd) ?
RUBY_SAFE_LEVEL_MAX : FIX2INT(RARRAY_AREF(final, 0));
return rb_check_funcall(cmd, idCall, 1, &objid); return rb_check_funcall(cmd, idCall, 1, &objid);
} }
@ -10486,8 +10483,6 @@ wmap_inspect_i(st_data_t key, st_data_t val, st_data_t arg)
rb_str_cat2(str, " => "); rb_str_cat2(str, " => ");
v = SPECIAL_CONST_P(v) ? rb_inspect(v) : rb_any_to_s(v); v = SPECIAL_CONST_P(v) ? rb_inspect(v) : rb_any_to_s(v);
rb_str_append(str, v); rb_str_append(str, v);
OBJ_INFECT(str, k);
OBJ_INFECT(str, v);
return ST_CONTINUE; return ST_CONTINUE;
} }

53
hash.c
View file

@ -40,7 +40,7 @@
#define HAS_EXTRA_STATES(hash, klass) ( \ #define HAS_EXTRA_STATES(hash, klass) ( \
((klass = has_extra_methods(rb_obj_class(hash))) != 0) || \ ((klass = has_extra_methods(rb_obj_class(hash))) != 0) || \
FL_TEST((hash), FL_EXIVAR|FL_TAINT|RHASH_PROC_DEFAULT) || \ FL_TEST((hash), FL_EXIVAR|RHASH_PROC_DEFAULT) || \
!NIL_P(RHASH_IFNONE(hash))) !NIL_P(RHASH_IFNONE(hash)))
#define SET_DEFAULT(hash, ifnone) ( \ #define SET_DEFAULT(hash, ifnone) ( \
@ -1554,7 +1554,7 @@ rb_hash_dup(VALUE hash)
{ {
const VALUE flags = RBASIC(hash)->flags; const VALUE flags = RBASIC(hash)->flags;
VALUE ret = hash_dup(hash, rb_obj_class(hash), VALUE ret = hash_dup(hash, rb_obj_class(hash),
flags & (FL_EXIVAR|FL_TAINT|RHASH_PROC_DEFAULT)); flags & (FL_EXIVAR|RHASH_PROC_DEFAULT));
if (flags & FL_EXIVAR) if (flags & FL_EXIVAR)
rb_copy_generic_ivar(ret, hash); rb_copy_generic_ivar(ret, hash);
return ret; return ret;
@ -2744,7 +2744,7 @@ hash_aset(st_data_t *key, st_data_t *val, struct update_arg *arg, int existing)
VALUE VALUE
rb_hash_key_str(VALUE key) rb_hash_key_str(VALUE key)
{ {
if (!RB_FL_ANY_RAW(key, FL_TAINT|FL_EXIVAR) && RBASIC_CLASS(key) == rb_cString) { if (!RB_FL_ANY_RAW(key, FL_EXIVAR) && RBASIC_CLASS(key) == rb_cString) {
return rb_fstring(key); return rb_fstring(key);
} }
else { else {
@ -3200,7 +3200,6 @@ rb_hash_to_a(VALUE hash)
ary = rb_ary_new_capa(RHASH_SIZE(hash)); ary = rb_ary_new_capa(RHASH_SIZE(hash));
rb_hash_foreach(hash, to_a_i, ary); rb_hash_foreach(hash, to_a_i, ary);
OBJ_INFECT(ary, hash);
return ary; return ary;
} }
@ -3218,11 +3217,9 @@ inspect_i(VALUE key, VALUE value, VALUE str)
rb_enc_copy(str, str2); rb_enc_copy(str, str2);
} }
rb_str_buf_append(str, str2); rb_str_buf_append(str, str2);
OBJ_INFECT(str, str2);
rb_str_buf_cat_ascii(str, "=>"); rb_str_buf_cat_ascii(str, "=>");
str2 = rb_inspect(value); str2 = rb_inspect(value);
rb_str_buf_append(str, str2); rb_str_buf_append(str, str2);
OBJ_INFECT(str, str2);
return ST_CONTINUE; return ST_CONTINUE;
} }
@ -3236,7 +3233,6 @@ inspect_hash(VALUE hash, VALUE dummy, int recur)
str = rb_str_buf_new2("{"); str = rb_str_buf_new2("{");
rb_hash_foreach(hash, inspect_i, str); rb_hash_foreach(hash, inspect_i, str);
rb_str_buf_cat2(str, "}"); rb_str_buf_cat2(str, "}");
OBJ_INFECT(str, hash);
return str; return str;
} }
@ -3303,7 +3299,6 @@ rb_hash_to_h_block(VALUE hash)
{ {
VALUE h = rb_hash_new_with_size(RHASH_SIZE(hash)); VALUE h = rb_hash_new_with_size(RHASH_SIZE(hash));
rb_hash_foreach(hash, to_h_i, h); rb_hash_foreach(hash, to_h_i, h);
OBJ_INFECT(h, hash);
return h; return h;
} }
@ -4556,8 +4551,6 @@ rb_hash_bulk_insert(long argc, const VALUE *argv, VALUE hash)
} }
} }
static int path_tainted = -1;
static char **origenviron; static char **origenviron;
#ifdef _WIN32 #ifdef _WIN32
#define GET_ENVIRON(e) ((e) = rb_w32_get_environ()) #define GET_ENVIRON(e) ((e) = rb_w32_get_environ())
@ -4615,7 +4608,6 @@ env_enc_str_new(const char *ptr, long len, rb_encoding *enc)
VALUE str = rb_external_str_new_with_enc(ptr, len, enc); VALUE str = rb_external_str_new_with_enc(ptr, len, enc);
#endif #endif
OBJ_TAINT(str);
rb_obj_freeze(str); rb_obj_freeze(str);
return str; return str;
} }
@ -4639,15 +4631,13 @@ env_str_new2(const char *ptr)
return env_str_new(ptr, strlen(ptr)); return env_str_new(ptr, strlen(ptr));
} }
static int env_path_tainted(const char *);
static const char TZ_ENV[] = "TZ"; static const char TZ_ENV[] = "TZ";
extern bool ruby_tz_uptodate_p; extern bool ruby_tz_uptodate_p;
static rb_encoding * static rb_encoding *
env_encoding_for(const char *name, const char *ptr) env_encoding_for(const char *name, const char *ptr)
{ {
if (ENVMATCH(name, PATH_ENV) && !env_path_tainted(ptr)) { if (ENVMATCH(name, PATH_ENV)) {
return rb_filesystem_encoding(); return rb_filesystem_encoding();
} }
else { else {
@ -4725,7 +4715,6 @@ env_delete(VALUE name)
ruby_setenv(nam, 0); ruby_setenv(nam, 0);
if (ENVMATCH(nam, PATH_ENV)) { if (ENVMATCH(nam, PATH_ENV)) {
RB_GC_GUARD(name); RB_GC_GUARD(name);
path_tainted = 0;
} }
else if (ENVMATCH(nam, TZ_ENV)) { else if (ENVMATCH(nam, TZ_ENV)) {
ruby_tz_uptodate_p = FALSE; ruby_tz_uptodate_p = FALSE;
@ -4842,28 +4831,11 @@ env_fetch(int argc, VALUE *argv, VALUE _)
return env_name_new(nam, env); return env_name_new(nam, env);
} }
static void
path_tainted_p(const char *path)
{
path_tainted = rb_path_check(path)?0:1;
}
static int
env_path_tainted(const char *path)
{
if (path_tainted < 0) {
path_tainted_p(path);
}
return path_tainted;
}
int int
rb_env_path_tainted(void) rb_env_path_tainted(void)
{ {
if (path_tainted < 0) { rb_warning("rb_env_path_tainted is deprecated and will be removed in Ruby 3.2.");
path_tainted_p(getenv(PATH_ENV)); return 0;
}
return path_tainted;
} }
#if defined(_WIN32) || (defined(HAVE_SETENV) && defined(HAVE_UNSETENV)) #if defined(_WIN32) || (defined(HAVE_SETENV) && defined(HAVE_UNSETENV))
@ -5133,14 +5105,6 @@ env_aset(VALUE nm, VALUE val)
ruby_setenv(name, value); ruby_setenv(name, value);
if (ENVMATCH(name, PATH_ENV)) { if (ENVMATCH(name, PATH_ENV)) {
RB_GC_GUARD(nm); RB_GC_GUARD(nm);
if (OBJ_TAINTED(val)) {
/* already tainted, no check */
path_tainted = 1;
return val;
}
else {
path_tainted_p(value);
}
} }
else if (ENVMATCH(name, TZ_ENV)) { else if (ENVMATCH(name, TZ_ENV)) {
ruby_tz_uptodate_p = FALSE; ruby_tz_uptodate_p = FALSE;
@ -5342,7 +5306,6 @@ env_reject_bang(VALUE ehash)
VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i)); VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
if (!NIL_P(val)) { if (!NIL_P(val)) {
if (RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) { if (RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) {
FL_UNSET(RARRAY_AREF(keys, i), FL_TAINT);
env_delete(RARRAY_AREF(keys, i)); env_delete(RARRAY_AREF(keys, i));
del++; del++;
} }
@ -5452,7 +5415,6 @@ env_select_bang(VALUE ehash)
VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i)); VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
if (!NIL_P(val)) { if (!NIL_P(val)) {
if (!RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) { if (!RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) {
FL_UNSET(RARRAY_AREF(keys, i), FL_TAINT);
env_delete(RARRAY_AREF(keys, i)); env_delete(RARRAY_AREF(keys, i));
del++; del++;
} }
@ -5581,7 +5543,6 @@ env_inspect(VALUE _)
} }
FREE_ENVIRON(environ); FREE_ENVIRON(environ);
rb_str_buf_cat2(str, "}"); rb_str_buf_cat2(str, "}");
OBJ_TAINT(str);
return str; return str;
} }
@ -5755,7 +5716,7 @@ env_rassoc(VALUE dmy, VALUE obj)
if (s++) { if (s++) {
long len = strlen(s); long len = strlen(s);
if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) { if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
VALUE result = rb_assoc_new(rb_tainted_str_new(*env, s-*env-1), obj); VALUE result = rb_assoc_new(rb_str_new(*env, s-*env-1), obj);
FREE_ENVIRON(environ); FREE_ENVIRON(environ);
return result; return result;
} }

View file

@ -308,10 +308,8 @@ void rb_check_trusted(VALUE);
rb_error_frozen_object(frozen_obj); \ rb_error_frozen_object(frozen_obj); \
} \ } \
} while (0) } while (0)
#define rb_check_trusted_internal(obj) ((void) 0)
#ifdef __GNUC__ #ifdef __GNUC__
#define rb_check_frozen(obj) __extension__({rb_check_frozen_internal(obj);}) #define rb_check_frozen(obj) __extension__({rb_check_frozen_internal(obj);})
#define rb_check_trusted(obj) __extension__({rb_check_trusted_internal(obj);})
#else #else
static inline void static inline void
rb_check_frozen_inline(VALUE obj) rb_check_frozen_inline(VALUE obj)
@ -322,7 +320,7 @@ rb_check_frozen_inline(VALUE obj)
static inline void static inline void
rb_check_trusted_inline(VALUE obj) rb_check_trusted_inline(VALUE obj)
{ {
rb_check_trusted_internal(obj); rb_check_trusted(obj);
} }
#define rb_check_trusted(obj) rb_check_trusted_inline(obj) #define rb_check_trusted(obj) rb_check_trusted_inline(obj)
#endif #endif

8
io.c
View file

@ -2525,7 +2525,6 @@ remain_size(rb_io_t *fptr)
static VALUE static VALUE
io_enc_str(VALUE str, rb_io_t *fptr) io_enc_str(VALUE str, rb_io_t *fptr)
{ {
OBJ_TAINT(str);
rb_enc_associate(str, io_read_encoding(fptr)); rb_enc_associate(str, io_read_encoding(fptr));
return str; return str;
} }
@ -2655,7 +2654,6 @@ io_shift_cbuf(rb_io_t *fptr, int len, VALUE *strp)
else { else {
rb_str_cat(str, fptr->cbuf.ptr+fptr->cbuf.off, len); rb_str_cat(str, fptr->cbuf.ptr+fptr->cbuf.off, len);
} }
OBJ_TAINT(str);
rb_enc_associate(str, fptr->encs.enc); rb_enc_associate(str, fptr->encs.enc);
} }
fptr->cbuf.off += len; fptr->cbuf.off += len;
@ -2820,7 +2818,6 @@ io_getpartial(int argc, VALUE *argv, VALUE io, int no_exception, int nonblock)
} }
shrinkable = io_setstrbuf(&str, len); shrinkable = io_setstrbuf(&str, len);
OBJ_TAINT(str);
GetOpenFile(io, fptr); GetOpenFile(io, fptr);
rb_io_check_byte_readable(fptr); rb_io_check_byte_readable(fptr);
@ -2963,7 +2960,6 @@ io_read_nonblock(rb_execution_context_t *ec, VALUE io, VALUE length, VALUE str,
} }
shrinkable = io_setstrbuf(&str, len); shrinkable = io_setstrbuf(&str, len);
OBJ_TAINT(str);
rb_bool_expected(ex, "exception"); rb_bool_expected(ex, "exception");
GetOpenFile(io, fptr); GetOpenFile(io, fptr);
@ -3150,7 +3146,6 @@ io_read(int argc, VALUE *argv, VALUE io)
} }
#endif #endif
if (n == 0) return Qnil; if (n == 0) return Qnil;
OBJ_TAINT(str);
return str; return str;
} }
@ -5185,7 +5180,6 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
if (n == 0 && ilen > 0) { if (n == 0 && ilen > 0) {
rb_eof_error(); rb_eof_error();
} }
OBJ_TAINT(str);
return str; return str;
} }
@ -5269,7 +5263,6 @@ rb_io_pread(int argc, VALUE *argv, VALUE io)
if (n == 0 && arg.count > 0) { if (n == 0 && arg.count > 0) {
rb_eof_error(); rb_eof_error();
} }
OBJ_TAINT(str);
return str; return str;
} }
@ -7088,7 +7081,6 @@ check_pipe_command(VALUE filename_or_command)
if (rb_enc_ascget(s, e, &chlen, rb_enc_get(filename_or_command)) == '|') { if (rb_enc_ascget(s, e, &chlen, rb_enc_get(filename_or_command)) == '|') {
VALUE cmd = rb_str_new(s+chlen, l-chlen); VALUE cmd = rb_str_new(s+chlen, l-chlen);
OBJ_INFECT(cmd, filename_or_command);
return cmd; return cmd;
} }
return Qnil; return Qnil;

View file

@ -544,11 +544,11 @@ class CGI
/Content-Disposition:.* filename=(?:"(.*?)"|([^;\r\n]*))/i.match(head) /Content-Disposition:.* filename=(?:"(.*?)"|([^;\r\n]*))/i.match(head)
filename = $1 || $2 || ''.dup filename = $1 || $2 || ''.dup
filename = CGI.unescape(filename) if unescape_filename?() filename = CGI.unescape(filename) if unescape_filename?()
body.instance_variable_set(:@original_filename, filename.taint) body.instance_variable_set(:@original_filename, filename)
## content type ## content type
/Content-Type: (.*)/i.match(head) /Content-Type: (.*)/i.match(head)
(content_type = $1 || ''.dup).chomp! (content_type = $1 || ''.dup).chomp!
body.instance_variable_set(:@content_type, content_type.taint) body.instance_variable_set(:@content_type, content_type)
## query parameter name ## query parameter name
/Content-Disposition:.* name=(?:"(.*?)"|([^;\r\n]*))/i.match(head) /Content-Disposition:.* name=(?:"(.*?)"|([^;\r\n]*))/i.match(head)
name = $1 || $2 || '' name = $1 || $2 || ''

View file

@ -50,7 +50,6 @@ class CGI
require 'digest/md5' require 'digest/md5'
md5 = Digest::MD5.hexdigest(id)[0,16] md5 = Digest::MD5.hexdigest(id)[0,16]
path = dir+"/"+prefix+md5 path = dir+"/"+prefix+md5
path.untaint
if File::exist?(path) if File::exist?(path)
@hash = nil @hash = nil
else else

View file

@ -219,36 +219,13 @@ class Delegator < BasicObject
end end
private :initialize_clone, :initialize_dup private :initialize_clone, :initialize_dup
##
# :method: trust
# Trust both the object returned by \_\_getobj\_\_ and self.
#
##
# :method: untrust
# Untrust both the object returned by \_\_getobj\_\_ and self.
#
##
# :method: taint
# Taint both the object returned by \_\_getobj\_\_ and self.
#
##
# :method: untaint
# Untaint both the object returned by \_\_getobj\_\_ and self.
#
## ##
# :method: freeze # :method: freeze
# Freeze both the object returned by \_\_getobj\_\_ and self. # Freeze both the object returned by \_\_getobj\_\_ and self.
# #
def freeze
[:trust, :untrust, :taint, :untaint, :freeze].each do |method| __getobj__.freeze
define_method method do super()
__getobj__.send(method)
super()
end
end end
@delegator_api = self.public_instance_methods @delegator_api = self.public_instance_methods

View file

@ -233,7 +233,7 @@ require_relative 'eq'
# def get_logger(name) # def get_logger(name)
# if !@loggers.has_key? name # if !@loggers.has_key? name
# # make the filename safe, then declare it to be so # # make the filename safe, then declare it to be so
# fname = name.gsub(/[.\/\\\:]/, "_").untaint # fname = name.gsub(/[.\/\\\:]/, "_")
# @loggers[name] = Logger.new(name, @basedir + "/" + fname) # @loggers[name] = Logger.new(name, @basedir + "/" + fname)
# end # end
# return @loggers[name] # return @loggers[name]
@ -594,16 +594,9 @@ module DRb
raise(DRbConnError, 'premature marshal format(can\'t read)') if str.size < sz raise(DRbConnError, 'premature marshal format(can\'t read)') if str.size < sz
DRb.mutex.synchronize do DRb.mutex.synchronize do
begin begin
save = Thread.current[:drb_untaint]
Thread.current[:drb_untaint] = []
Marshal::load(str) Marshal::load(str)
rescue NameError, ArgumentError rescue NameError, ArgumentError
DRbUnknown.new($!, str) DRbUnknown.new($!, str)
ensure
Thread.current[:drb_untaint].each do |x|
x.untaint
end
Thread.current[:drb_untaint] = save
end end
end end
end end
@ -843,8 +836,6 @@ module DRb
# URI protocols. # URI protocols.
def self.open(uri, config) def self.open(uri, config)
host, port, = parse_uri(uri) host, port, = parse_uri(uri)
host.untaint
port.untaint
soc = TCPSocket.open(host, port) soc = TCPSocket.open(host, port)
self.new(uri, soc, config) self.new(uri, soc, config)
end end
@ -1061,9 +1052,6 @@ module DRb
if DRb.here?(uri) if DRb.here?(uri)
obj = DRb.to_obj(ref) obj = DRb.to_obj(ref)
if ((! obj.tainted?) && Thread.current[:drb_untaint])
Thread.current[:drb_untaint].push(obj)
end
return obj return obj
end end

View file

@ -248,8 +248,6 @@ module DRb
# configuration. Either a Hash or DRb::DRbSSLSocket::SSLConfig # configuration. Either a Hash or DRb::DRbSSLSocket::SSLConfig
def self.open(uri, config) def self.open(uri, config)
host, port, = parse_uri(uri) host, port, = parse_uri(uri)
host.untaint
port.untaint
soc = TCPSocket.open(host, port) soc = TCPSocket.open(host, port)
ssl_conf = SSLConfig::new(config) ssl_conf = SSLConfig::new(config)
ssl_conf.setup_ssl_context ssl_conf.setup_ssl_context

View file

@ -27,7 +27,6 @@ module DRb
def self.open(uri, config) def self.open(uri, config)
filename, = parse_uri(uri) filename, = parse_uri(uri)
filename.untaint
soc = UNIXSocket.open(filename) soc = UNIXSocket.open(filename)
self.new(uri, soc, config) self.new(uri, soc, config)
end end

View file

@ -46,7 +46,7 @@ module Find
ps = [path] ps = [path]
while file = ps.shift while file = ps.shift
catch(:prune) do catch(:prune) do
yield file.dup.taint yield file.dup
begin begin
s = File.lstat(file) s = File.lstat(file)
rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
@ -63,7 +63,7 @@ module Find
fs.sort! fs.sort!
fs.reverse_each {|f| fs.reverse_each {|f|
f = File.join(file, f) f = File.join(file, f)
ps.unshift f.untaint ps.unshift f
} }
end end
end end

View file

@ -3238,7 +3238,7 @@ module Net
if atom if atom
atom atom
else else
symbol = flag.capitalize.untaint.intern symbol = flag.capitalize.intern
@flag_symbols[symbol] = true @flag_symbols[symbol] = true
if @flag_symbols.length > IMAP.max_flag_count if @flag_symbols.length > IMAP.max_flag_count
raise FlagCountError, "number of flag symbols exceeded" raise FlagCountError, "number of flag symbols exceeded"

View file

@ -106,17 +106,17 @@ class PP < PrettyPrint
# and preserves the previous set of objects being printed. # and preserves the previous set of objects being printed.
def guard_inspect_key def guard_inspect_key
if Thread.current[:__recursive_key__] == nil if Thread.current[:__recursive_key__] == nil
Thread.current[:__recursive_key__] = {}.compare_by_identity.taint Thread.current[:__recursive_key__] = {}.compare_by_identity
end end
if Thread.current[:__recursive_key__][:inspect] == nil if Thread.current[:__recursive_key__][:inspect] == nil
Thread.current[:__recursive_key__][:inspect] = {}.compare_by_identity.taint Thread.current[:__recursive_key__][:inspect] = {}.compare_by_identity
end end
save = Thread.current[:__recursive_key__][:inspect] save = Thread.current[:__recursive_key__][:inspect]
begin begin
Thread.current[:__recursive_key__][:inspect] = {}.compare_by_identity.taint Thread.current[:__recursive_key__][:inspect] = {}.compare_by_identity
yield yield
ensure ensure
Thread.current[:__recursive_key__][:inspect] = save Thread.current[:__recursive_key__][:inspect] = save

View file

@ -194,15 +194,12 @@ class Resolv
line.sub!(/#.*/, '') line.sub!(/#.*/, '')
addr, hostname, *aliases = line.split(/\s+/) addr, hostname, *aliases = line.split(/\s+/)
next unless addr next unless addr
addr.untaint
hostname.untaint
@addr2name[addr] = [] unless @addr2name.include? addr @addr2name[addr] = [] unless @addr2name.include? addr
@addr2name[addr] << hostname @addr2name[addr] << hostname
@addr2name[addr] += aliases @addr2name[addr] += aliases
@name2addr[hostname] = [] unless @name2addr.include? hostname @name2addr[hostname] = [] unless @name2addr.include? hostname
@name2addr[hostname] << addr @name2addr[hostname] << addr
aliases.each {|n| aliases.each {|n|
n.untaint
@name2addr[n] = [] unless @name2addr.include? n @name2addr[n] = [] unless @name2addr.include? n
@name2addr[n] << addr @name2addr[n] << addr
} }
@ -964,7 +961,6 @@ class Resolv
f.each {|line| f.each {|line|
line.sub!(/[#;].*/, '') line.sub!(/[#;].*/, '')
keyword, *args = line.split(/\s+/) keyword, *args = line.split(/\s+/)
args.each(&:untaint)
next unless keyword next unless keyword
case keyword case keyword
when 'nameserver' when 'nameserver'

View file

@ -147,16 +147,6 @@ class Set
super super
end end
def taint # :nodoc:
@hash.taint
super
end
def untaint # :nodoc:
@hash.untaint
super
end
# Returns the number of elements. # Returns the number of elements.
def size def size
@hash.size @hash.size

View file

@ -58,10 +58,9 @@
# == Singleton and Marshal # == Singleton and Marshal
# #
# By default Singleton's #_dump(depth) returns the empty string. Marshalling by # By default Singleton's #_dump(depth) returns the empty string. Marshalling by
# default will strip state information, e.g. instance variables and taint # default will strip state information, e.g. instance variables from the instance.
# state, from the instance. Classes using Singleton can provide custom # Classes using Singleton can provide custom _load(str) and _dump(depth) methods
# _load(str) and _dump(depth) methods to retain some of the previous state of # to retain some of the previous state of the instance.
# the instance.
# #
# require 'singleton' # require 'singleton'
# #
@ -82,7 +81,6 @@
# a = Example.instance # a = Example.instance
# a.keep = "keep this" # a.keep = "keep this"
# a.strip = "get rid of this" # a.strip = "get rid of this"
# a.taint
# #
# stored_state = Marshal.dump(a) # stored_state = Marshal.dump(a)
# #

View file

@ -150,16 +150,12 @@ rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE (*dumper)(VALUE),
st_insert(compat_allocator_table(), (st_data_t)allocator, (st_data_t)compat); st_insert(compat_allocator_table(), (st_data_t)allocator, (st_data_t)compat);
} }
#define MARSHAL_INFECTION FL_TAINT
STATIC_ASSERT(marshal_infection_is_int, MARSHAL_INFECTION == (int)MARSHAL_INFECTION);
struct dump_arg { struct dump_arg {
VALUE str, dest; VALUE str, dest;
st_table *symbols; st_table *symbols;
st_table *data; st_table *data;
st_table *compat_tbl; st_table *compat_tbl;
st_table *encodings; st_table *encodings;
int infection;
}; };
struct dump_call_arg { struct dump_call_arg {
@ -268,7 +264,6 @@ w_nbyte(const char *s, long n, struct dump_arg *arg)
{ {
VALUE buf = arg->str; VALUE buf = arg->str;
rb_str_buf_cat(buf, s, n); rb_str_buf_cat(buf, s, n);
RBASIC(buf)->flags |= arg->infection;
if (arg->dest && RSTRING_LEN(buf) >= BUFSIZ) { if (arg->dest && RSTRING_LEN(buf) >= BUFSIZ) {
rb_io_write(arg->dest, buf); rb_io_write(arg->dest, buf);
rb_str_resize(buf, 0); rb_str_resize(buf, 0);
@ -770,8 +765,6 @@ w_object(VALUE obj, struct dump_arg *arg, int limit)
rb_builtin_type_name(BUILTIN_TYPE(obj))); rb_builtin_type_name(BUILTIN_TYPE(obj)));
} }
arg->infection |= (int)FL_TEST(obj, MARSHAL_INFECTION);
if (rb_obj_respond_to(obj, s_mdump, TRUE)) { if (rb_obj_respond_to(obj, s_mdump, TRUE)) {
st_add_direct(arg->data, obj, arg->data->num_entries); st_add_direct(arg->data, obj, arg->data->num_entries);
@ -1077,7 +1070,6 @@ rb_marshal_dump_limited(VALUE obj, VALUE port, int limit)
arg->dest = 0; arg->dest = 0;
arg->symbols = st_init_numtable(); arg->symbols = st_init_numtable();
arg->data = rb_init_identtable(); arg->data = rb_init_identtable();
arg->infection = 0;
arg->compat_tbl = 0; arg->compat_tbl = 0;
arg->encodings = 0; arg->encodings = 0;
arg->str = rb_str_buf_new(0); arg->str = rb_str_buf_new(0);
@ -1116,7 +1108,6 @@ struct load_arg {
st_table *data; st_table *data;
VALUE proc; VALUE proc;
st_table *compat_tbl; st_table *compat_tbl;
int infection;
}; };
static VALUE static VALUE
@ -1195,7 +1186,6 @@ r_byte1_buffered(struct load_arg *arg)
str = load_funcall(arg, arg->src, s_read, 1, &n); str = load_funcall(arg, arg->src, s_read, 1, &n);
if (NIL_P(str)) too_short(); if (NIL_P(str)) too_short();
StringValue(str); StringValue(str);
arg->infection |= (int)FL_TEST(str, MARSHAL_INFECTION);
memcpy(arg->buf, RSTRING_PTR(str), RSTRING_LEN(str)); memcpy(arg->buf, RSTRING_PTR(str), RSTRING_LEN(str));
arg->offset = 0; arg->offset = 0;
arg->buflen = RSTRING_LEN(str); arg->buflen = RSTRING_LEN(str);
@ -1294,7 +1284,6 @@ r_bytes1(long len, struct load_arg *arg)
if (NIL_P(str)) too_short(); if (NIL_P(str)) too_short();
StringValue(str); StringValue(str);
if (RSTRING_LEN(str) != len) too_short(); if (RSTRING_LEN(str) != len) too_short();
arg->infection |= (int)FL_TEST(str, MARSHAL_INFECTION);
return str; return str;
} }
@ -1325,7 +1314,6 @@ r_bytes1_buffered(long len, struct load_arg *arg)
tmp_len = RSTRING_LEN(tmp); tmp_len = RSTRING_LEN(tmp);
if (tmp_len < need_len) too_short(); if (tmp_len < need_len) too_short();
arg->infection |= (int)FL_TEST(tmp, MARSHAL_INFECTION);
str = rb_str_new(arg->buf+arg->offset, buflen); str = rb_str_new(arg->buf+arg->offset, buflen);
rb_str_cat(str, RSTRING_PTR(tmp), need_len); rb_str_cat(str, RSTRING_PTR(tmp), need_len);
@ -1472,12 +1460,6 @@ r_entry0(VALUE v, st_index_t num, struct load_arg *arg)
else { else {
st_insert(arg->data, num, (st_data_t)v); st_insert(arg->data, num, (st_data_t)v);
} }
if (arg->infection &&
!RB_TYPE_P(v, T_CLASS) && !RB_TYPE_P(v, T_MODULE)) {
OBJ_TAINT(v);
if ((VALUE)real_obj != Qundef)
OBJ_TAINT((VALUE)real_obj);
}
return v; return v;
} }
@ -2117,25 +2099,22 @@ marshal_load(int argc, VALUE *argv, VALUE _)
VALUE VALUE
rb_marshal_load_with_proc(VALUE port, VALUE proc) rb_marshal_load_with_proc(VALUE port, VALUE proc)
{ {
int major, minor, infection = 0; int major, minor;
VALUE v; VALUE v;
VALUE wrapper; /* used to avoid memory leak in case of exception */ VALUE wrapper; /* used to avoid memory leak in case of exception */
struct load_arg *arg; struct load_arg *arg;
v = rb_check_string_type(port); v = rb_check_string_type(port);
if (!NIL_P(v)) { if (!NIL_P(v)) {
infection = (int)FL_TEST(port, MARSHAL_INFECTION); /* original taintedness */
port = v; port = v;
} }
else if (rb_respond_to(port, s_getbyte) && rb_respond_to(port, s_read)) { else if (rb_respond_to(port, s_getbyte) && rb_respond_to(port, s_read)) {
rb_check_funcall(port, s_binmode, 0, 0); rb_check_funcall(port, s_binmode, 0, 0);
infection = (int)FL_TAINT;
} }
else { else {
io_needed(); io_needed();
} }
wrapper = TypedData_Make_Struct(0, struct load_arg, &load_arg_data, arg); wrapper = TypedData_Make_Struct(0, struct load_arg, &load_arg_data, arg);
arg->infection = infection;
arg->src = port; arg->src = port;
arg->offset = 0; arg->offset = 0;
arg->symbols = st_init_numtable(); arg->symbols = st_init_numtable();

2
node.h
View file

@ -175,7 +175,7 @@ typedef struct RNode {
#define RNODE(obj) (R_CAST(RNode)(obj)) #define RNODE(obj) (R_CAST(RNode)(obj))
/* FL : 0..4: T_TYPES, 5: KEEP_WB, 6: PROMOTED, 7: FINALIZE, 8: TAINT, 9: UNTRUSTED, 10: EXIVAR, 11: FREEZE */ /* FL : 0..4: T_TYPES, 5: KEEP_WB, 6: PROMOTED, 7: FINALIZE, 8: UNUSED, 9: UNUSED, 10: EXIVAR, 11: FREEZE */
/* NODE_FL: 0..4: T_TYPES, 5: KEEP_WB, 6: PROMOTED, 7: NODE_FL_NEWLINE, /* NODE_FL: 0..4: T_TYPES, 5: KEEP_WB, 6: PROMOTED, 7: NODE_FL_NEWLINE,
* 8..14: nd_type, * 8..14: nd_type,
* 15..: nd_line * 15..: nd_line

122
object.c
View file

@ -346,7 +346,7 @@ init_copy(VALUE dest, VALUE obj)
rb_raise(rb_eTypeError, "[bug] frozen object (%s) allocated", rb_obj_classname(dest)); rb_raise(rb_eTypeError, "[bug] frozen object (%s) allocated", rb_obj_classname(dest));
} }
RBASIC(dest)->flags &= ~(T_MASK|FL_EXIVAR); 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);
rb_copy_wb_protected_attribute(dest, obj); rb_copy_wb_protected_attribute(dest, obj);
rb_copy_generic_ivar(dest, obj); rb_copy_generic_ivar(dest, obj);
rb_gc_copy_finalizer(dest, obj); rb_gc_copy_finalizer(dest, obj);
@ -383,7 +383,7 @@ special_object_p(VALUE obj)
* Produces a shallow copy of <i>obj</i>---the instance variables of * Produces a shallow copy of <i>obj</i>---the instance variables of
* <i>obj</i> are copied, but not the objects they reference. * <i>obj</i> are copied, but not the objects they reference.
* #clone copies the frozen (unless +:freeze+ keyword argument is * #clone copies the frozen (unless +:freeze+ keyword argument is
* given with a false value) and tainted state of <i>obj</i>. See * given with a false value) state of <i>obj</i>. See
* also the discussion under Object#dup. * also the discussion under Object#dup.
* *
* class Klass * class Klass
@ -491,7 +491,6 @@ rb_obj_clone(VALUE obj)
* *
* Produces a shallow copy of <i>obj</i>---the instance variables of * Produces a shallow copy of <i>obj</i>---the instance variables of
* <i>obj</i> are copied, but not the objects they reference. * <i>obj</i> are copied, but not the objects they reference.
* #dup copies the tainted state of <i>obj</i>.
* *
* This method may have class-specific behavior. If so, that * This method may have class-specific behavior. If so, that
* behavior will be documented under the #+initialize_copy+ method of * behavior will be documented under the #+initialize_copy+ method of
@ -616,7 +615,6 @@ rb_obj_init_copy(VALUE obj, VALUE orig)
{ {
if (obj == orig) return obj; if (obj == orig) return obj;
rb_check_frozen(obj); rb_check_frozen(obj);
rb_check_trusted(obj);
if (TYPE(obj) != TYPE(orig) || rb_obj_class(obj) != rb_obj_class(orig)) { if (TYPE(obj) != TYPE(orig) || rb_obj_class(obj) != rb_obj_class(orig)) {
rb_raise(rb_eTypeError, "initialize_copy should take same class object"); rb_raise(rb_eTypeError, "initialize_copy should take same class object");
} }
@ -659,7 +657,6 @@ rb_any_to_s(VALUE obj)
VALUE cname = rb_class_name(CLASS_OF(obj)); VALUE cname = rb_class_name(CLASS_OF(obj));
str = rb_sprintf("#<%"PRIsVALUE":%p>", cname, (void*)obj); str = rb_sprintf("#<%"PRIsVALUE":%p>", cname, (void*)obj);
OBJ_INFECT(str, obj);
return str; return str;
} }
@ -728,7 +725,6 @@ inspect_obj(VALUE obj, VALUE str, int recur)
} }
rb_str_cat2(str, ">"); rb_str_cat2(str, ">");
RSTRING_PTR(str)[0] = '#'; RSTRING_PTR(str)[0] = '#';
OBJ_INFECT(str, obj);
return str; return str;
} }
@ -1164,26 +1160,15 @@ rb_obj_dummy1(VALUE _x, VALUE _y)
/** /**
* call-seq: * call-seq:
* obj.tainted? -> true or false * obj.tainted? -> false
* *
* Returns true if the object is tainted. * Returns false. This method is deprecated and will be removed in Ruby 3.2.
*
* See #taint for more information.
*--
* Determines if \a obj is tainted. Equivalent to \c Object\#tainted? in Ruby.
* \param[in] obj the object to be determined
* \retval Qtrue if the object is tainted
* \retval Qfalse if the object is not tainted
* \sa rb_obj_taint
* \sa rb_obj_untaint
*++
*/ */
VALUE VALUE
rb_obj_tainted(VALUE obj) rb_obj_tainted(VALUE obj)
{ {
if (OBJ_TAINTED(obj)) rb_warning("Object#tainted? is deprecated and will be removed in Ruby 3.2.");
return Qtrue;
return Qfalse; return Qfalse;
} }
@ -1191,33 +1176,13 @@ rb_obj_tainted(VALUE obj)
* call-seq: * call-seq:
* obj.taint -> obj * obj.taint -> obj
* *
* Mark the object as tainted. * Returns object. This method is deprecated and will be removed in Ruby 3.2.
*
* Objects that are marked as tainted will be restricted from various built-in
* methods. This is to prevent insecure data, such as command-line arguments
* or strings read from Kernel#gets, from inadvertently compromising the user's
* system.
*
* To check whether an object is tainted, use #tainted?.
*
* You should only untaint a tainted object if your code has inspected it and
* determined that it is safe. To do so use #untaint.
*--
* Marks the object as tainted. Equivalent to \c Object\#taint in Ruby
* \param[in] obj the object to be tainted
* \return the object itself
* \sa rb_obj_untaint
* \sa rb_obj_tainted
*++
*/ */
VALUE VALUE
rb_obj_taint(VALUE obj) rb_obj_taint(VALUE obj)
{ {
if (!OBJ_TAINTED(obj) && OBJ_TAINTABLE(obj)) { rb_warning("Object#taint is deprecated and will be removed in Ruby 3.2.");
rb_check_frozen(obj);
OBJ_TAINT(obj);
}
return obj; return obj;
} }
@ -1226,74 +1191,42 @@ rb_obj_taint(VALUE obj)
* call-seq: * call-seq:
* obj.untaint -> obj * obj.untaint -> obj
* *
* Removes the tainted mark from the object. * Returns object. This method is deprecated and will be removed in Ruby 3.2.
*
* See #taint for more information.
*--
* Removes the tainted mark from the object.
* Equivalent to \c Object\#untaint in Ruby.
*
* \param[in] obj the object to be tainted
* \return the object itself
* \sa rb_obj_taint
* \sa rb_obj_tainted
*++
*/ */
VALUE VALUE
rb_obj_untaint(VALUE obj) rb_obj_untaint(VALUE obj)
{ {
if (OBJ_TAINTED(obj)) { rb_warning("Object#untaint is deprecated and will be removed in Ruby 3.2.");
rb_check_frozen(obj);
FL_UNSET(obj, FL_TAINT);
}
return obj; return obj;
} }
/** /**
* call-seq: * call-seq:
* obj.untrusted? -> true or false * obj.untrusted? -> false
* *
* Deprecated method that is equivalent to #tainted?. * Returns false. This method is deprecated and will be removed in Ruby 3.2.
*--
* \deprecated Use rb_obj_tainted.
*
* Trustiness used to have independent semantics from taintedness.
* But now trustiness of objects is obsolete and this function behaves
* the same as rb_obj_tainted.
*
* \sa rb_obj_tainted
*++
*/ */
VALUE VALUE
rb_obj_untrusted(VALUE obj) rb_obj_untrusted(VALUE obj)
{ {
rb_warning("untrusted? is deprecated and its behavior is same as tainted?"); rb_warning("Object#untrusted? is deprecated and will be removed in Ruby 3.2.");
return rb_obj_tainted(obj); return Qfalse;
} }
/** /**
* call-seq: * call-seq:
* obj.untrust -> obj * obj.untrust -> obj
* *
* Deprecated method that is equivalent to #taint. * Returns object. This method is deprecated and will be removed in Ruby 3.2.
*--
* \deprecated Use rb_obj_taint(obj)
*
* Trustiness used to have independent semantics from taintedness.
* But now trustiness of objects is obsolete and this function behaves
* the same as rb_obj_taint.
*
* \sa rb_obj_taint
*++
*/ */
VALUE VALUE
rb_obj_untrust(VALUE obj) rb_obj_untrust(VALUE obj)
{ {
rb_warning("untrust is deprecated and its behavior is same as taint"); rb_warning("Object#untrust is deprecated and will be removed in Ruby 3.2.");
return rb_obj_taint(obj); return obj;
} }
@ -1301,37 +1234,24 @@ rb_obj_untrust(VALUE obj)
* call-seq: * call-seq:
* obj.trust -> obj * obj.trust -> obj
* *
* Deprecated method that is equivalent to #untaint. * Returns object. This method is deprecated and will be removed in Ruby 3.2.
*--
* \deprecated Use rb_obj_untaint(obj)
*
* Trustiness used to have independent semantics from taintedness.
* But now trustiness of objects is obsolete and this function behaves
* the same as rb_obj_untaint.
*
* \sa rb_obj_untaint
*++
*/ */
VALUE VALUE
rb_obj_trust(VALUE obj) rb_obj_trust(VALUE obj)
{ {
rb_warning("trust is deprecated and its behavior is same as untaint"); rb_warning("Object#trust is deprecated and will be removed in Ruby 3.2.");
return rb_obj_untaint(obj); return obj;
} }
/** /**
* Convenient function to infect \a victim with the taintedness of \a carrier. * Does nothing. This method is deprecated and will be removed in Ruby 3.2.
*
* It just keeps the taintedness of \a victim if \a carrier is not tainted.
* \param[in,out] victim the object being infected with the taintness of \a carrier
* \param[in] carrier a possibly tainted object
*/ */
void void
rb_obj_infect(VALUE victim, VALUE carrier) rb_obj_infect(VALUE victim, VALUE carrier)
{ {
OBJ_INFECT(victim, carrier); rb_warning("rb_obj_infect is deprecated and will be removed in Ruby 3.2.");
} }
/** /**

33
pack.c
View file

@ -296,7 +296,6 @@ pack_pack(rb_execution_context_t *ec, VALUE ary, VALUE fmt, VALUE buffer)
StringValue(from); StringValue(from);
ptr = RSTRING_PTR(from); ptr = RSTRING_PTR(from);
plen = RSTRING_LEN(from); plen = RSTRING_LEN(from);
OBJ_INFECT(res, from);
} }
if (p[-1] == '*') if (p[-1] == '*')
@ -657,7 +656,6 @@ pack_pack(rb_execution_context_t *ec, VALUE ary, VALUE fmt, VALUE buffer)
StringValue(from); StringValue(from);
ptr = RSTRING_PTR(from); ptr = RSTRING_PTR(from);
plen = RSTRING_LEN(from); plen = RSTRING_LEN(from);
OBJ_INFECT(res, from);
if (len == 0 && type == 'm') { if (len == 0 && type == 'm') {
encodes(res, ptr, plen, type, 0); encodes(res, ptr, plen, type, 0);
@ -685,7 +683,6 @@ pack_pack(rb_execution_context_t *ec, VALUE ary, VALUE fmt, VALUE buffer)
case 'M': /* quoted-printable encoded string */ case 'M': /* quoted-printable encoded string */
from = rb_obj_as_string(NEXTFROM); from = rb_obj_as_string(NEXTFROM);
OBJ_INFECT(res, from);
if (len <= 1) if (len <= 1)
len = 72; len = 72;
qpencode(res, from, len); qpencode(res, from, len);
@ -711,8 +708,6 @@ pack_pack(rb_execution_context_t *ec, VALUE ary, VALUE fmt, VALUE buffer)
} }
else { else {
t = StringValuePtr(from); t = StringValuePtr(from);
OBJ_INFECT(res, from);
rb_obj_taint(from);
} }
if (!associates) { if (!associates) {
associates = rb_ary_new(); associates = rb_ary_new();
@ -764,7 +759,6 @@ pack_pack(rb_execution_context_t *ec, VALUE ary, VALUE fmt, VALUE buffer)
if (associates) { if (associates) {
str_associate(res, associates); str_associate(res, associates);
} }
OBJ_INFECT(res, fmt);
switch (enc_info) { switch (enc_info) {
case 1: case 1:
ENCODING_CODERANGE_SET(res, rb_usascii_encindex(), ENC_CODERANGE_7BIT); ENCODING_CODERANGE_SET(res, rb_usascii_encindex(), ENC_CODERANGE_7BIT);
@ -923,15 +917,6 @@ hex2num(char c)
# define AVOID_CC_BUG # define AVOID_CC_BUG
#endif #endif
static VALUE
infected_str_new(const char *ptr, long len, VALUE str)
{
VALUE s = rb_str_new(ptr, len);
OBJ_INFECT(s, str);
return s;
}
/* unpack mode */ /* unpack mode */
#define UNPACK_ARRAY 0 #define UNPACK_ARRAY 0
#define UNPACK_BLOCK 1 #define UNPACK_BLOCK 1
@ -1052,7 +1037,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
if (*t != ' ' && *t != '\0') break; if (*t != ' ' && *t != '\0') break;
t--; len--; t--; len--;
} }
UNPACK_PUSH(infected_str_new(s, len, str)); UNPACK_PUSH(rb_str_new(s, len));
s += end; s += end;
} }
break; break;
@ -1063,7 +1048,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
if (len > send-s) len = send-s; if (len > send-s) len = send-s;
while (t < s+len && *t) t++; while (t < s+len && *t) t++;
UNPACK_PUSH(infected_str_new(s, t-s, str)); UNPACK_PUSH(rb_str_new(s, t-s));
if (t < send) t++; if (t < send) t++;
s = star ? t : s+len; s = star ? t : s+len;
} }
@ -1071,7 +1056,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
case 'a': case 'a':
if (len > send - s) len = send - s; if (len > send - s) len = send - s;
UNPACK_PUSH(infected_str_new(s, len, str)); UNPACK_PUSH(rb_str_new(s, len));
s += len; s += len;
break; break;
@ -1086,7 +1071,6 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
len = (send - s) * 8; len = (send - s) * 8;
bits = 0; bits = 0;
bitstr = rb_usascii_str_new(0, len); bitstr = rb_usascii_str_new(0, len);
OBJ_INFECT(bitstr, str);
t = RSTRING_PTR(bitstr); t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
if (i & 7) bits >>= 1; if (i & 7) bits >>= 1;
@ -1108,7 +1092,6 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
len = (send - s) * 8; len = (send - s) * 8;
bits = 0; bits = 0;
bitstr = rb_usascii_str_new(0, len); bitstr = rb_usascii_str_new(0, len);
OBJ_INFECT(bitstr, str);
t = RSTRING_PTR(bitstr); t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
if (i & 7) bits <<= 1; if (i & 7) bits <<= 1;
@ -1130,7 +1113,6 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
len = (send - s) * 2; len = (send - s) * 2;
bits = 0; bits = 0;
bitstr = rb_usascii_str_new(0, len); bitstr = rb_usascii_str_new(0, len);
OBJ_INFECT(bitstr, str);
t = RSTRING_PTR(bitstr); t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
if (i & 1) if (i & 1)
@ -1154,7 +1136,6 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
len = (send - s) * 2; len = (send - s) * 2;
bits = 0; bits = 0;
bitstr = rb_usascii_str_new(0, len); bitstr = rb_usascii_str_new(0, len);
OBJ_INFECT(bitstr, str);
t = RSTRING_PTR(bitstr); t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
if (i & 1) if (i & 1)
@ -1366,7 +1347,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
case 'u': case 'u':
{ {
VALUE buf = infected_str_new(0, (send - s)*3/4, str); VALUE buf = rb_str_new(0, (send - s)*3/4);
char *ptr = RSTRING_PTR(buf); char *ptr = RSTRING_PTR(buf);
long total = 0; long total = 0;
@ -1421,7 +1402,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
case 'm': case 'm':
{ {
VALUE buf = infected_str_new(0, (send - s + 3)*3/4, str); /* +3 is for skipping paddings */ VALUE buf = rb_str_new(0, (send - s + 3)*3/4); /* +3 is for skipping paddings */
char *ptr = RSTRING_PTR(buf); char *ptr = RSTRING_PTR(buf);
int a = -1,b = -1,c = 0,d = 0; int a = -1,b = -1,c = 0,d = 0;
static signed char b64_xtable[256]; static signed char b64_xtable[256];
@ -1502,7 +1483,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
case 'M': case 'M':
{ {
VALUE buf = infected_str_new(0, send - s, str); VALUE buf = rb_str_new(0, send - s);
char *ptr = RSTRING_PTR(buf), *ss = s; char *ptr = RSTRING_PTR(buf), *ss = s;
int csum = 0; int csum = 0;
int c1, c2; int c1, c2;
@ -1571,7 +1552,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
while (p < pend) { while (p < pend) {
if (RB_TYPE_P(*p, T_STRING) && RSTRING_PTR(*p) == t) { if (RB_TYPE_P(*p, T_STRING) && RSTRING_PTR(*p) == t) {
if (len < RSTRING_LEN(*p)) { if (len < RSTRING_LEN(*p)) {
tmp = rb_tainted_str_new(t, len); tmp = rb_str_new(t, len);
str_associate(tmp, a); str_associate(tmp, a);
} }
else { else {

6
proc.c
View file

@ -1377,7 +1377,6 @@ rb_block_to_s(VALUE self, const struct rb_block *block, const char *additional_i
if (additional_info) rb_str_cat_cstr(str, additional_info); if (additional_info) rb_str_cat_cstr(str, additional_info);
rb_str_cat_cstr(str, ">"); rb_str_cat_cstr(str, ">");
OBJ_INFECT_RAW(str, self);
return str; return str;
} }
@ -1490,8 +1489,6 @@ mnew_missing(VALUE klass, VALUE obj, ID id, VALUE mclass)
RB_OBJ_WRITE(method, &data->me, me); RB_OBJ_WRITE(method, &data->me, me);
OBJ_INFECT(method, klass);
return method; return method;
} }
@ -1548,7 +1545,6 @@ mnew_internal(const rb_method_entry_t *me, VALUE klass, VALUE iclass,
RB_OBJ_WRITE(method, &data->iclass, iclass); RB_OBJ_WRITE(method, &data->iclass, iclass);
RB_OBJ_WRITE(method, &data->me, me); RB_OBJ_WRITE(method, &data->me, me);
OBJ_INFECT(method, klass);
return method; return method;
} }
@ -1691,7 +1687,6 @@ method_unbind(VALUE obj)
RB_OBJ_WRITE(method, &data->recv, Qundef); RB_OBJ_WRITE(method, &data->recv, Qundef);
RB_OBJ_WRITE(method, &data->klass, orig->klass); RB_OBJ_WRITE(method, &data->klass, orig->klass);
RB_OBJ_WRITE(method, &data->me, rb_method_entry_clone(orig->me)); RB_OBJ_WRITE(method, &data->me, rb_method_entry_clone(orig->me));
OBJ_INFECT(method, obj);
return method; return method;
} }
@ -2775,7 +2770,6 @@ method_inspect(VALUE method)
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
str = rb_sprintf("#<% "PRIsVALUE": ", rb_obj_class(method)); str = rb_sprintf("#<% "PRIsVALUE": ", rb_obj_class(method));
OBJ_INFECT_RAW(str, method);
mklass = data->klass; mklass = data->klass;

View file

@ -1325,7 +1325,6 @@ range_to_s(VALUE range)
str = rb_str_dup(str); str = rb_str_dup(str);
rb_str_cat(str, "...", EXCL(range) ? 3 : 2); rb_str_cat(str, "...", EXCL(range) ? 3 : 2);
rb_str_append(str, str2); rb_str_append(str, str2);
OBJ_INFECT(str, range);
return str; return str;
} }
@ -1349,7 +1348,6 @@ inspect_range(VALUE range, VALUE dummy, int recur)
str2 = rb_inspect(RANGE_END(range)); str2 = rb_inspect(RANGE_END(range));
} }
if (str2 != Qundef) rb_str_append(str, str2); if (str2 != Qundef) rb_str_append(str, str2);
OBJ_INFECT(str, range);
return str; return str;
} }

View file

@ -1853,7 +1853,6 @@ nurat_marshal_load(VALUE self, VALUE a)
VALUE num, den; VALUE num, den;
rb_check_frozen(self); rb_check_frozen(self);
rb_check_trusted(self);
Check_Type(a, T_ARRAY); Check_Type(a, T_ARRAY);
if (RARRAY_LEN(a) != 2) if (RARRAY_LEN(a) != 2)

25
re.c
View file

@ -462,7 +462,6 @@ rb_reg_desc(const char *s, long len, VALUE re)
if (RBASIC(re)->flags & REG_ENCODING_NONE) if (RBASIC(re)->flags & REG_ENCODING_NONE)
rb_str_buf_cat2(str, "n"); rb_str_buf_cat2(str, "n");
} }
OBJ_INFECT(str, re);
return str; return str;
} }
@ -488,7 +487,6 @@ rb_reg_source(VALUE re)
rb_reg_check(re); rb_reg_check(re);
str = rb_str_dup(RREGEXP_SRC(re)); str = rb_str_dup(RREGEXP_SRC(re));
if (OBJ_TAINTED(re)) OBJ_TAINT(str);
return str; return str;
} }
@ -647,7 +645,6 @@ rb_reg_str_with_term(VALUE re, int term)
} }
rb_enc_copy(str, re); rb_enc_copy(str, re);
OBJ_INFECT(str, re);
return str; return str;
} }
@ -1337,7 +1334,6 @@ match_set_string(VALUE m, VALUE string, long pos, long len)
if (err) rb_memerror(); if (err) rb_memerror();
rmatch->regs.beg[0] = pos; rmatch->regs.beg[0] = pos;
rmatch->regs.end[0] = pos + len; rmatch->regs.end[0] = pos + len;
OBJ_INFECT(match, string);
} }
void void
@ -1601,20 +1597,14 @@ rb_reg_search0(VALUE re, VALUE str, long pos, int reverse, int set_backref_str)
onig_region_free(regs, 0); onig_region_free(regs, 0);
if (err) rb_memerror(); if (err) rb_memerror();
} }
else {
FL_UNSET(match, FL_TAINT);
}
if (set_backref_str) { if (set_backref_str) {
RMATCH(match)->str = rb_str_new4(str); RMATCH(match)->str = rb_str_new4(str);
OBJ_INFECT(match, str);
} }
RMATCH(match)->regexp = re; RMATCH(match)->regexp = re;
rb_backref_set(match); rb_backref_set(match);
OBJ_INFECT(match, re);
return result; return result;
} }
@ -1685,18 +1675,12 @@ rb_reg_start_with_p(VALUE re, VALUE str)
onig_region_free(regs, 0); onig_region_free(regs, 0);
if (err) rb_memerror(); if (err) rb_memerror();
} }
else {
FL_UNSET(match, FL_TAINT);
}
RMATCH(match)->str = rb_str_new4(str); RMATCH(match)->str = rb_str_new4(str);
OBJ_INFECT(match, str);
RMATCH(match)->regexp = re; RMATCH(match)->regexp = re;
rb_backref_set(match); rb_backref_set(match);
OBJ_INFECT(match, re);
return true; return true;
} }
@ -1740,7 +1724,6 @@ rb_reg_nth_match(int nth, VALUE match)
end = END(nth); end = END(nth);
len = end - start; len = end - start;
str = rb_str_subseq(RMATCH(match)->str, start, len); str = rb_str_subseq(RMATCH(match)->str, start, len);
OBJ_INFECT(str, match);
return str; return str;
} }
@ -1773,7 +1756,6 @@ rb_reg_match_pre(VALUE match)
regs = RMATCH_REGS(match); regs = RMATCH_REGS(match);
if (BEG(0) == -1) return Qnil; if (BEG(0) == -1) return Qnil;
str = rb_str_subseq(RMATCH(match)->str, 0, BEG(0)); str = rb_str_subseq(RMATCH(match)->str, 0, BEG(0));
if (OBJ_TAINTED(match)) OBJ_TAINT(str);
return str; return str;
} }
@ -1803,7 +1785,6 @@ rb_reg_match_post(VALUE match)
str = RMATCH(match)->str; str = RMATCH(match)->str;
pos = END(0); pos = END(0);
str = rb_str_subseq(str, pos, RSTRING_LEN(str) - pos); str = rb_str_subseq(str, pos, RSTRING_LEN(str) - pos);
if (OBJ_TAINTED(match)) OBJ_TAINT(str);
return str; return str;
} }
@ -1855,7 +1836,6 @@ match_array(VALUE match, int start)
VALUE ary; VALUE ary;
VALUE target; VALUE target;
int i; int i;
int taint = OBJ_TAINTED(match);
match_check(match); match_check(match);
regs = RMATCH_REGS(match); regs = RMATCH_REGS(match);
@ -1868,7 +1848,6 @@ match_array(VALUE match, int start)
} }
else { else {
VALUE str = rb_str_subseq(target, regs->beg[i], regs->end[i]-regs->beg[i]); VALUE str = rb_str_subseq(target, regs->beg[i], regs->end[i]-regs->beg[i]);
if (taint) OBJ_TAINT(str);
rb_ary_push(ary, str); rb_ary_push(ary, str);
} }
} }
@ -2129,8 +2108,6 @@ match_to_s(VALUE match)
match_check(match); match_check(match);
if (NIL_P(str)) str = rb_str_new(0,0); if (NIL_P(str)) str = rb_str_new(0,0);
if (OBJ_TAINTED(match)) OBJ_TAINT(str);
if (OBJ_TAINTED(RMATCH(match)->str)) OBJ_TAINT(str);
return str; return str;
} }
@ -2891,7 +2868,6 @@ rb_reg_initialize_str(VALUE obj, VALUE str, int options, onig_errmsg_buffer err,
} }
ret = rb_reg_initialize(obj, RSTRING_PTR(str), RSTRING_LEN(str), enc, ret = rb_reg_initialize(obj, RSTRING_PTR(str), RSTRING_LEN(str), enc,
options, err, sourcefile, sourceline); options, err, sourcefile, sourceline);
OBJ_INFECT(obj, str);
if (ret == 0) reg_set_source(obj, str, str_enc); if (ret == 0) reg_set_source(obj, str, str_enc);
return ret; return ret;
} }
@ -3580,7 +3556,6 @@ rb_reg_quote(VALUE str)
t += rb_enc_mbcput(c, t, enc); t += rb_enc_mbcput(c, t, enc);
} }
rb_str_resize(tmp, t - RSTRING_PTR(tmp)); rb_str_resize(tmp, t - RSTRING_PTR(tmp));
OBJ_INFECT(tmp, str);
return tmp; return tmp;
} }

1
ruby.c
View file

@ -2227,7 +2227,6 @@ external_str_new_cstr(const char *p)
#if UTF8_PATH #if UTF8_PATH
VALUE str = rb_utf8_str_new_cstr(p); VALUE str = rb_utf8_str_new_cstr(p);
str = str_conv_enc(str, NULL, rb_default_external_encoding()); str = str_conv_enc(str, NULL, rb_default_external_encoding());
OBJ_TAINT_RAW(str);
return str; return str;
#else #else
return rb_external_str_new_cstr(p); return rb_external_str_new_cstr(p);

8
safe.c
View file

@ -9,11 +9,6 @@
**********************************************************************/ **********************************************************************/
/* safe-level:
0 - strings from streams/environment/ARGV are tainted (default)
1 - no dangerous operation by tainted value
*/
#define SAFE_LEVEL_MAX RUBY_SAFE_LEVEL_MAX #define SAFE_LEVEL_MAX RUBY_SAFE_LEVEL_MAX
#include "ruby/ruby.h" #include "ruby/ruby.h"
@ -141,9 +136,6 @@ void
rb_check_safe_obj(VALUE x) rb_check_safe_obj(VALUE x)
{ {
rb_warn("rb_check_safe_obj will be removed in Ruby 3.0"); rb_warn("rb_check_safe_obj will be removed in Ruby 3.0");
if (rb_safe_level() > 0 && OBJ_TAINTED(x)) {
rb_insecure_operation();
}
} }
void void

View file

@ -1195,7 +1195,7 @@ trap_handler(VALUE *cmd, int sig)
if (!NIL_P(command)) { if (!NIL_P(command)) {
const char *cptr; const char *cptr;
long len; long len;
SafeStringValue(command); /* taint check */ StringValue(command);
*cmd = command; *cmd = command;
RSTRING_GETMEM(command, cptr, len); RSTRING_GETMEM(command, cptr, len);
switch (len) { switch (len) {
@ -1393,10 +1393,6 @@ sig_trap(int argc, VALUE *argv, VALUE _)
func = trap_handler(&cmd, sig); func = trap_handler(&cmd, sig);
} }
if (OBJ_TAINTED(cmd)) {
rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
}
return trap(sig, func, cmd); return trap(sig, func, cmd);
} }

View file

@ -20,24 +20,28 @@ describe "Array#clear" do
a.size.should == 0 a.size.should == 0
end end
it "keeps tainted status" do ruby_version_is ''...'2.7' do
a = [1] it "keeps tainted status" do
a.taint a = [1]
a.tainted?.should be_true a.taint
a.clear a.tainted?.should be_true
a.tainted?.should be_true a.clear
a.tainted?.should be_true
end
end end
it "does not accept any arguments" do it "does not accept any arguments" do
-> { [1].clear(true) }.should raise_error(ArgumentError) -> { [1].clear(true) }.should raise_error(ArgumentError)
end end
it "keeps untrusted status" do ruby_version_is ''...'2.7' do
a = [1] it "keeps untrusted status" do
a.untrust a = [1]
a.untrusted?.should be_true a.untrust
a.clear a.untrusted?.should be_true
a.untrusted?.should be_true a.clear
a.untrusted?.should be_true
end
end end
it "raises a #{frozen_error_class} on a frozen array" do it "raises a #{frozen_error_class} on a frozen array" do

View file

@ -22,16 +22,18 @@ describe "Array#compact" do
ArraySpecs::MyArray[1, 2, 3, nil].compact.should be_an_instance_of(Array) ArraySpecs::MyArray[1, 2, 3, nil].compact.should be_an_instance_of(Array)
end end
it "does not keep tainted status even if all elements are removed" do ruby_version_is ''...'2.7' do
a = [nil, nil] it "does not keep tainted status even if all elements are removed" do
a.taint a = [nil, nil]
a.compact.tainted?.should be_false a.taint
end a.compact.tainted?.should be_false
end
it "does not keep untrusted status even if all elements are removed" do it "does not keep untrusted status even if all elements are removed" do
a = [nil, nil] a = [nil, nil]
a.untrust a.untrust
a.compact.untrusted?.should be_false a.compact.untrusted?.should be_false
end
end end
end end
@ -57,18 +59,20 @@ describe "Array#compact!" do
[1, 2, false, 3].compact!.should == nil [1, 2, false, 3].compact!.should == nil
end end
it "keeps tainted status even if all elements are removed" do ruby_version_is ''...'2.7' do
a = [nil, nil] it "keeps tainted status even if all elements are removed" do
a.taint a = [nil, nil]
a.compact! a.taint
a.tainted?.should be_true a.compact!
end a.tainted?.should be_true
end
it "keeps untrusted status even if all elements are removed" do it "keeps untrusted status even if all elements are removed" do
a = [nil, nil] a = [nil, nil]
a.untrust a.untrust
a.compact! a.compact!
a.untrusted?.should be_true a.untrusted?.should be_true
end
end end
it "raises a #{frozen_error_class} on a frozen array" do it "raises a #{frozen_error_class} on a frozen array" do

View file

@ -41,60 +41,62 @@ describe "Array#concat" do
-> { ArraySpecs.frozen_array.concat([]) }.should raise_error(frozen_error_class) -> { ArraySpecs.frozen_array.concat([]) }.should raise_error(frozen_error_class)
end end
it "keeps tainted status" do ruby_version_is ''...'2.7' do
ary = [1, 2] it "keeps tainted status" do
ary.taint ary = [1, 2]
ary.concat([3]) ary.taint
ary.tainted?.should be_true ary.concat([3])
ary.concat([]) ary.tainted?.should be_true
ary.tainted?.should be_true ary.concat([])
end ary.tainted?.should be_true
end
it "is not infected by the other" do it "is not infected by the other" do
ary = [1,2] ary = [1,2]
other = [3]; other.taint other = [3]; other.taint
ary.tainted?.should be_false ary.tainted?.should be_false
ary.concat(other) ary.concat(other)
ary.tainted?.should be_false ary.tainted?.should be_false
end end
it "keeps the tainted status of elements" do it "keeps the tainted status of elements" do
ary = [ Object.new, Object.new, Object.new ] ary = [ Object.new, Object.new, Object.new ]
ary.each {|x| x.taint } ary.each {|x| x.taint }
ary.concat([ Object.new ]) ary.concat([ Object.new ])
ary[0].tainted?.should be_true ary[0].tainted?.should be_true
ary[1].tainted?.should be_true ary[1].tainted?.should be_true
ary[2].tainted?.should be_true ary[2].tainted?.should be_true
ary[3].tainted?.should be_false ary[3].tainted?.should be_false
end end
it "keeps untrusted status" do it "keeps untrusted status" do
ary = [1, 2] ary = [1, 2]
ary.untrust ary.untrust
ary.concat([3]) ary.concat([3])
ary.untrusted?.should be_true ary.untrusted?.should be_true
ary.concat([]) ary.concat([])
ary.untrusted?.should be_true ary.untrusted?.should be_true
end end
it "is not infected untrustedness by the other" do it "is not infected untrustedness by the other" do
ary = [1,2] ary = [1,2]
other = [3]; other.untrust other = [3]; other.untrust
ary.untrusted?.should be_false ary.untrusted?.should be_false
ary.concat(other) ary.concat(other)
ary.untrusted?.should be_false ary.untrusted?.should be_false
end end
it "keeps the untrusted status of elements" do it "keeps the untrusted status of elements" do
ary = [ Object.new, Object.new, Object.new ] ary = [ Object.new, Object.new, Object.new ]
ary.each {|x| x.untrust } ary.each {|x| x.untrust }
ary.concat([ Object.new ]) ary.concat([ Object.new ])
ary[0].untrusted?.should be_true ary[0].untrusted?.should be_true
ary[1].untrusted?.should be_true ary[1].untrusted?.should be_true
ary[2].untrusted?.should be_true ary[2].untrusted?.should be_true
ary[3].untrusted?.should be_false ary[3].untrusted?.should be_false
end
end end
it "appends elements to an Array with enough capacity that has been shifted" do it "appends elements to an Array with enough capacity that has been shifted" do

View file

@ -39,23 +39,25 @@ describe "Array#delete_at" do
-> { [1,2,3].freeze.delete_at(0) }.should raise_error(frozen_error_class) -> { [1,2,3].freeze.delete_at(0) }.should raise_error(frozen_error_class)
end end
it "keeps tainted status" do ruby_version_is ''...'2.7' do
ary = [1, 2] it "keeps tainted status" do
ary.taint ary = [1, 2]
ary.tainted?.should be_true ary.taint
ary.delete_at(0) ary.tainted?.should be_true
ary.tainted?.should be_true ary.delete_at(0)
ary.delete_at(0) # now empty ary.tainted?.should be_true
ary.tainted?.should be_true ary.delete_at(0) # now empty
end ary.tainted?.should be_true
end
it "keeps untrusted status" do it "keeps untrusted status" do
ary = [1, 2] ary = [1, 2]
ary.untrust ary.untrust
ary.untrusted?.should be_true ary.untrusted?.should be_true
ary.delete_at(0) ary.delete_at(0)
ary.untrusted?.should be_true ary.untrusted?.should be_true
ary.delete_at(0) # now empty ary.delete_at(0) # now empty
ary.untrusted?.should be_true ary.untrusted?.should be_true
end
end end
end end

View file

@ -47,18 +47,20 @@ describe "Array#delete_if" do
-> { ArraySpecs.empty_frozen_array.delete_if {} }.should raise_error(frozen_error_class) -> { ArraySpecs.empty_frozen_array.delete_if {} }.should raise_error(frozen_error_class)
end end
it "keeps tainted status" do ruby_version_is ''...'2.7' do
@a.taint it "keeps tainted status" do
@a.tainted?.should be_true @a.taint
@a.delete_if{ true } @a.tainted?.should be_true
@a.tainted?.should be_true @a.delete_if{ true }
end @a.tainted?.should be_true
end
it "keeps untrusted status" do it "keeps untrusted status" do
@a.untrust @a.untrust
@a.untrusted?.should be_true @a.untrusted?.should be_true
@a.delete_if{ true } @a.delete_if{ true }
@a.untrusted?.should be_true @a.untrusted?.should be_true
end
end end
it_behaves_like :enumeratorized_with_origin_size, :delete_if, [1,2,3] it_behaves_like :enumeratorized_with_origin_size, :delete_if, [1,2,3]

View file

@ -44,23 +44,25 @@ describe "Array#delete" do
-> { [1, 2, 3].freeze.delete(1) }.should raise_error(frozen_error_class) -> { [1, 2, 3].freeze.delete(1) }.should raise_error(frozen_error_class)
end end
it "keeps tainted status" do ruby_version_is ''...'2.7' do
a = [1, 2] it "keeps tainted status" do
a.taint a = [1, 2]
a.tainted?.should be_true a.taint
a.delete(2) a.tainted?.should be_true
a.tainted?.should be_true a.delete(2)
a.delete(1) # now empty a.tainted?.should be_true
a.tainted?.should be_true a.delete(1) # now empty
end a.tainted?.should be_true
end
it "keeps untrusted status" do it "keeps untrusted status" do
a = [1, 2] a = [1, 2]
a.untrust a.untrust
a.untrusted?.should be_true a.untrusted?.should be_true
a.delete(2) a.delete(2)
a.untrusted?.should be_true a.untrusted?.should be_true
a.delete(1) # now empty a.delete(1) # now empty
a.untrusted?.should be_true a.untrusted?.should be_true
end
end end
end end

View file

@ -145,12 +145,14 @@ describe "Array#flatten" do
end end
end end
it "returns a tainted array if self is tainted" do ruby_version_is ''...'2.7' do
[].taint.flatten.tainted?.should be_true it "returns a tainted array if self is tainted" do
end [].taint.flatten.tainted?.should be_true
end
it "returns an untrusted array if self is untrusted" do it "returns an untrusted array if self is untrusted" do
[].untrust.flatten.untrusted?.should be_true [].untrust.flatten.untrusted?.should be_true
end
end end
it "performs respond_to? and method_missing-aware checks when coercing elements to array" do it "performs respond_to? and method_missing-aware checks when coercing elements to array" do

View file

@ -88,42 +88,44 @@ describe "Array#* with an integer" do
end end
end end
it "copies the taint status of the original array even if the passed count is 0" do ruby_version_is ''...'2.7' do
ary = [1, 2, 3] it "copies the taint status of the original array even if the passed count is 0" do
ary.taint ary = [1, 2, 3]
(ary * 0).tainted?.should == true ary.taint
end (ary * 0).tainted?.should == true
end
it "copies the taint status of the original array even if the array is empty" do it "copies the taint status of the original array even if the array is empty" do
ary = [] ary = []
ary.taint ary.taint
(ary * 3).tainted?.should == true (ary * 3).tainted?.should == true
end end
it "copies the taint status of the original array if the passed count is not 0" do it "copies the taint status of the original array if the passed count is not 0" do
ary = [1, 2, 3] ary = [1, 2, 3]
ary.taint ary.taint
(ary * 1).tainted?.should == true (ary * 1).tainted?.should == true
(ary * 2).tainted?.should == true (ary * 2).tainted?.should == true
end end
it "copies the untrusted status of the original array even if the passed count is 0" do it "copies the untrusted status of the original array even if the passed count is 0" do
ary = [1, 2, 3] ary = [1, 2, 3]
ary.untrust ary.untrust
(ary * 0).untrusted?.should == true (ary * 0).untrusted?.should == true
end end
it "copies the untrusted status of the original array even if the array is empty" do it "copies the untrusted status of the original array even if the array is empty" do
ary = [] ary = []
ary.untrust ary.untrust
(ary * 3).untrusted?.should == true (ary * 3).untrusted?.should == true
end end
it "copies the untrusted status of the original array if the passed count is not 0" do it "copies the untrusted status of the original array if the passed count is not 0" do
ary = [1, 2, 3] ary = [1, 2, 3]
ary.untrust ary.untrust
(ary * 1).untrusted?.should == true (ary * 1).untrusted?.should == true
(ary * 2).untrusted?.should == true (ary * 2).untrusted?.should == true
end
end end
end end

View file

@ -15,14 +15,16 @@ describe "Array#pack with format 'P'" do
["hello"].pack("P").unpack("P5").should == ["hello"] ["hello"].pack("P").unpack("P5").should == ["hello"]
end end
it "taints the input string" do ruby_version_is ''...'2.7' do
input_string = "hello" it "taints the input string" do
[input_string].pack("P") input_string = "hello"
input_string.tainted?.should be_true [input_string].pack("P")
end input_string.tainted?.should be_true
end
it "does not taint the output string in normal cases" do it "does not taint the output string in normal cases" do
["hello"].pack("P").tainted?.should be_false ["hello"].pack("P").tainted?.should be_false
end
end end
it "with nil gives a null pointer" do it "with nil gives a null pointer" do
@ -42,14 +44,16 @@ describe "Array#pack with format 'p'" do
["hello"].pack("p").unpack("p").should == ["hello"] ["hello"].pack("p").unpack("p").should == ["hello"]
end end
it "taints the input string" do ruby_version_is ''...'2.7' do
input_string = "hello" it "taints the input string" do
[input_string].pack("p") input_string = "hello"
input_string.tainted?.should be_true [input_string].pack("p")
end input_string.tainted?.should be_true
end
it "does not taint the output string in normal cases" do it "does not taint the output string in normal cases" do
["hello"].pack("p").tainted?.should be_false ["hello"].pack("p").tainted?.should be_false
end
end end
it "with nil gives a null pointer" do it "with nil gives a null pointer" do

View file

@ -33,8 +33,10 @@ describe :array_pack_basic_non_float, shared: true do
[@obj, @obj].pack(d).should be_an_instance_of(String) [@obj, @obj].pack(d).should be_an_instance_of(String)
end end
it "taints the output string if the format string is tainted" do ruby_version_is ''...'2.7' do
[@obj, @obj].pack("x"+pack_format.taint).tainted?.should be_true it "taints the output string if the format string is tainted" do
[@obj, @obj].pack("x"+pack_format.taint).tainted?.should be_true
end
end end
end end
@ -49,8 +51,10 @@ describe :array_pack_basic_float, shared: true do
[1.2, 4.7].pack(d).should be_an_instance_of(String) [1.2, 4.7].pack(d).should be_an_instance_of(String)
end end
it "taints the output string if the format string is tainted" do ruby_version_is ''...'2.7' do
[3.2, 2.8].pack("x"+pack_format.taint).tainted?.should be_true it "taints the output string if the format string is tainted" do
[3.2, 2.8].pack("x"+pack_format.taint).tainted?.should be_true
end
end end
end end

View file

@ -1,33 +1,35 @@
describe :array_pack_taint, shared: true do describe :array_pack_taint, shared: true do
it "returns a tainted string when a pack argument is tainted" do ruby_version_is ''...'2.7' do
["abcd".taint, 0x20].pack(pack_format("3C")).tainted?.should be_true it "returns a tainted string when a pack argument is tainted" do
end ["abcd".taint, 0x20].pack(pack_format("3C")).tainted?.should be_true
end
it "does not return a tainted string when the array is tainted" do it "does not return a tainted string when the array is tainted" do
["abcd", 0x20].taint.pack(pack_format("3C")).tainted?.should be_false ["abcd", 0x20].taint.pack(pack_format("3C")).tainted?.should be_false
end end
it "returns a tainted string when the format is tainted" do it "returns a tainted string when the format is tainted" do
["abcd", 0x20].pack(pack_format("3C").taint).tainted?.should be_true ["abcd", 0x20].pack(pack_format("3C").taint).tainted?.should be_true
end end
it "returns a tainted string when an empty format is tainted" do it "returns a tainted string when an empty format is tainted" do
["abcd", 0x20].pack("".taint).tainted?.should be_true ["abcd", 0x20].pack("".taint).tainted?.should be_true
end end
it "returns a untrusted string when the format is untrusted" do it "returns a untrusted string when the format is untrusted" do
["abcd", 0x20].pack(pack_format("3C").untrust).untrusted?.should be_true ["abcd", 0x20].pack(pack_format("3C").untrust).untrusted?.should be_true
end end
it "returns a untrusted string when the empty format is untrusted" do it "returns a untrusted string when the empty format is untrusted" do
["abcd", 0x20].pack("".untrust).untrusted?.should be_true ["abcd", 0x20].pack("".untrust).untrusted?.should be_true
end end
it "returns a untrusted string when a pack argument is untrusted" do it "returns a untrusted string when a pack argument is untrusted" do
["abcd".untrust, 0x20].pack(pack_format("3C")).untrusted?.should be_true ["abcd".untrust, 0x20].pack(pack_format("3C")).untrusted?.should be_true
end end
it "returns a trusted string when the array is untrusted" do it "returns a trusted string when the array is untrusted" do
["abcd", 0x20].untrust.pack(pack_format("3C")).untrusted?.should be_false ["abcd", 0x20].untrust.pack(pack_format("3C")).untrusted?.should be_false
end
end end
end end

View file

@ -41,17 +41,19 @@ describe "Array#+" do
([5, 6] + ArraySpecs::ToAryArray[1, 2]).should == [5, 6, 1, 2] ([5, 6] + ArraySpecs::ToAryArray[1, 2]).should == [5, 6, 1, 2]
end end
it "does not get infected even if an original array is tainted" do ruby_version_is ''...'2.7' do
([1, 2] + [3, 4]).tainted?.should be_false it "does not get infected even if an original array is tainted" do
([1, 2].taint + [3, 4]).tainted?.should be_false ([1, 2] + [3, 4]).tainted?.should be_false
([1, 2] + [3, 4].taint).tainted?.should be_false ([1, 2].taint + [3, 4]).tainted?.should be_false
([1, 2].taint + [3, 4].taint).tainted?.should be_false ([1, 2] + [3, 4].taint).tainted?.should be_false
end ([1, 2].taint + [3, 4].taint).tainted?.should be_false
end
it "does not infected even if an original array is untrusted" do it "does not infected even if an original array is untrusted" do
([1, 2] + [3, 4]).untrusted?.should be_false ([1, 2] + [3, 4]).untrusted?.should be_false
([1, 2].untrust + [3, 4]).untrusted?.should be_false ([1, 2].untrust + [3, 4]).untrusted?.should be_false
([1, 2] + [3, 4].untrust).untrusted?.should be_false ([1, 2] + [3, 4].untrust).untrusted?.should be_false
([1, 2].untrust + [3, 4].untrust).untrusted?.should be_false ([1, 2].untrust + [3, 4].untrust).untrusted?.should be_false
end
end end
end end

View file

@ -30,12 +30,14 @@ describe "Array#pop" do
array.pop.should == [1, 'two', 3.0, array, array, array, array] array.pop.should == [1, 'two', 3.0, array, array, array, array]
end end
it "keeps taint status" do ruby_version_is ''...'2.7' do
a = [1, 2].taint it "keeps taint status" do
a.pop a = [1, 2].taint
a.tainted?.should be_true a.pop
a.pop a.tainted?.should be_true
a.tainted?.should be_true a.pop
a.tainted?.should be_true
end
end end
it "raises a #{frozen_error_class} on a frozen array" do it "raises a #{frozen_error_class} on a frozen array" do
@ -46,12 +48,14 @@ describe "Array#pop" do
-> { ArraySpecs.empty_frozen_array.pop }.should raise_error(frozen_error_class) -> { ArraySpecs.empty_frozen_array.pop }.should raise_error(frozen_error_class)
end end
it "keeps untrusted status" do ruby_version_is ''...'2.7' do
a = [1, 2].untrust it "keeps untrusted status" do
a.pop a = [1, 2].untrust
a.untrusted?.should be_true a.pop
a.pop a.untrusted?.should be_true
a.untrusted?.should be_true a.pop
a.untrusted?.should be_true
end
end end
describe "passed a number n as an argument" do describe "passed a number n as an argument" do
@ -132,24 +136,26 @@ describe "Array#pop" do
ArraySpecs::MyArray[1, 2, 3].pop(2).should be_an_instance_of(Array) ArraySpecs::MyArray[1, 2, 3].pop(2).should be_an_instance_of(Array)
end end
it "returns an untainted array even if the array is tainted" do ruby_version_is ''...'2.7' do
ary = [1, 2].taint it "returns an untainted array even if the array is tainted" do
ary.pop(2).tainted?.should be_false ary = [1, 2].taint
ary.pop(0).tainted?.should be_false ary.pop(2).tainted?.should be_false
end ary.pop(0).tainted?.should be_false
end
it "keeps taint status" do it "keeps taint status" do
a = [1, 2].taint a = [1, 2].taint
a.pop(2) a.pop(2)
a.tainted?.should be_true a.tainted?.should be_true
a.pop(2) a.pop(2)
a.tainted?.should be_true a.tainted?.should be_true
end end
it "returns a trusted array even if the array is untrusted" do it "returns a trusted array even if the array is untrusted" do
ary = [1, 2].untrust ary = [1, 2].untrust
ary.pop(2).untrusted?.should be_false ary.pop(2).untrusted?.should be_false
ary.pop(0).untrusted?.should be_false ary.pop(0).untrusted?.should be_false
end
end end
it "raises a #{frozen_error_class} on a frozen array" do it "raises a #{frozen_error_class} on a frozen array" do
@ -157,12 +163,14 @@ describe "Array#pop" do
-> { ArraySpecs.frozen_array.pop(0) }.should raise_error(frozen_error_class) -> { ArraySpecs.frozen_array.pop(0) }.should raise_error(frozen_error_class)
end end
it "keeps untrusted status" do ruby_version_is ''...'2.7' do
a = [1, 2].untrust it "keeps untrusted status" do
a.pop(2) a = [1, 2].untrust
a.untrusted?.should be_true a.pop(2)
a.pop(2) a.untrusted?.should be_true
a.untrusted?.should be_true a.pop(2)
a.untrusted?.should be_true
end
end end
end end
end end

View file

@ -18,25 +18,27 @@ describe :array_clone, shared: true do
b.__id__.should_not == a.__id__ b.__id__.should_not == a.__id__
end end
it "copies taint status from the original" do ruby_version_is ''...'2.7' do
a = [1, 2, 3, 4] it "copies taint status from the original" do
b = [1, 2, 3, 4] a = [1, 2, 3, 4]
a.taint b = [1, 2, 3, 4]
aa = a.send @method a.taint
bb = b.send @method aa = a.send @method
bb = b.send @method
aa.tainted?.should == true aa.tainted?.should == true
bb.tainted?.should == false bb.tainted?.should == false
end end
it "copies untrusted status from the original" do it "copies untrusted status from the original" do
a = [1, 2, 3, 4] a = [1, 2, 3, 4]
b = [1, 2, 3, 4] b = [1, 2, 3, 4]
a.untrust a.untrust
aa = a.send @method aa = a.send @method
bb = b.send @method bb = b.send @method
aa.untrusted?.should == true aa.untrusted?.should == true
bb.untrusted?.should == false bb.untrusted?.should == false
end
end end
end end

View file

@ -42,16 +42,18 @@ describe :array_collect, shared: true do
}.should raise_error(ArgumentError) }.should raise_error(ArgumentError)
end end
it "does not copy tainted status" do ruby_version_is ''...'2.7' do
a = [1, 2, 3] it "does not copy tainted status" do
a.taint a = [1, 2, 3]
a.send(@method){|x| x}.tainted?.should be_false a.taint
end a.send(@method){|x| x}.tainted?.should be_false
end
it "does not copy untrusted status" do it "does not copy untrusted status" do
a = [1, 2, 3] a = [1, 2, 3]
a.untrust a.untrust
a.send(@method){|x| x}.untrusted?.should be_false a.send(@method){|x| x}.untrusted?.should be_false
end
end end
before :all do before :all do
@ -94,19 +96,21 @@ describe :array_collect_b, shared: true do
a.should == ["1!", "2!", "3!"] a.should == ["1!", "2!", "3!"]
end end
it "keeps tainted status" do ruby_version_is ''...'2.7' do
a = [1, 2, 3] it "keeps tainted status" do
a.taint a = [1, 2, 3]
a.tainted?.should be_true a.taint
a.send(@method){|x| x} a.tainted?.should be_true
a.tainted?.should be_true a.send(@method){|x| x}
end a.tainted?.should be_true
end
it "keeps untrusted status" do it "keeps untrusted status" do
a = [1, 2, 3] a = [1, 2, 3]
a.untrust a.untrust
a.send(@method){|x| x} a.send(@method){|x| x}
a.untrusted?.should be_true a.untrusted?.should be_true
end
end end
describe "when frozen" do describe "when frozen" do

View file

@ -64,28 +64,30 @@ describe :array_inspect, shared: true do
ArraySpecs.empty_recursive_array.send(@method).should == "[[...]]" ArraySpecs.empty_recursive_array.send(@method).should == "[[...]]"
end end
it "taints the result if the Array is non-empty and tainted" do ruby_version_is ''...'2.7' do
[1, 2].taint.send(@method).tainted?.should be_true it "taints the result if the Array is non-empty and tainted" do
end [1, 2].taint.send(@method).tainted?.should be_true
end
it "does not taint the result if the Array is tainted but empty" do it "does not taint the result if the Array is tainted but empty" do
[].taint.send(@method).tainted?.should be_false [].taint.send(@method).tainted?.should be_false
end end
it "taints the result if an element is tainted" do it "taints the result if an element is tainted" do
["str".taint].send(@method).tainted?.should be_true ["str".taint].send(@method).tainted?.should be_true
end end
it "untrusts the result if the Array is untrusted" do it "untrusts the result if the Array is untrusted" do
[1, 2].untrust.send(@method).untrusted?.should be_true [1, 2].untrust.send(@method).untrusted?.should be_true
end end
it "does not untrust the result if the Array is untrusted but empty" do it "does not untrust the result if the Array is untrusted but empty" do
[].untrust.send(@method).untrusted?.should be_false [].untrust.send(@method).untrusted?.should be_false
end end
it "untrusts the result if an element is untrusted" do it "untrusts the result if an element is untrusted" do
["str".untrust].send(@method).untrusted?.should be_true ["str".untrust].send(@method).untrusted?.should be_true
end
end end
describe "with encoding" do describe "with encoding" do

View file

@ -58,32 +58,34 @@ describe :array_join_with_default_separator, shared: true do
-> { ArraySpecs.empty_recursive_array.send(@method) }.should raise_error(ArgumentError) -> { ArraySpecs.empty_recursive_array.send(@method) }.should raise_error(ArgumentError)
end end
it "taints the result if the Array is tainted and non-empty" do ruby_version_is ''...'2.7' do
[1, 2].taint.send(@method).tainted?.should be_true it "taints the result if the Array is tainted and non-empty" do
end [1, 2].taint.send(@method).tainted?.should be_true
end
it "does not taint the result if the Array is tainted but empty" do it "does not taint the result if the Array is tainted but empty" do
[].taint.send(@method).tainted?.should be_false [].taint.send(@method).tainted?.should be_false
end end
it "taints the result if the result of coercing an element is tainted" do it "taints the result if the result of coercing an element is tainted" do
s = mock("taint") s = mock("taint")
s.should_receive(:to_s).and_return("str".taint) s.should_receive(:to_s).and_return("str".taint)
[s].send(@method).tainted?.should be_true [s].send(@method).tainted?.should be_true
end end
it "untrusts the result if the Array is untrusted and non-empty" do it "untrusts the result if the Array is untrusted and non-empty" do
[1, 2].untrust.send(@method).untrusted?.should be_true [1, 2].untrust.send(@method).untrusted?.should be_true
end end
it "does not untrust the result if the Array is untrusted but empty" do it "does not untrust the result if the Array is untrusted but empty" do
[].untrust.send(@method).untrusted?.should be_false [].untrust.send(@method).untrusted?.should be_false
end end
it "untrusts the result if the result of coercing an element is untrusted" do it "untrusts the result if the result of coercing an element is untrusted" do
s = mock("untrust") s = mock("untrust")
s.should_receive(:to_s).and_return("str".untrust) s.should_receive(:to_s).and_return("str".untrust)
[s].send(@method).untrusted?.should be_true [s].send(@method).untrusted?.should be_true
end
end end
it "uses the first encoding when other strings are compatible" do it "uses the first encoding when other strings are compatible" do
@ -125,39 +127,41 @@ describe :array_join_with_string_separator, shared: true do
[1, [2, ArraySpecs::MyArray[3, 4], 5], 6].send(@method, ":").should == "1:2:3:4:5:6" [1, [2, ArraySpecs::MyArray[3, 4], 5], 6].send(@method, ":").should == "1:2:3:4:5:6"
end end
describe "with a tainted separator" do ruby_version_is ''...'2.7' do
before :each do describe "with a tainted separator" do
@sep = ":".taint before :each do
@sep = ":".taint
end
it "does not taint the result if the array is empty" do
[].send(@method, @sep).tainted?.should be_false
end
it "does not taint the result if the array has only one element" do
[1].send(@method, @sep).tainted?.should be_false
end
it "taints the result if the array has two or more elements" do
[1, 2].send(@method, @sep).tainted?.should be_true
end
end end
it "does not taint the result if the array is empty" do describe "with an untrusted separator" do
[].send(@method, @sep).tainted?.should be_false before :each do
end @sep = ":".untrust
end
it "does not taint the result if the array has only one element" do it "does not untrust the result if the array is empty" do
[1].send(@method, @sep).tainted?.should be_false [].send(@method, @sep).untrusted?.should be_false
end end
it "taints the result if the array has two or more elements" do it "does not untrust the result if the array has only one element" do
[1, 2].send(@method, @sep).tainted?.should be_true [1].send(@method, @sep).untrusted?.should be_false
end end
end
describe "with an untrusted separator" do it "untrusts the result if the array has two or more elements" do
before :each do [1, 2].send(@method, @sep).untrusted?.should be_true
@sep = ":".untrust end
end
it "does not untrust the result if the array is empty" do
[].send(@method, @sep).untrusted?.should be_false
end
it "does not untrust the result if the array has only one element" do
[1].send(@method, @sep).untrusted?.should be_false
end
it "untrusts the result if the array has two or more elements" do
[1, 2].send(@method, @sep).untrusted?.should be_true
end end
end end
end end

View file

@ -117,18 +117,20 @@ describe "Array#shift" do
ArraySpecs::MyArray[1, 2, 3].shift(2).should be_an_instance_of(Array) ArraySpecs::MyArray[1, 2, 3].shift(2).should be_an_instance_of(Array)
end end
it "returns an untainted array even if the array is tainted" do ruby_version_is ''...'2.7' do
ary = [1, 2].taint it "returns an untainted array even if the array is tainted" do
ary.shift(2).tainted?.should be_false ary = [1, 2].taint
ary.shift(0).tainted?.should be_false ary.shift(2).tainted?.should be_false
end ary.shift(0).tainted?.should be_false
end
it "keeps taint status" do it "keeps taint status" do
a = [1, 2].taint a = [1, 2].taint
a.shift(2) a.shift(2)
a.tainted?.should be_true a.tainted?.should be_true
a.shift(2) a.shift(2)
a.tainted?.should be_true a.tainted?.should be_true
end
end end
end end
end end

View file

@ -39,44 +39,76 @@ describe "Array#uniq" do
[x, y].uniq.should == [x, y] [x, y].uniq.should == [x, y]
end end
it "compares elements with matching hash codes with #eql?" do ruby_version_is '2.7' do
a = Array.new(2) do it "compares elements with matching hash codes with #eql?" do
obj = mock('0') a = Array.new(2) do
obj.should_receive(:hash).at_least(1).and_return(0) obj = mock('0')
obj.should_receive(:hash).at_least(1).and_return(0)
def obj.eql?(o) def obj.eql?(o)
# It's undefined whether the impl does a[0].eql?(a[1]) or false
# a[1].eql?(a[0]) so we taint both. end
taint
o.taint obj
false
end end
obj a.uniq.should == a
end
a.uniq.should == a a = Array.new(2) do
a[0].tainted?.should == true obj = mock('0')
a[1].tainted?.should == true obj.should_receive(:hash).at_least(1).and_return(0)
a = Array.new(2) do def obj.eql?(o)
obj = mock('0') true
obj.should_receive(:hash).at_least(1).and_return(0) end
def obj.eql?(o) obj
# It's undefined whether the impl does a[0].eql?(a[1]) or
# a[1].eql?(a[0]) so we taint both.
taint
o.taint
true
end end
obj a.uniq.size.should == 1
end end
end
a.uniq.size.should == 1 ruby_version_is ''...'2.7' do
a[0].tainted?.should == true it "compares elements with matching hash codes with #eql?" do
a[1].tainted?.should == true a = Array.new(2) do
obj = mock('0')
obj.should_receive(:hash).at_least(1).and_return(0)
def obj.eql?(o)
# It's undefined whether the impl does a[0].eql?(a[1]) or
# a[1].eql?(a[0]) so we taint both.
taint
o.taint
false
end
obj
end
a.uniq.should == a
a[0].tainted?.should == true
a[1].tainted?.should == true
a = Array.new(2) do
obj = mock('0')
obj.should_receive(:hash).at_least(1).and_return(0)
def obj.eql?(o)
# It's undefined whether the impl does a[0].eql?(a[1]) or
# a[1].eql?(a[0]) so we taint both.
taint
o.taint
true
end
obj
end
a.uniq.size.should == 1
a[0].tainted?.should == true
a[1].tainted?.should == true
end
end end
it "compares elements based on the value returned from the block" do it "compares elements based on the value returned from the block" do

View file

@ -33,12 +33,14 @@ describe "Enumerable#group_by" do
[3, 4, 5] => [[3, 4, 5]] } [3, 4, 5] => [[3, 4, 5]] }
end end
it "returns a tainted hash if self is tainted" do ruby_version_is ''...'2.7' do
EnumerableSpecs::Empty.new.taint.group_by {}.tainted?.should be_true it "returns a tainted hash if self is tainted" do
end EnumerableSpecs::Empty.new.taint.group_by {}.tainted?.should be_true
end
it "returns an untrusted hash if self is untrusted" do it "returns an untrusted hash if self is untrusted" do
EnumerableSpecs::Empty.new.untrust.group_by {}.untrusted?.should be_true EnumerableSpecs::Empty.new.untrust.group_by {}.untrusted?.should be_true
end
end end
it_behaves_like :enumerable_enumeratorized_with_origin_size, :group_by it_behaves_like :enumerable_enumeratorized_with_origin_size, :group_by

View file

@ -14,11 +14,13 @@ describe :enumerable_entries, shared: true do
count.arguments_passed.should == [:hello, "world"] count.arguments_passed.should == [:hello, "world"]
end end
it "returns a tainted array if self is tainted" do ruby_version_is ''...'2.7' do
EnumerableSpecs::Empty.new.taint.send(@method).tainted?.should be_true it "returns a tainted array if self is tainted" do
end EnumerableSpecs::Empty.new.taint.send(@method).tainted?.should be_true
end
it "returns an untrusted array if self is untrusted" do it "returns an untrusted array if self is untrusted" do
EnumerableSpecs::Empty.new.untrust.send(@method).untrusted?.should be_true EnumerableSpecs::Empty.new.untrust.send(@method).untrusted?.should be_true
end
end end
end end

View file

@ -31,44 +31,76 @@ describe 'Enumerable#uniq' do
[x, y].to_enum.uniq.should == [x, y] [x, y].to_enum.uniq.should == [x, y]
end end
it "compares elements with matching hash codes with #eql?" do ruby_version_is '2.7' do
a = Array.new(2) do it "compares elements with matching hash codes with #eql?" do
obj = mock('0') a = Array.new(2) do
obj.should_receive(:hash).at_least(1).and_return(0) obj = mock('0')
obj.should_receive(:hash).at_least(1).and_return(0)
def obj.eql?(o) def obj.eql?(o)
# It's undefined whether the impl does a[0].eql?(a[1]) or false
# a[1].eql?(a[0]) so we taint both. end
taint
o.taint obj
false
end end
obj a.uniq.should == a
end
a.uniq.should == a a = Array.new(2) do
a[0].tainted?.should == true obj = mock('0')
a[1].tainted?.should == true obj.should_receive(:hash).at_least(1).and_return(0)
a = Array.new(2) do def obj.eql?(o)
obj = mock('0') true
obj.should_receive(:hash).at_least(1).and_return(0) end
def obj.eql?(o) obj
# It's undefined whether the impl does a[0].eql?(a[1]) or
# a[1].eql?(a[0]) so we taint both.
taint
o.taint
true
end end
obj a.to_enum.uniq.size.should == 1
end end
end
a.to_enum.uniq.size.should == 1 ruby_version_is ''...'2.7' do
a[0].tainted?.should == true it "compares elements with matching hash codes with #eql?" do
a[1].tainted?.should == true a = Array.new(2) do
obj = mock('0')
obj.should_receive(:hash).at_least(1).and_return(0)
def obj.eql?(o)
# It's undefined whether the impl does a[0].eql?(a[1]) or
# a[1].eql?(a[0]) so we taint both.
taint
o.taint
false
end
obj
end
a.uniq.should == a
a[0].tainted?.should == true
a[1].tainted?.should == true
a = Array.new(2) do
obj = mock('0')
obj.should_receive(:hash).at_least(1).and_return(0)
def obj.eql?(o)
# It's undefined whether the impl does a[0].eql?(a[1]) or
# a[1].eql?(a[0]) so we taint both.
taint
o.taint
true
end
obj
end
a.to_enum.uniq.size.should == 1
a[0].tainted?.should == true
a[1].tainted?.should == true
end
end end
context 'when yielded with multiple arguments' do context 'when yielded with multiple arguments' do

View file

@ -32,9 +32,11 @@ describe "Hash#reject" do
HashSpecs::MyHash[1 => 2, 3 => 4].reject { true }.should be_kind_of(Hash) HashSpecs::MyHash[1 => 2, 3 => 4].reject { true }.should be_kind_of(Hash)
end end
it "does not taint the resulting hash" do ruby_version_is ''...'2.7' do
h = { a: 1 }.taint it "does not taint the resulting hash" do
h.reject {false}.tainted?.should == false h = { a: 1 }.taint
h.reject {false}.tainted?.should == false
end
end end
end end

View file

@ -149,46 +149,80 @@ describe :hash_eql_additional, shared: true do
h.send(@method, HashSpecs::MyHash[h]).should be_true h.send(@method, HashSpecs::MyHash[h]).should be_true
end end
# Why isn't this true of eql? too ? ruby_version_is '2.7' do
it "compares keys with matching hash codes via eql?" do # Why isn't this true of eql? too ?
a = Array.new(2) do it "compares keys with matching hash codes via eql?" do
obj = mock('0') a = Array.new(2) do
obj.should_receive(:hash).at_least(1).and_return(0) obj = mock('0')
obj.should_receive(:hash).at_least(1).and_return(0)
# It's undefined whether the impl does a[0].eql?(a[1]) or def obj.eql?(o)
# a[1].eql?(a[0]) so we taint both. return true if self.equal?(o)
def obj.eql?(o) false
return true if self.equal?(o) end
taint
o.taint obj
false
end end
obj { a[0] => 1 }.send(@method, { a[1] => 1 }).should be_false
end
{ a[0] => 1 }.send(@method, { a[1] => 1 }).should be_false a = Array.new(2) do
a[0].tainted?.should be_true obj = mock('0')
a[1].tainted?.should be_true obj.should_receive(:hash).at_least(1).and_return(0)
a = Array.new(2) do def obj.eql?(o)
obj = mock('0') true
obj.should_receive(:hash).at_least(1).and_return(0) end
def obj.eql?(o) obj
# It's undefined whether the impl does a[0].send(@method, a[1]) or
# a[1].send(@method, a[0]) so we taint both.
taint
o.taint
true
end end
obj { a[0] => 1 }.send(@method, { a[1] => 1 }).should be_true
end end
end
{ a[0] => 1 }.send(@method, { a[1] => 1 }).should be_true ruby_version_is ''...'2.7' do
a[0].tainted?.should be_true # Why isn't this true of eql? too ?
a[1].tainted?.should be_true it "compares keys with matching hash codes via eql?" do
a = Array.new(2) do
obj = mock('0')
obj.should_receive(:hash).at_least(1).and_return(0)
# It's undefined whether the impl does a[0].eql?(a[1]) or
# a[1].eql?(a[0]) so we taint both.
def obj.eql?(o)
return true if self.equal?(o)
taint
o.taint
false
end
obj
end
{ a[0] => 1 }.send(@method, { a[1] => 1 }).should be_false
a[0].tainted?.should be_true
a[1].tainted?.should be_true
a = Array.new(2) do
obj = mock('0')
obj.should_receive(:hash).at_least(1).and_return(0)
def obj.eql?(o)
# It's undefined whether the impl does a[0].send(@method, a[1]) or
# a[1].send(@method, a[0]) so we taint both.
taint
o.taint
true
end
obj
end
{ a[0] => 1 }.send(@method, { a[1] => 1 }).should be_true
a[0].tainted?.should be_true
a[1].tainted?.should be_true
end
end end
it "compares the values in self to values in other hash" do it "compares the values in self to values in other hash" do

View file

@ -77,14 +77,16 @@ describe :hash_to_s, shared: true do
y.send(@method).should == "{1=>{0=>{...}}}" y.send(@method).should == "{1=>{0=>{...}}}"
end end
it "returns a tainted string if self is tainted and not empty" do ruby_version_is ''...'2.7' do
{}.taint.send(@method).tainted?.should be_false it "returns a tainted string if self is tainted and not empty" do
{ nil => nil }.taint.send(@method).tainted?.should be_true {}.taint.send(@method).tainted?.should be_false
end { nil => nil }.taint.send(@method).tainted?.should be_true
end
it "returns an untrusted string if self is untrusted and not empty" do it "returns an untrusted string if self is untrusted and not empty" do
{}.untrust.send(@method).untrusted?.should be_false {}.untrust.send(@method).untrusted?.should be_false
{ nil => nil }.untrust.send(@method).untrusted?.should be_true { nil => nil }.untrust.send(@method).untrusted?.should be_true
end
end end
it "does not raise if inspected result is not default external encoding" do it "does not raise if inspected result is not default external encoding" do

View file

@ -27,11 +27,13 @@ describe "Hash#to_a" do
ent.should == pairs ent.should == pairs
end end
it "returns a tainted array if self is tainted" do ruby_version_is ''...'2.7' do
{}.taint.to_a.tainted?.should be_true it "returns a tainted array if self is tainted" do
end {}.taint.to_a.tainted?.should be_true
end
it "returns an untrusted array if self is untrusted" do it "returns an untrusted array if self is untrusted" do
{}.untrust.to_a.untrusted?.should be_true {}.untrust.to_a.untrusted?.should be_true
end
end end
end end

View file

@ -38,9 +38,11 @@ describe "IO#gets" do
IOSpecs.lines.each { |line| line.should == @io.gets } IOSpecs.lines.each { |line| line.should == @io.gets }
end end
it "returns tainted strings" do ruby_version_is ''...'2.7' do
while line = @io.gets it "returns tainted strings" do
line.tainted?.should == true while line = @io.gets
line.tainted?.should == true
end
end end
end end
@ -62,9 +64,11 @@ describe "IO#gets" do
@io.gets(nil).should == IOSpecs.lines.join("") @io.gets(nil).should == IOSpecs.lines.join("")
end end
it "returns tainted strings" do ruby_version_is ''...'2.7' do
while line = @io.gets(nil) it "returns tainted strings" do
line.tainted?.should == true while line = @io.gets(nil)
line.tainted?.should == true
end
end end
end end
@ -96,9 +100,11 @@ describe "IO#gets" do
@io.gets.should == IOSpecs.lines[4] @io.gets.should == IOSpecs.lines[4]
end end
it "returns tainted strings" do ruby_version_is ''...'2.7' do
while line = @io.gets("") it "returns tainted strings" do
line.tainted?.should == true while line = @io.gets("")
line.tainted?.should == true
end
end end
end end
@ -120,9 +126,11 @@ describe "IO#gets" do
@io.gets("la linea").should == "Voici la ligne une.\nQui \303\250 la linea" @io.gets("la linea").should == "Voici la ligne une.\nQui \303\250 la linea"
end end
it "returns tainted strings" do ruby_version_is ''...'2.7' do
while line = @io.gets("la") it "returns tainted strings" do
line.tainted?.should == true while line = @io.gets("la")
line.tainted?.should == true
end
end end
end end

View file

@ -108,9 +108,15 @@ describe "Kernel#clone" do
cloned.bar.should == ['a'] cloned.bar.should == ['a']
end end
it 'copies frozen? and tainted?' do it 'copies frozen?' do
o = ''.taint.freeze.clone o = ''.freeze.clone
o.frozen?.should be_true o.frozen?.should be_true
o.tainted?.should be_true end
ruby_version_is ''...'2.7' do
it 'copies tainted?' do
o = ''.taint.clone
o.tainted?.should be_true
end
end end
end end

View file

@ -6,12 +6,14 @@ describe "Kernel#inspect" do
Object.new.inspect.should be_an_instance_of(String) Object.new.inspect.should be_an_instance_of(String)
end end
it "returns a tainted string if self is tainted" do ruby_version_is ''...'2.7' do
Object.new.taint.inspect.tainted?.should be_true it "returns a tainted string if self is tainted" do
end Object.new.taint.inspect.tainted?.should be_true
end
it "returns an untrusted string if self is untrusted" do it "returns an untrusted string if self is untrusted" do
Object.new.untrust.inspect.untrusted?.should be_true Object.new.untrust.inspect.untrusted?.should be_true
end
end end
it "does not call #to_s if it is defined" do it "does not call #to_s if it is defined" do

View file

@ -52,14 +52,16 @@ describe :kernel_dup_clone, shared: true do
o2.original.should equal(o) o2.original.should equal(o)
end end
it "preserves tainted state from the original" do ruby_version_is ''...'2.7' do
o = ObjectSpecDupInitCopy.new it "preserves tainted state from the original" do
o2 = o.send(@method) o = ObjectSpecDupInitCopy.new
o.taint o2 = o.send(@method)
o3 = o.send(@method) o.taint
o3 = o.send(@method)
o2.tainted?.should == false o2.tainted?.should == false
o3.tainted?.should == true o3.tainted?.should == true
end
end end
it "does not preserve the object_id" do it "does not preserve the object_id" do
@ -69,14 +71,16 @@ describe :kernel_dup_clone, shared: true do
o2.object_id.should_not == old_object_id o2.object_id.should_not == old_object_id
end end
it "preserves untrusted state from the original" do ruby_version_is ''...'2.7' do
o = ObjectSpecDupInitCopy.new it "preserves untrusted state from the original" do
o2 = o.send(@method) o = ObjectSpecDupInitCopy.new
o.untrust o2 = o.send(@method)
o3 = o.send(@method) o.untrust
o3 = o.send(@method)
o2.untrusted?.should == false o2.untrusted?.should == false
o3.untrusted?.should == true o3.untrusted?.should == true
end
end end
it "returns nil for NilClass" do it "returns nil for NilClass" do

View file

@ -2,44 +2,46 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes' require_relative 'fixtures/classes'
describe "Kernel#taint" do describe "Kernel#taint" do
it "returns self" do ruby_version_is ''...'2.7' do
o = Object.new it "returns self" do
o.taint.should equal(o) o = Object.new
end o.taint.should equal(o)
it "sets the tainted bit" do
o = Object.new
o.taint
o.tainted?.should == true
end
it "raises #{frozen_error_class} on an untainted, frozen object" do
o = Object.new.freeze
-> { o.taint }.should raise_error(frozen_error_class)
end
it "does not raise an error on a tainted, frozen object" do
o = Object.new.taint.freeze
o.taint.should equal(o)
end
it "has no effect on immediate values" do
[nil, true, false].each do |v|
v.taint
v.tainted?.should == false
end end
end
it "no raises a RuntimeError on symbols" do it "sets the tainted bit" do
v = :sym o = Object.new
-> { v.taint }.should_not raise_error(RuntimeError) o.taint
v.tainted?.should == false o.tainted?.should == true
end end
it "no raises error on fixnum values" do it "raises #{frozen_error_class} on an untainted, frozen object" do
[1].each do |v| o = Object.new.freeze
-> { o.taint }.should raise_error(frozen_error_class)
end
it "does not raise an error on a tainted, frozen object" do
o = Object.new.taint.freeze
o.taint.should equal(o)
end
it "has no effect on immediate values" do
[nil, true, false].each do |v|
v.taint
v.tainted?.should == false
end
end
it "no raises a RuntimeError on symbols" do
v = :sym
-> { v.taint }.should_not raise_error(RuntimeError) -> { v.taint }.should_not raise_error(RuntimeError)
v.tainted?.should == false v.tainted?.should == false
end end
it "no raises error on fixnum values" do
[1].each do |v|
-> { v.taint }.should_not raise_error(RuntimeError)
v.tainted?.should == false
end
end
end end
end end

View file

@ -2,11 +2,13 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes' require_relative 'fixtures/classes'
describe "Kernel#tainted?" do describe "Kernel#tainted?" do
it "returns true if Object is tainted" do ruby_version_is ''...'2.7' do
o = mock('o') it "returns true if Object is tainted" do
p = mock('p') o = mock('o')
p.taint p = mock('p')
o.tainted?.should == false p.taint
p.tainted?.should == true o.tainted?.should == false
p.tainted?.should == true
end
end end
end end

View file

@ -6,11 +6,13 @@ describe "Kernel#to_s" do
Object.new.to_s.should =~ /Object/ Object.new.to_s.should =~ /Object/
end end
it "returns a tainted result if self is tainted" do ruby_version_is ''...'2.7' do
Object.new.taint.to_s.tainted?.should be_true it "returns a tainted result if self is tainted" do
end Object.new.taint.to_s.tainted?.should be_true
end
it "returns an untrusted result if self is untrusted" do it "returns an untrusted result if self is untrusted" do
Object.new.untrust.to_s.untrusted?.should be_true Object.new.untrust.to_s.untrusted?.should be_true
end
end end
end end

View file

@ -2,24 +2,26 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes' require_relative 'fixtures/classes'
describe "Kernel#trust" do describe "Kernel#trust" do
it "returns self" do ruby_version_is ''...'2.7' do
o = Object.new it "returns self" do
o.trust.should equal(o) o = Object.new
end o.trust.should equal(o)
end
it "clears the untrusted bit" do it "clears the untrusted bit" do
o = Object.new.untrust o = Object.new.untrust
o.trust o.trust
o.untrusted?.should == false o.untrusted?.should == false
end end
it "raises #{frozen_error_class} on an untrusted, frozen object" do it "raises #{frozen_error_class} on an untrusted, frozen object" do
o = Object.new.untrust.freeze o = Object.new.untrust.freeze
-> { o.trust }.should raise_error(frozen_error_class) -> { o.trust }.should raise_error(frozen_error_class)
end end
it "does not raise an error on a trusted, frozen object" do it "does not raise an error on a trusted, frozen object" do
o = Object.new.freeze o = Object.new.freeze
o.trust.should equal(o) o.trust.should equal(o)
end
end end
end end

View file

@ -2,24 +2,26 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes' require_relative 'fixtures/classes'
describe "Kernel#untaint" do describe "Kernel#untaint" do
it "returns self" do ruby_version_is ''...'2.7' do
o = Object.new it "returns self" do
o.untaint.should equal(o) o = Object.new
end o.untaint.should equal(o)
end
it "clears the tainted bit" do it "clears the tainted bit" do
o = Object.new.taint o = Object.new.taint
o.untaint o.untaint
o.tainted?.should == false o.tainted?.should == false
end end
it "raises #{frozen_error_class} on a tainted, frozen object" do it "raises #{frozen_error_class} on a tainted, frozen object" do
o = Object.new.taint.freeze o = Object.new.taint.freeze
-> { o.untaint }.should raise_error(frozen_error_class) -> { o.untaint }.should raise_error(frozen_error_class)
end end
it "does not raise an error on an untainted, frozen object" do it "does not raise an error on an untainted, frozen object" do
o = Object.new.freeze o = Object.new.freeze
o.untaint.should equal(o) o.untaint.should equal(o)
end
end end
end end

View file

@ -2,24 +2,26 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes' require_relative 'fixtures/classes'
describe "Kernel#untrust" do describe "Kernel#untrust" do
it "returns self" do ruby_version_is ''...'2.7' do
o = Object.new it "returns self" do
o.untrust.should equal(o) o = Object.new
end o.untrust.should equal(o)
end
it "sets the untrusted bit" do it "sets the untrusted bit" do
o = Object.new o = Object.new
o.untrust o.untrust
o.untrusted?.should == true o.untrusted?.should == true
end end
it "raises #{frozen_error_class} on a trusted, frozen object" do it "raises #{frozen_error_class} on a trusted, frozen object" do
o = Object.new.freeze o = Object.new.freeze
-> { o.untrust }.should raise_error(frozen_error_class) -> { o.untrust }.should raise_error(frozen_error_class)
end end
it "does not raise an error on an untrusted, frozen object" do it "does not raise an error on an untrusted, frozen object" do
o = Object.new.untrust.freeze o = Object.new.untrust.freeze
o.untrust.should equal(o) o.untrust.should equal(o)
end
end end
end end

View file

@ -2,27 +2,29 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes' require_relative 'fixtures/classes'
describe "Kernel#untrusted?" do describe "Kernel#untrusted?" do
it "returns the untrusted status of an object" do ruby_version_is ''...'2.7' do
o = mock('o') it "returns the untrusted status of an object" do
o.untrusted?.should == false o = mock('o')
o.untrust o.untrusted?.should == false
o.untrusted?.should == true o.untrust
end o.untrusted?.should == true
end
it "has no effect on immediate values" do it "has no effect on immediate values" do
a = nil a = nil
b = true b = true
c = false c = false
a.untrust a.untrust
b.untrust b.untrust
c.untrust c.untrust
a.untrusted?.should == false a.untrusted?.should == false
b.untrusted?.should == false b.untrusted?.should == false
c.untrusted?.should == false c.untrusted?.should == false
end end
it "has effect on immediate values" do it "has effect on immediate values" do
d = 1 d = 1
-> { d.untrust }.should_not raise_error(RuntimeError) -> { d.untrust }.should_not raise_error(RuntimeError)
end
end end
end end

View file

@ -581,27 +581,29 @@ describe "Marshal.dump" do
-> { Marshal.dump(m) }.should raise_error(TypeError) -> { Marshal.dump(m) }.should raise_error(TypeError)
end end
it "returns an untainted string if object is untainted" do ruby_version_is ''...'2.7' do
Marshal.dump(Object.new).tainted?.should be_false it "returns an untainted string if object is untainted" do
end Marshal.dump(Object.new).tainted?.should be_false
end
it "returns a tainted string if object is tainted" do it "returns a tainted string if object is tainted" do
Marshal.dump(Object.new.taint).tainted?.should be_true Marshal.dump(Object.new.taint).tainted?.should be_true
end end
it "returns a tainted string if nested object is tainted" do it "returns a tainted string if nested object is tainted" do
Marshal.dump([[Object.new.taint]]).tainted?.should be_true Marshal.dump([[Object.new.taint]]).tainted?.should be_true
end end
it "returns a trusted string if object is trusted" do it "returns a trusted string if object is trusted" do
Marshal.dump(Object.new).untrusted?.should be_false Marshal.dump(Object.new).untrusted?.should be_false
end end
it "returns an untrusted string if object is untrusted" do it "returns an untrusted string if object is untrusted" do
Marshal.dump(Object.new.untrust).untrusted?.should be_true Marshal.dump(Object.new.untrust).untrusted?.should be_true
end end
it "returns an untrusted string if nested object is untrusted" do it "returns an untrusted string if nested object is untrusted" do
Marshal.dump([[Object.new.untrust]]).untrusted?.should be_true Marshal.dump([[Object.new.untrust]]).untrusted?.should be_true
end
end end
end end

View file

@ -182,85 +182,87 @@ describe :marshal_load, shared: true do
end end
end end
it "returns an untainted object if source is untainted" do ruby_version_is ''...'2.7' do
x = Object.new it "returns an untainted object if source is untainted" do
y = Marshal.send(@method, Marshal.dump(x))
y.tainted?.should be_false
end
describe "when source is tainted" do
it "returns a tainted object" do
x = Object.new x = Object.new
x.taint y = Marshal.send(@method, Marshal.dump(x))
s = Marshal.dump(x) y.tainted?.should be_false
y = Marshal.send(@method, s) end
y.tainted?.should be_true
# note that round-trip via Marshal does not preserve describe "when source is tainted" do
# the taintedness at each level of the nested structure it "returns a tainted object" do
y = Marshal.send(@method, Marshal.dump([[x]])) x = Object.new
x.taint
s = Marshal.dump(x)
y = Marshal.send(@method, s)
y.tainted?.should be_true
# note that round-trip via Marshal does not preserve
# the taintedness at each level of the nested structure
y = Marshal.send(@method, Marshal.dump([[x]]))
y.tainted?.should be_true
y.first.tainted?.should be_true
y.first.first.tainted?.should be_true
end
it "does not taint Symbols" do
x = [:x]
y = Marshal.send(@method, Marshal.dump(x).taint)
y.tainted?.should be_true
y.first.tainted?.should be_false
end
it "does not taint Fixnums" do
x = [1]
y = Marshal.send(@method, Marshal.dump(x).taint)
y.tainted?.should be_true
y.first.tainted?.should be_false
end
it "does not taint Bignums" do
x = [bignum_value]
y = Marshal.send(@method, Marshal.dump(x).taint)
y.tainted?.should be_true
y.first.tainted?.should be_false
end
it "does not taint Floats" do
x = [1.2]
y = Marshal.send(@method, Marshal.dump(x).taint)
y.tainted?.should be_true
y.first.tainted?.should be_false
end
end
it "preserves taintedness of nested structure" do
x = Object.new
a = [[x]]
x.taint
y = Marshal.send(@method, Marshal.dump(a))
y.tainted?.should be_true y.tainted?.should be_true
y.first.tainted?.should be_true y.first.tainted?.should be_true
y.first.first.tainted?.should be_true y.first.first.tainted?.should be_true
end end
it "does not taint Symbols" do it "returns a trusted object if source is trusted" do
x = [:x] x = Object.new
y = Marshal.send(@method, Marshal.dump(x).taint) y = Marshal.send(@method, Marshal.dump(x))
y.tainted?.should be_true y.untrusted?.should be_false
y.first.tainted?.should be_false
end end
it "does not taint Fixnums" do it "returns an untrusted object if source is untrusted" do
x = [1] x = Object.new
y = Marshal.send(@method, Marshal.dump(x).taint) x.untrust
y.tainted?.should be_true y = Marshal.send(@method, Marshal.dump(x))
y.first.tainted?.should be_false y.untrusted?.should be_true
# note that round-trip via Marshal does not preserve
# the untrustedness at each level of the nested structure
y = Marshal.send(@method, Marshal.dump([[x]]))
y.untrusted?.should be_true
y.first.untrusted?.should be_true
y.first.first.untrusted?.should be_true
end end
it "does not taint Bignums" do
x = [bignum_value]
y = Marshal.send(@method, Marshal.dump(x).taint)
y.tainted?.should be_true
y.first.tainted?.should be_false
end
it "does not taint Floats" do
x = [1.2]
y = Marshal.send(@method, Marshal.dump(x).taint)
y.tainted?.should be_true
y.first.tainted?.should be_false
end
end
it "preserves taintedness of nested structure" do
x = Object.new
a = [[x]]
x.taint
y = Marshal.send(@method, Marshal.dump(a))
y.tainted?.should be_true
y.first.tainted?.should be_true
y.first.first.tainted?.should be_true
end
it "returns a trusted object if source is trusted" do
x = Object.new
y = Marshal.send(@method, Marshal.dump(x))
y.untrusted?.should be_false
end
it "returns an untrusted object if source is untrusted" do
x = Object.new
x.untrust
y = Marshal.send(@method, Marshal.dump(x))
y.untrusted?.should be_true
# note that round-trip via Marshal does not preserve
# the untrustedness at each level of the nested structure
y = Marshal.send(@method, Marshal.dump([[x]]))
y.untrusted?.should be_true
y.first.untrusted?.should be_true
y.first.first.untrusted?.should be_true
end end
# Note: Ruby 1.9 should be compatible with older marshal format # Note: Ruby 1.9 should be compatible with older marshal format

View file

@ -6,20 +6,22 @@ describe "MatchData#post_match" do
$'.should == ': The Movie' $'.should == ': The Movie'
end end
it "keeps taint status from the source string" do ruby_version_is ''...'2.7' do
str = "THX1138: The Movie" it "keeps taint status from the source string" do
str.taint str = "THX1138: The Movie"
res = /(.)(.)(\d+)(\d)/.match(str).post_match str.taint
res.tainted?.should be_true res = /(.)(.)(\d+)(\d)/.match(str).post_match
$'.tainted?.should be_true res.tainted?.should be_true
end $'.tainted?.should be_true
end
it "keeps untrusted status from the source string" do it "keeps untrusted status from the source string" do
str = "THX1138: The Movie" str = "THX1138: The Movie"
str.untrust str.untrust
res = /(.)(.)(\d+)(\d)/.match(str).post_match res = /(.)(.)(\d+)(\d)/.match(str).post_match
res.untrusted?.should be_true res.untrusted?.should be_true
$'.untrusted?.should be_true $'.untrusted?.should be_true
end
end end
it "sets the encoding to the encoding of the source String" do it "sets the encoding to the encoding of the source String" do

View file

@ -6,20 +6,22 @@ describe "MatchData#pre_match" do
$`.should == 'T' $`.should == 'T'
end end
it "keeps taint status from the source string" do ruby_version_is ''...'2.7' do
str = "THX1138: The Movie" it "keeps taint status from the source string" do
str.taint str = "THX1138: The Movie"
res = /(.)(.)(\d+)(\d)/.match(str).pre_match str.taint
res.tainted?.should be_true res = /(.)(.)(\d+)(\d)/.match(str).pre_match
$`.tainted?.should be_true res.tainted?.should be_true
end $`.tainted?.should be_true
end
it "keeps untrusted status from the source string" do it "keeps untrusted status from the source string" do
str = "THX1138: The Movie" str = "THX1138: The Movie"
str.untrust str.untrust
res = /(.)(.)(\d+)(\d)/.match(str).pre_match res = /(.)(.)(\d+)(\d)/.match(str).pre_match
res.untrusted?.should be_true res.untrusted?.should be_true
$`.untrusted?.should be_true $`.untrusted?.should be_true
end
end end
it "sets the encoding to the encoding of the source String" do it "sets the encoding to the encoding of the source String" do

View file

@ -47,16 +47,18 @@ describe "Module#append_features" do
end end
it "copies own tainted status to the given module" do ruby_version_is ''...'2.7' do
other = Module.new it "copies own tainted status to the given module" do
Module.new.taint.send :append_features, other other = Module.new
other.tainted?.should be_true Module.new.taint.send :append_features, other
end other.tainted?.should be_true
end
it "copies own untrusted status to the given module" do it "copies own untrusted status to the given module" do
other = Module.new other = Module.new
Module.new.untrust.send :append_features, other Module.new.untrust.send :append_features, other
other.untrusted?.should be_true other.untrusted?.should be_true
end
end end
describe "when other is frozen" do describe "when other is frozen" do

View file

@ -42,16 +42,18 @@ describe "Module#extend_object" do
ScratchPad.recorded.should == :extended ScratchPad.recorded.should == :extended
end end
it "does not copy own tainted status to the given object" do ruby_version_is ''...'2.7' do
other = Object.new it "does not copy own tainted status to the given object" do
Module.new.taint.send :extend_object, other other = Object.new
other.tainted?.should be_false Module.new.taint.send :extend_object, other
end other.tainted?.should be_false
end
it "does not copy own untrusted status to the given object" do it "does not copy own untrusted status to the given object" do
other = Object.new other = Object.new
Module.new.untrust.send :extend_object, other Module.new.untrust.send :extend_object, other
other.untrusted?.should be_false other.untrusted?.should be_false
end
end end
describe "when given a frozen object" do describe "when given a frozen object" do

View file

@ -28,16 +28,18 @@ describe "Module#prepend_features" do
}.should raise_error(ArgumentError) }.should raise_error(ArgumentError)
end end
it "copies own tainted status to the given module" do ruby_version_is ''...'2.7' do
other = Module.new it "copies own tainted status to the given module" do
Module.new.taint.send :prepend_features, other other = Module.new
other.tainted?.should be_true Module.new.taint.send :prepend_features, other
end other.tainted?.should be_true
end
it "copies own untrusted status to the given module" do it "copies own untrusted status to the given module" do
other = Module.new other = Module.new
Module.new.untrust.send :prepend_features, other Module.new.untrust.send :prepend_features, other
other.untrusted?.should be_true other.untrusted?.should be_true
end
end end
it "clears caches of the given module" do it "clears caches of the given module" do

View file

@ -12,15 +12,17 @@ describe "Range#inspect" do
(0.5..2.4).inspect.should == "0.5..2.4" (0.5..2.4).inspect.should == "0.5..2.4"
end end
it "returns a tainted string if either end is tainted" do ruby_version_is ''...'2.7' do
(("a".taint)..."c").inspect.tainted?.should be_true it "returns a tainted string if either end is tainted" do
("a"...("c".taint)).inspect.tainted?.should be_true (("a".taint)..."c").inspect.tainted?.should be_true
("a"..."c").taint.inspect.tainted?.should be_true ("a"...("c".taint)).inspect.tainted?.should be_true
end ("a"..."c").taint.inspect.tainted?.should be_true
end
it "returns a untrusted string if either end is untrusted" do it "returns a untrusted string if either end is untrusted" do
(("a".untrust)..."c").inspect.untrusted?.should be_true (("a".untrust)..."c").inspect.untrusted?.should be_true
("a"...("c".untrust)).inspect.untrusted?.should be_true ("a"...("c".untrust)).inspect.untrusted?.should be_true
("a"..."c").untrust.inspect.untrusted?.should be_true ("a"..."c").untrust.inspect.untrusted?.should be_true
end
end end
end end

View file

@ -11,15 +11,17 @@ describe "Range#to_s" do
(0.5..2.4).to_s.should == "0.5..2.4" (0.5..2.4).to_s.should == "0.5..2.4"
end end
it "returns a tainted string if either end is tainted" do ruby_version_is ''...'2.7' do
(("a".taint)..."c").to_s.tainted?.should be_true it "returns a tainted string if either end is tainted" do
("a"...("c".taint)).to_s.tainted?.should be_true (("a".taint)..."c").to_s.tainted?.should be_true
("a"..."c").taint.to_s.tainted?.should be_true ("a"...("c".taint)).to_s.tainted?.should be_true
end ("a"..."c").taint.to_s.tainted?.should be_true
end
it "returns a untrusted string if either end is untrusted" do it "returns a untrusted string if either end is untrusted" do
(("a".untrust)..."c").to_s.untrusted?.should be_true (("a".untrust)..."c").to_s.untrusted?.should be_true
("a"...("c".untrust)).to_s.untrusted?.should be_true ("a"...("c".untrust)).to_s.untrusted?.should be_true
("a"..."c").untrust.to_s.untrusted?.should be_true ("a"..."c").untrust.to_s.untrusted?.should be_true
end
end end
end end

View file

@ -13,10 +13,12 @@ describe "String#b" do
str.should == "こんちには" str.should == "こんちには"
end end
it "copies own tainted/untrusted status to the returning value" do ruby_version_is ''...'2.7' do
utf_8 = "こんちには".taint.untrust it "copies own tainted/untrusted status to the returning value" do
ret = utf_8.b utf_8 = "こんちには".taint.untrust
ret.tainted?.should be_true ret = utf_8.b
ret.untrusted?.should be_true ret.tainted?.should be_true
ret.untrusted?.should be_true
end
end end
end end

View file

@ -12,9 +12,11 @@ describe "String#capitalize" do
"123ABC".capitalize.should == "123abc" "123ABC".capitalize.should == "123abc"
end end
it "taints resulting string when self is tainted" do ruby_version_is ''...'2.7' do
"".taint.capitalize.tainted?.should == true it "taints resulting string when self is tainted" do
"hello".taint.capitalize.tainted?.should == true "".taint.capitalize.tainted?.should == true
"hello".taint.capitalize.tainted?.should == true
end
end end
describe "full Unicode case mapping" do describe "full Unicode case mapping" do

View file

@ -47,12 +47,14 @@ describe "String#center with length, padding" do
"radiology".center(8, '-').should == "radiology" "radiology".center(8, '-').should == "radiology"
end end
it "taints result when self or padstr is tainted" do ruby_version_is ''...'2.7' do
"x".taint.center(4).tainted?.should == true it "taints result when self or padstr is tainted" do
"x".taint.center(0).tainted?.should == true "x".taint.center(4).tainted?.should == true
"".taint.center(0).tainted?.should == true "x".taint.center(0).tainted?.should == true
"x".taint.center(4, "*").tainted?.should == true "".taint.center(0).tainted?.should == true
"x".center(4, "*".taint).tainted?.should == true "x".taint.center(4, "*").tainted?.should == true
"x".center(4, "*".taint).tainted?.should == true
end
end end
it "calls #to_int to convert length to an integer" do it "calls #to_int to convert length to an integer" do
@ -98,10 +100,12 @@ describe "String#center with length, padding" do
"foo".center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String) "foo".center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
end end
it "when padding is tainted and self is untainted returns a tainted string if and only if length is longer than self" do ruby_version_is ''...'2.7' do
"hello".center(4, 'X'.taint).tainted?.should be_false it "when padding is tainted and self is untainted returns a tainted string if and only if length is longer than self" do
"hello".center(5, 'X'.taint).tainted?.should be_false "hello".center(4, 'X'.taint).tainted?.should be_false
"hello".center(6, 'X'.taint).tainted?.should be_true "hello".center(5, 'X'.taint).tainted?.should be_false
"hello".center(6, 'X'.taint).tainted?.should be_true
end
end end
describe "with width" do describe "with width" do

View file

@ -38,8 +38,10 @@ describe "String#chomp" do
"".chomp.should == "" "".chomp.should == ""
end end
it "taints the result if self is tainted" do ruby_version_is ''...'2.7' do
"abc".taint.chomp.tainted?.should be_true it "taints the result if self is tainted" do
"abc".taint.chomp.tainted?.should be_true
end
end end
it "returns subclass instances when called on a subclass" do it "returns subclass instances when called on a subclass" do
@ -63,8 +65,10 @@ describe "String#chomp" do
str.chomp(nil).should_not equal(str) str.chomp(nil).should_not equal(str)
end end
it "taints the result if self is tainted" do ruby_version_is ''...'2.7' do
"abc".taint.chomp(nil).tainted?.should be_true it "taints the result if self is tainted" do
"abc".taint.chomp(nil).tainted?.should be_true
end
end end
it "returns an empty String when self is empty" do it "returns an empty String when self is empty" do
@ -93,8 +97,10 @@ describe "String#chomp" do
"abc\r\n\r\n\r\n".chomp("").should == "abc" "abc\r\n\r\n\r\n".chomp("").should == "abc"
end end
it "taints the result if self is tainted" do ruby_version_is ''...'2.7' do
"abc".taint.chomp("").tainted?.should be_true it "taints the result if self is tainted" do
"abc".taint.chomp("").tainted?.should be_true
end
end end
it "returns an empty String when self is empty" do it "returns an empty String when self is empty" do
@ -115,8 +121,10 @@ describe "String#chomp" do
"abc\r\n\r\n".chomp("\n").should == "abc\r\n" "abc\r\n\r\n".chomp("\n").should == "abc\r\n"
end end
it "taints the result if self is tainted" do ruby_version_is ''...'2.7' do
"abc".taint.chomp("\n").tainted?.should be_true it "taints the result if self is tainted" do
"abc".taint.chomp("\n").tainted?.should be_true
end
end end
it "returns an empty String when self is empty" do it "returns an empty String when self is empty" do
@ -151,12 +159,14 @@ describe "String#chomp" do
"".chomp("abc").should == "" "".chomp("abc").should == ""
end end
it "taints the result if self is tainted" do ruby_version_is ''...'2.7' do
"abc".taint.chomp("abc").tainted?.should be_true it "taints the result if self is tainted" do
end "abc".taint.chomp("abc").tainted?.should be_true
end
it "does not taint the result when the argument is tainted" do it "does not taint the result when the argument is tainted" do
"abc".chomp("abc".taint).tainted?.should be_false "abc".chomp("abc".taint).tainted?.should be_false
end
end end
it "returns an empty String when the argument equals self" do it "returns an empty String when the argument equals self" do
@ -201,8 +211,10 @@ describe "String#chomp!" do
"".chomp!.should be_nil "".chomp!.should be_nil
end end
it "taints the result if self is tainted" do ruby_version_is ''...'2.7' do
"abc\n".taint.chomp!.tainted?.should be_true it "taints the result if self is tainted" do
"abc\n".taint.chomp!.tainted?.should be_true
end
end end
it "returns subclass instances when called on a subclass" do it "returns subclass instances when called on a subclass" do
@ -247,8 +259,10 @@ describe "String#chomp!" do
"abc\r\n\r\n\r\n".chomp!("").should == "abc" "abc\r\n\r\n\r\n".chomp!("").should == "abc"
end end
it "taints the result if self is tainted" do ruby_version_is ''...'2.7' do
"abc\n".taint.chomp!("").tainted?.should be_true it "taints the result if self is tainted" do
"abc\n".taint.chomp!("").tainted?.should be_true
end
end end
it "returns nil when self is empty" do it "returns nil when self is empty" do
@ -269,8 +283,10 @@ describe "String#chomp!" do
"abc\r\n\r\n".chomp!("\n").should == "abc\r\n" "abc\r\n\r\n".chomp!("\n").should == "abc\r\n"
end end
it "taints the result if self is tainted" do ruby_version_is ''...'2.7' do
"abc\n".taint.chomp!("\n").tainted?.should be_true it "taints the result if self is tainted" do
"abc\n".taint.chomp!("\n").tainted?.should be_true
end
end end
it "returns nil when self is empty" do it "returns nil when self is empty" do
@ -305,12 +321,14 @@ describe "String#chomp!" do
"".chomp!("abc").should be_nil "".chomp!("abc").should be_nil
end end
it "taints the result if self is tainted" do ruby_version_is ''...'2.7' do
"abc".taint.chomp!("abc").tainted?.should be_true it "taints the result if self is tainted" do
end "abc".taint.chomp!("abc").tainted?.should be_true
end
it "does not taint the result when the argument is tainted" do it "does not taint the result when the argument is tainted" do
"abc".chomp!("abc".taint).tainted?.should be_false "abc".chomp!("abc".taint).tainted?.should be_false
end
end end
end end

View file

@ -49,14 +49,16 @@ describe "String#chop" do
s.chop.should_not equal(s) s.chop.should_not equal(s)
end end
it "taints result when self is tainted" do ruby_version_is ''...'2.7' do
"hello".taint.chop.tainted?.should == true it "taints result when self is tainted" do
"".taint.chop.tainted?.should == true "hello".taint.chop.tainted?.should == true
end "".taint.chop.tainted?.should == true
end
it "untrusts result when self is untrusted" do it "untrusts result when self is untrusted" do
"hello".untrust.chop.untrusted?.should == true "hello".untrust.chop.untrusted?.should == true
"".untrust.chop.untrusted?.should == true "".untrust.chop.untrusted?.should == true
end
end end
it "returns subclass instances when called on a subclass" do it "returns subclass instances when called on a subclass" do

View file

@ -25,17 +25,19 @@ describe "String#crypt" do
"mypassword".crypt(obj).should == "$2a$04$0WVaz0pV3jzfZ5G5tpmHWuBQGbkjzgtSc3gJbmdy0GAGMa45MFM2." "mypassword".crypt(obj).should == "$2a$04$0WVaz0pV3jzfZ5G5tpmHWuBQGbkjzgtSc3gJbmdy0GAGMa45MFM2."
end end
it "taints the result if either salt or self is tainted" do ruby_version_is ''...'2.7' do
tainted_salt = "$2a$04$0WVaz0pV3jzfZ5G5tpmHWu" it "taints the result if either salt or self is tainted" do
tainted_str = "mypassword" tainted_salt = "$2a$04$0WVaz0pV3jzfZ5G5tpmHWu"
tainted_str = "mypassword"
tainted_salt.taint tainted_salt.taint
tainted_str.taint tainted_str.taint
"mypassword".crypt("$2a$04$0WVaz0pV3jzfZ5G5tpmHWu").tainted?.should == false "mypassword".crypt("$2a$04$0WVaz0pV3jzfZ5G5tpmHWu").tainted?.should == false
tainted_str.crypt("$2a$04$0WVaz0pV3jzfZ5G5tpmHWu").tainted?.should == true tainted_str.crypt("$2a$04$0WVaz0pV3jzfZ5G5tpmHWu").tainted?.should == true
"mypassword".crypt(tainted_salt).tainted?.should == true "mypassword".crypt(tainted_salt).tainted?.should == true
tainted_str.crypt(tainted_salt).tainted?.should == true tainted_str.crypt(tainted_salt).tainted?.should == true
end
end end
it "doesn't return subclass instances" do it "doesn't return subclass instances" do
@ -83,17 +85,19 @@ describe "String#crypt" do
"".crypt(obj).should == "aaQSqAReePlq6" "".crypt(obj).should == "aaQSqAReePlq6"
end end
it "taints the result if either salt or self is tainted" do ruby_version_is ''...'2.7' do
tainted_salt = "aa" it "taints the result if either salt or self is tainted" do
tainted_str = "hello" tainted_salt = "aa"
tainted_str = "hello"
tainted_salt.taint tainted_salt.taint
tainted_str.taint tainted_str.taint
"hello".crypt("aa").tainted?.should == false "hello".crypt("aa").tainted?.should == false
tainted_str.crypt("aa").tainted?.should == true tainted_str.crypt("aa").tainted?.should == true
"hello".crypt(tainted_salt).tainted?.should == true "hello".crypt(tainted_salt).tainted?.should == true
tainted_str.crypt(tainted_salt).tainted?.should == true tainted_str.crypt(tainted_salt).tainted?.should == true
end
end end
it "doesn't return subclass instances" do it "doesn't return subclass instances" do

View file

@ -22,9 +22,11 @@ ruby_version_is '2.5' do
r.should == s r.should == s
end end
it "taints resulting strings when other is tainted" do ruby_version_is ''...'2.7' do
'hello'.taint.delete_prefix('hell').tainted?.should == true it "taints resulting strings when other is tainted" do
'hello'.taint.delete_prefix('').tainted?.should == true 'hello'.taint.delete_prefix('hell').tainted?.should == true
'hello'.taint.delete_prefix('').tainted?.should == true
end
end end
it "doesn't set $~" do it "doesn't set $~" do

Some files were not shown because too many files have changed in this diff Show more