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

View file

@ -128,10 +128,10 @@ EOU
exit 2 unless src
trim = trim_mode_opt(trim_mode, disable_percent)
if safe_level.nil?
erb = factory.new(src.untaint, trim_mode: trim)
erb = factory.new(src, trim_mode: trim)
else
# [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
erb.filename = filename
if output
@ -143,7 +143,7 @@ EOU
puts erb.src
end
else
bind = TOPLEVEL_BINDING.taint
bind = TOPLEVEL_BINDING
if variables
enc = erb.encoding
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_M_TBL_INIT(klass);
OBJ_INFECT(klass, super);
return (VALUE)klass;
}
@ -511,8 +510,6 @@ make_metaclass(VALUE klass)
while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super);
RCLASS_SET_SUPER(metaclass, super ? ENSURE_EIGENCLASS(super) : rb_cClass);
OBJ_INFECT(metaclass, RCLASS_SUPER(metaclass));
return metaclass;
}
@ -851,8 +848,6 @@ rb_include_class_new(VALUE module, VALUE super)
else {
RBASIC_SET_CLASS(klass, module);
}
OBJ_INFECT(klass, module);
OBJ_INFECT(klass, super);
return (VALUE)klass;
}
@ -867,7 +862,6 @@ ensure_includable(VALUE klass, VALUE module)
if (!NIL_P(rb_refinement_module_get_refined_class(module))) {
rb_raise(rb_eArgError, "refinement module is not allowed");
}
OBJ_INFECT(klass, module);
}
void
@ -1660,12 +1654,6 @@ singleton_class_of(VALUE obj)
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));
return klass;

4
dir.c
View file

@ -1129,9 +1129,8 @@ rb_dir_getwd_ospath(void)
DATA_PTR(path_guard) = path;
#ifdef __APPLE__
cwd = rb_str_normalize_ospath(path, strlen(path));
OBJ_TAINT(cwd);
#else
cwd = rb_tainted_str_new2(path);
cwd = rb_str_new2(path);
#endif
DATA_PTR(path_guard) = 0;
@ -2564,7 +2563,6 @@ push_pattern(const char *path, VALUE ary, void *enc)
#if defined _WIN32 || defined __APPLE__
VALUE name = rb_utf8_str_new_cstr(path);
rb_encoding *eenc = rb_default_internal_encoding();
OBJ_TAINT(name);
name = rb_str_conv_enc(name, NULL, eenc ? eenc : enc);
#else
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);
++s;
}
FL_UNSET(enclib, FL_TAINT);
enclib = rb_fstring(enclib);
ruby_verbose = 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();
rb_block_call(obj, id_each, argc, argv, collect_all, ary);
OBJ_INFECT(ary, obj);
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();
rb_block_call(obj, id_each, argc, argv, iter, hash);
OBJ_INFECT(hash, obj);
return hash;
}
@ -1245,7 +1243,6 @@ enum_sort_by(VALUE obj)
buf = rb_ary_tmp_new(SORT_BY_BUFSIZE*2);
rb_ary_store(buf, SORT_BY_BUFSIZE*2-1, Qnil);
memo = MEMO_NEW(0, 0, 0);
OBJ_INFECT(memo, obj);
data = (struct sort_by_data *)&memo->v1;
RB_OBJ_WRITE(memo, &data->ary, ary);
RB_OBJ_WRITE(memo, &data->buf, buf);
@ -1270,7 +1267,6 @@ enum_sort_by(VALUE obj)
}
rb_ary_resize(ary, RARRAY_LEN(ary)/2);
RBASIC_SET_CLASS_RAW(ary, rb_cArray);
OBJ_INFECT(ary, memo);
return ary;
}

View file

@ -1077,7 +1077,6 @@ inspect_enumerator(VALUE obj, VALUE dummy, int recur)
if (recur) {
str = rb_sprintf("#<%"PRIsVALUE": ...>", rb_class_path(cname));
OBJ_TAINT(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_buf_cat2(str, ", ");
OBJ_INFECT(str, arg);
}
if (!NIL_P(kwds)) {
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_buf_cat2(str, ", ");
OBJ_INFECT(str, arg);
}
if (!NIL_P(kwds)) {
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);
rb_str_catf(errmsg, " - %"PRIsVALUE, str);
OBJ_INFECT(errmsg, mesg);
}
mesg = errmsg;
@ -2319,19 +2318,7 @@ syserr_eqq(VALUE self, VALUE exc)
/*
* Document-class: SecurityError
*
* Raised when attempting a potential unsafe operation, typically when
* 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
* No longer used by internal code.
*/
/*
@ -2971,12 +2958,14 @@ rb_check_frozen(VALUE obj)
void
rb_error_untrusted(VALUE obj)
{
rb_warning("rb_error_untrusted is deprecated and will be removed in Ruby 3.2.");
}
#undef rb_check_trusted
void
rb_check_trusted(VALUE obj)
{
rb_warning("rb_check_trusted is deprecated and will be removed in Ruby 3.2.");
}
void

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -110,7 +110,6 @@ path_initialize(VALUE self, VALUE arg)
str = rb_obj_dup(str);
set_strpath(self, str);
OBJ_INFECT(self, str);
return self;
}
@ -134,15 +133,12 @@ path_freeze(VALUE self)
* call-seq:
* pathname.taint -> obj
*
* Taints this Pathname.
*
* See Object.taint.
* Returns pathname. This method is deprecated and will be removed in Ruby 3.2.
*/
static VALUE
path_taint(VALUE self)
{
rb_call_super(0, 0);
rb_obj_taint(get_strpath(self));
rb_warning("Pathname#taint is deprecated and will be removed in Ruby 3.2.");
return self;
}
@ -150,15 +146,12 @@ path_taint(VALUE self)
* call-seq:
* pathname.untaint -> obj
*
* Untaints this Pathname.
*
* See Object.untaint.
* Returns pathname. This method is deprecated and will be removed in Ruby 3.2.
*/
static VALUE
path_untaint(VALUE self)
{
rb_call_super(0, 0);
rb_obj_untaint(get_strpath(self));
rb_warning("Pathname#untaint is deprecated and will be removed in Ruby 3.2.");
return self;
}
@ -308,7 +301,6 @@ path_sub_ext(VALUE self, VALUE repl)
}
str2 = rb_str_subseq(str, 0, ext-p);
rb_str_append(str2, repl);
OBJ_INFECT(str2, str);
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))
dat_str = rb_tainted_str_new(datbuf, ss);
dat_str = rb_str_new(datbuf, ss);
else {
rb_str_resize(dat_str, ss);
OBJ_TAINT(dat_str);
rb_obj_reveal(dat_str, rb_cString);
}
@ -1660,7 +1659,7 @@ bsock_recvmsg_internal(VALUE sock,
}
ctl_end = (char*)cmh + cmh->cmsg_len;
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)
make_io_for_unix_rights(ctl, cmh, msg_end);
else

View file

@ -143,7 +143,7 @@ rsock_strbuf(VALUE str, long buflen)
{
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);
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)) {
rb_str_set_len(str, slen);
}
rb_obj_taint(str);
switch (from) {
case RECV_RECV:
return str;
@ -282,7 +281,6 @@ rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str,
if (slen != RSTRING_LEN(str)) {
rb_str_set_len(str, slen);
}
rb_obj_taint(str);
switch (from) {
case RECV_RECV:
return str;
@ -329,7 +327,6 @@ rsock_read_nonblock(VALUE sock, VALUE length, VALUE buf, VALUE ex)
VALUE str = rsock_strbuf(buf, len);
char *ptr;
OBJ_TAINT(str);
GetOpenFile(sock, fptr);
if (len == 0) {

View file

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

View file

@ -1164,7 +1164,7 @@ sock_s_getservbyport(int argc, VALUE *argv, VALUE _)
if (!sp) {
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);
rb_freeaddrinfo(res);
OBJ_INFECT(addr, port);
OBJ_INFECT(addr, host);
return addr;
}
@ -1457,7 +1455,6 @@ sock_s_unpack_sockaddr_in(VALUE self, VALUE addr)
#endif
}
host = rsock_make_ipaddr((struct sockaddr*)sockaddr, RSTRING_SOCKLEN(addr));
OBJ_INFECT(host, addr);
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));
addr = rb_str_new((char*)&sockaddr, rsock_unix_sockaddr_len(path));
OBJ_INFECT(addr, path);
return addr;
}
@ -1524,7 +1520,6 @@ sock_s_unpack_sockaddr_un(VALUE self, VALUE addr)
RSTRING_LEN(addr), (int)sizeof(struct sockaddr_un));
}
path = rsock_unixpath_str(sockaddr, RSTRING_SOCKLEN(addr));
OBJ_INFECT(path, addr);
return path;
}
#endif

16
file.c
View file

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

5
gc.c
View file

@ -3288,9 +3288,6 @@ static VALUE
run_single_final(VALUE final, VALUE objid)
{
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);
}
@ -10486,8 +10483,6 @@ wmap_inspect_i(st_data_t key, st_data_t val, st_data_t arg)
rb_str_cat2(str, " => ");
v = SPECIAL_CONST_P(v) ? rb_inspect(v) : rb_any_to_s(v);
rb_str_append(str, v);
OBJ_INFECT(str, k);
OBJ_INFECT(str, v);
return ST_CONTINUE;
}

53
hash.c
View file

@ -40,7 +40,7 @@
#define HAS_EXTRA_STATES(hash, klass) ( \
((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)))
#define SET_DEFAULT(hash, ifnone) ( \
@ -1554,7 +1554,7 @@ rb_hash_dup(VALUE hash)
{
const VALUE flags = RBASIC(hash)->flags;
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)
rb_copy_generic_ivar(ret, hash);
return ret;
@ -2744,7 +2744,7 @@ hash_aset(st_data_t *key, st_data_t *val, struct update_arg *arg, int existing)
VALUE
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);
}
else {
@ -3200,7 +3200,6 @@ rb_hash_to_a(VALUE hash)
ary = rb_ary_new_capa(RHASH_SIZE(hash));
rb_hash_foreach(hash, to_a_i, ary);
OBJ_INFECT(ary, hash);
return ary;
}
@ -3218,11 +3217,9 @@ inspect_i(VALUE key, VALUE value, VALUE str)
rb_enc_copy(str, str2);
}
rb_str_buf_append(str, str2);
OBJ_INFECT(str, str2);
rb_str_buf_cat_ascii(str, "=>");
str2 = rb_inspect(value);
rb_str_buf_append(str, str2);
OBJ_INFECT(str, str2);
return ST_CONTINUE;
}
@ -3236,7 +3233,6 @@ inspect_hash(VALUE hash, VALUE dummy, int recur)
str = rb_str_buf_new2("{");
rb_hash_foreach(hash, inspect_i, str);
rb_str_buf_cat2(str, "}");
OBJ_INFECT(str, hash);
return str;
}
@ -3303,7 +3299,6 @@ rb_hash_to_h_block(VALUE hash)
{
VALUE h = rb_hash_new_with_size(RHASH_SIZE(hash));
rb_hash_foreach(hash, to_h_i, h);
OBJ_INFECT(h, hash);
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;
#ifdef _WIN32
#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);
#endif
OBJ_TAINT(str);
rb_obj_freeze(str);
return str;
}
@ -4639,15 +4631,13 @@ env_str_new2(const char *ptr)
return env_str_new(ptr, strlen(ptr));
}
static int env_path_tainted(const char *);
static const char TZ_ENV[] = "TZ";
extern bool ruby_tz_uptodate_p;
static rb_encoding *
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();
}
else {
@ -4725,7 +4715,6 @@ env_delete(VALUE name)
ruby_setenv(nam, 0);
if (ENVMATCH(nam, PATH_ENV)) {
RB_GC_GUARD(name);
path_tainted = 0;
}
else if (ENVMATCH(nam, TZ_ENV)) {
ruby_tz_uptodate_p = FALSE;
@ -4842,28 +4831,11 @@ env_fetch(int argc, VALUE *argv, VALUE _)
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
rb_env_path_tainted(void)
{
if (path_tainted < 0) {
path_tainted_p(getenv(PATH_ENV));
}
return path_tainted;
rb_warning("rb_env_path_tainted is deprecated and will be removed in Ruby 3.2.");
return 0;
}
#if defined(_WIN32) || (defined(HAVE_SETENV) && defined(HAVE_UNSETENV))
@ -5133,14 +5105,6 @@ env_aset(VALUE nm, VALUE val)
ruby_setenv(name, value);
if (ENVMATCH(name, PATH_ENV)) {
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)) {
ruby_tz_uptodate_p = FALSE;
@ -5342,7 +5306,6 @@ env_reject_bang(VALUE ehash)
VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
if (!NIL_P(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));
del++;
}
@ -5452,7 +5415,6 @@ env_select_bang(VALUE ehash)
VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
if (!NIL_P(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));
del++;
}
@ -5581,7 +5543,6 @@ env_inspect(VALUE _)
}
FREE_ENVIRON(environ);
rb_str_buf_cat2(str, "}");
OBJ_TAINT(str);
return str;
}
@ -5755,7 +5716,7 @@ env_rassoc(VALUE dmy, VALUE obj)
if (s++) {
long len = strlen(s);
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);
return result;
}

View file

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

8
io.c
View file

@ -2525,7 +2525,6 @@ remain_size(rb_io_t *fptr)
static VALUE
io_enc_str(VALUE str, rb_io_t *fptr)
{
OBJ_TAINT(str);
rb_enc_associate(str, io_read_encoding(fptr));
return str;
}
@ -2655,7 +2654,6 @@ io_shift_cbuf(rb_io_t *fptr, int len, VALUE *strp)
else {
rb_str_cat(str, fptr->cbuf.ptr+fptr->cbuf.off, len);
}
OBJ_TAINT(str);
rb_enc_associate(str, fptr->encs.enc);
}
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);
OBJ_TAINT(str);
GetOpenFile(io, 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);
OBJ_TAINT(str);
rb_bool_expected(ex, "exception");
GetOpenFile(io, fptr);
@ -3150,7 +3146,6 @@ io_read(int argc, VALUE *argv, VALUE io)
}
#endif
if (n == 0) return Qnil;
OBJ_TAINT(str);
return str;
}
@ -5185,7 +5180,6 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
if (n == 0 && ilen > 0) {
rb_eof_error();
}
OBJ_TAINT(str);
return str;
}
@ -5269,7 +5263,6 @@ rb_io_pread(int argc, VALUE *argv, VALUE io)
if (n == 0 && arg.count > 0) {
rb_eof_error();
}
OBJ_TAINT(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)) == '|') {
VALUE cmd = rb_str_new(s+chlen, l-chlen);
OBJ_INFECT(cmd, filename_or_command);
return cmd;
}
return Qnil;

View file

@ -544,11 +544,11 @@ class CGI
/Content-Disposition:.* filename=(?:"(.*?)"|([^;\r\n]*))/i.match(head)
filename = $1 || $2 || ''.dup
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: (.*)/i.match(head)
(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
/Content-Disposition:.* name=(?:"(.*?)"|([^;\r\n]*))/i.match(head)
name = $1 || $2 || ''

View file

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

View file

@ -219,37 +219,14 @@ class Delegator < BasicObject
end
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
# Freeze both the object returned by \_\_getobj\_\_ and self.
#
[:trust, :untrust, :taint, :untaint, :freeze].each do |method|
define_method method do
__getobj__.send(method)
def freeze
__getobj__.freeze
super()
end
end
@delegator_api = self.public_instance_methods
def self.public_api # :nodoc:

View file

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

View file

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

View file

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

View file

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

View file

@ -3238,7 +3238,7 @@ module Net
if atom
atom
else
symbol = flag.capitalize.untaint.intern
symbol = flag.capitalize.intern
@flag_symbols[symbol] = true
if @flag_symbols.length > IMAP.max_flag_count
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.
def guard_inspect_key
if Thread.current[:__recursive_key__] == nil
Thread.current[:__recursive_key__] = {}.compare_by_identity.taint
Thread.current[:__recursive_key__] = {}.compare_by_identity
end
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
save = Thread.current[:__recursive_key__][:inspect]
begin
Thread.current[:__recursive_key__][:inspect] = {}.compare_by_identity.taint
Thread.current[:__recursive_key__][:inspect] = {}.compare_by_identity
yield
ensure
Thread.current[:__recursive_key__][:inspect] = save

View file

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

View file

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

View file

@ -58,10 +58,9 @@
# == Singleton and Marshal
#
# By default Singleton's #_dump(depth) returns the empty string. Marshalling by
# default will strip state information, e.g. instance variables and taint
# state, from the instance. Classes using Singleton can provide custom
# _load(str) and _dump(depth) methods to retain some of the previous state of
# the instance.
# default will strip state information, e.g. instance variables from the instance.
# Classes using Singleton can provide custom _load(str) and _dump(depth) methods
# to retain some of the previous state of the instance.
#
# require 'singleton'
#
@ -82,7 +81,6 @@
# a = Example.instance
# a.keep = "keep this"
# a.strip = "get rid of this"
# a.taint
#
# 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);
}
#define MARSHAL_INFECTION FL_TAINT
STATIC_ASSERT(marshal_infection_is_int, MARSHAL_INFECTION == (int)MARSHAL_INFECTION);
struct dump_arg {
VALUE str, dest;
st_table *symbols;
st_table *data;
st_table *compat_tbl;
st_table *encodings;
int infection;
};
struct dump_call_arg {
@ -268,7 +264,6 @@ w_nbyte(const char *s, long n, struct dump_arg *arg)
{
VALUE buf = arg->str;
rb_str_buf_cat(buf, s, n);
RBASIC(buf)->flags |= arg->infection;
if (arg->dest && RSTRING_LEN(buf) >= BUFSIZ) {
rb_io_write(arg->dest, buf);
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)));
}
arg->infection |= (int)FL_TEST(obj, MARSHAL_INFECTION);
if (rb_obj_respond_to(obj, s_mdump, TRUE)) {
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->symbols = st_init_numtable();
arg->data = rb_init_identtable();
arg->infection = 0;
arg->compat_tbl = 0;
arg->encodings = 0;
arg->str = rb_str_buf_new(0);
@ -1116,7 +1108,6 @@ struct load_arg {
st_table *data;
VALUE proc;
st_table *compat_tbl;
int infection;
};
static VALUE
@ -1195,7 +1186,6 @@ r_byte1_buffered(struct load_arg *arg)
str = load_funcall(arg, arg->src, s_read, 1, &n);
if (NIL_P(str)) too_short();
StringValue(str);
arg->infection |= (int)FL_TEST(str, MARSHAL_INFECTION);
memcpy(arg->buf, RSTRING_PTR(str), RSTRING_LEN(str));
arg->offset = 0;
arg->buflen = RSTRING_LEN(str);
@ -1294,7 +1284,6 @@ r_bytes1(long len, struct load_arg *arg)
if (NIL_P(str)) too_short();
StringValue(str);
if (RSTRING_LEN(str) != len) too_short();
arg->infection |= (int)FL_TEST(str, MARSHAL_INFECTION);
return str;
}
@ -1325,7 +1314,6 @@ r_bytes1_buffered(long len, struct load_arg *arg)
tmp_len = RSTRING_LEN(tmp);
if (tmp_len < need_len) too_short();
arg->infection |= (int)FL_TEST(tmp, MARSHAL_INFECTION);
str = rb_str_new(arg->buf+arg->offset, buflen);
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 {
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;
}
@ -2117,25 +2099,22 @@ marshal_load(int argc, VALUE *argv, VALUE _)
VALUE
rb_marshal_load_with_proc(VALUE port, VALUE proc)
{
int major, minor, infection = 0;
int major, minor;
VALUE v;
VALUE wrapper; /* used to avoid memory leak in case of exception */
struct load_arg *arg;
v = rb_check_string_type(port);
if (!NIL_P(v)) {
infection = (int)FL_TEST(port, MARSHAL_INFECTION); /* original taintedness */
port = v;
}
else if (rb_respond_to(port, s_getbyte) && rb_respond_to(port, s_read)) {
rb_check_funcall(port, s_binmode, 0, 0);
infection = (int)FL_TAINT;
}
else {
io_needed();
}
wrapper = TypedData_Make_Struct(0, struct load_arg, &load_arg_data, arg);
arg->infection = infection;
arg->src = port;
arg->offset = 0;
arg->symbols = st_init_numtable();

2
node.h
View file

@ -175,7 +175,7 @@ typedef struct RNode {
#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,
* 8..14: nd_type,
* 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));
}
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_generic_ivar(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
* <i>obj</i> are copied, but not the objects they reference.
* #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.
*
* class Klass
@ -491,7 +491,6 @@ rb_obj_clone(VALUE obj)
*
* Produces a shallow copy of <i>obj</i>---the instance variables of
* <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
* 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;
rb_check_frozen(obj);
rb_check_trusted(obj);
if (TYPE(obj) != TYPE(orig) || rb_obj_class(obj) != rb_obj_class(orig)) {
rb_raise(rb_eTypeError, "initialize_copy should take same class object");
}
@ -659,7 +657,6 @@ rb_any_to_s(VALUE obj)
VALUE cname = rb_class_name(CLASS_OF(obj));
str = rb_sprintf("#<%"PRIsVALUE":%p>", cname, (void*)obj);
OBJ_INFECT(str, obj);
return str;
}
@ -728,7 +725,6 @@ inspect_obj(VALUE obj, VALUE str, int recur)
}
rb_str_cat2(str, ">");
RSTRING_PTR(str)[0] = '#';
OBJ_INFECT(str, obj);
return str;
}
@ -1164,26 +1160,15 @@ rb_obj_dummy1(VALUE _x, VALUE _y)
/**
* call-seq:
* obj.tainted? -> true or false
* obj.tainted? -> false
*
* Returns true if the object is tainted.
*
* 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
*++
* Returns false. This method is deprecated and will be removed in Ruby 3.2.
*/
VALUE
rb_obj_tainted(VALUE obj)
{
if (OBJ_TAINTED(obj))
return Qtrue;
rb_warning("Object#tainted? is deprecated and will be removed in Ruby 3.2.");
return Qfalse;
}
@ -1191,33 +1176,13 @@ rb_obj_tainted(VALUE obj)
* call-seq:
* obj.taint -> obj
*
* Mark the object as tainted.
*
* 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
*++
* Returns object. This method is deprecated and will be removed in Ruby 3.2.
*/
VALUE
rb_obj_taint(VALUE obj)
{
if (!OBJ_TAINTED(obj) && OBJ_TAINTABLE(obj)) {
rb_check_frozen(obj);
OBJ_TAINT(obj);
}
rb_warning("Object#taint is deprecated and will be removed in Ruby 3.2.");
return obj;
}
@ -1226,74 +1191,42 @@ rb_obj_taint(VALUE obj)
* call-seq:
* obj.untaint -> obj
*
* Removes the tainted mark from the object.
*
* 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
*++
* Returns object. This method is deprecated and will be removed in Ruby 3.2.
*/
VALUE
rb_obj_untaint(VALUE obj)
{
if (OBJ_TAINTED(obj)) {
rb_check_frozen(obj);
FL_UNSET(obj, FL_TAINT);
}
rb_warning("Object#untaint is deprecated and will be removed in Ruby 3.2.");
return obj;
}
/**
* call-seq:
* obj.untrusted? -> true or false
* obj.untrusted? -> false
*
* Deprecated method that is equivalent to #tainted?.
*--
* \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
*++
* Returns false. This method is deprecated and will be removed in Ruby 3.2.
*/
VALUE
rb_obj_untrusted(VALUE obj)
{
rb_warning("untrusted? is deprecated and its behavior is same as tainted?");
return rb_obj_tainted(obj);
rb_warning("Object#untrusted? is deprecated and will be removed in Ruby 3.2.");
return Qfalse;
}
/**
* call-seq:
* obj.untrust -> obj
*
* Deprecated method that is equivalent to #taint.
*--
* \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
*++
* Returns object. This method is deprecated and will be removed in Ruby 3.2.
*/
VALUE
rb_obj_untrust(VALUE obj)
{
rb_warning("untrust is deprecated and its behavior is same as taint");
return rb_obj_taint(obj);
rb_warning("Object#untrust is deprecated and will be removed in Ruby 3.2.");
return obj;
}
@ -1301,37 +1234,24 @@ rb_obj_untrust(VALUE obj)
* call-seq:
* obj.trust -> obj
*
* Deprecated method that is equivalent to #untaint.
*--
* \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
*++
* Returns object. This method is deprecated and will be removed in Ruby 3.2.
*/
VALUE
rb_obj_trust(VALUE obj)
{
rb_warning("trust is deprecated and its behavior is same as untaint");
return rb_obj_untaint(obj);
rb_warning("Object#trust is deprecated and will be removed in Ruby 3.2.");
return obj;
}
/**
* Convenient function to infect \a victim with the taintedness of \a carrier.
*
* 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
* Does nothing. This method is deprecated and will be removed in Ruby 3.2.
*/
void
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);
ptr = RSTRING_PTR(from);
plen = RSTRING_LEN(from);
OBJ_INFECT(res, from);
}
if (p[-1] == '*')
@ -657,7 +656,6 @@ pack_pack(rb_execution_context_t *ec, VALUE ary, VALUE fmt, VALUE buffer)
StringValue(from);
ptr = RSTRING_PTR(from);
plen = RSTRING_LEN(from);
OBJ_INFECT(res, from);
if (len == 0 && type == 'm') {
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 */
from = rb_obj_as_string(NEXTFROM);
OBJ_INFECT(res, from);
if (len <= 1)
len = 72;
qpencode(res, from, len);
@ -711,8 +708,6 @@ pack_pack(rb_execution_context_t *ec, VALUE ary, VALUE fmt, VALUE buffer)
}
else {
t = StringValuePtr(from);
OBJ_INFECT(res, from);
rb_obj_taint(from);
}
if (!associates) {
associates = rb_ary_new();
@ -764,7 +759,6 @@ pack_pack(rb_execution_context_t *ec, VALUE ary, VALUE fmt, VALUE buffer)
if (associates) {
str_associate(res, associates);
}
OBJ_INFECT(res, fmt);
switch (enc_info) {
case 1:
ENCODING_CODERANGE_SET(res, rb_usascii_encindex(), ENC_CODERANGE_7BIT);
@ -923,15 +917,6 @@ hex2num(char c)
# define AVOID_CC_BUG
#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 */
#define UNPACK_ARRAY 0
#define UNPACK_BLOCK 1
@ -1052,7 +1037,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
if (*t != ' ' && *t != '\0') break;
t--; len--;
}
UNPACK_PUSH(infected_str_new(s, len, str));
UNPACK_PUSH(rb_str_new(s, len));
s += end;
}
break;
@ -1063,7 +1048,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
if (len > send-s) len = send-s;
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++;
s = star ? t : s+len;
}
@ -1071,7 +1056,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
case 'a':
if (len > send - s) len = send - s;
UNPACK_PUSH(infected_str_new(s, len, str));
UNPACK_PUSH(rb_str_new(s, len));
s += len;
break;
@ -1086,7 +1071,6 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
len = (send - s) * 8;
bits = 0;
bitstr = rb_usascii_str_new(0, len);
OBJ_INFECT(bitstr, str);
t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) {
if (i & 7) bits >>= 1;
@ -1108,7 +1092,6 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
len = (send - s) * 8;
bits = 0;
bitstr = rb_usascii_str_new(0, len);
OBJ_INFECT(bitstr, str);
t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) {
if (i & 7) bits <<= 1;
@ -1130,7 +1113,6 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
len = (send - s) * 2;
bits = 0;
bitstr = rb_usascii_str_new(0, len);
OBJ_INFECT(bitstr, str);
t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) {
if (i & 1)
@ -1154,7 +1136,6 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
len = (send - s) * 2;
bits = 0;
bitstr = rb_usascii_str_new(0, len);
OBJ_INFECT(bitstr, str);
t = RSTRING_PTR(bitstr);
for (i=0; i<len; i++) {
if (i & 1)
@ -1366,7 +1347,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
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);
long total = 0;
@ -1421,7 +1402,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
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);
int a = -1,b = -1,c = 0,d = 0;
static signed char b64_xtable[256];
@ -1502,7 +1483,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
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;
int csum = 0;
int c1, c2;
@ -1571,7 +1552,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
while (p < pend) {
if (RB_TYPE_P(*p, T_STRING) && RSTRING_PTR(*p) == t) {
if (len < RSTRING_LEN(*p)) {
tmp = rb_tainted_str_new(t, len);
tmp = rb_str_new(t, len);
str_associate(tmp, a);
}
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);
rb_str_cat_cstr(str, ">");
OBJ_INFECT_RAW(str, self);
return str;
}
@ -1490,8 +1489,6 @@ mnew_missing(VALUE klass, VALUE obj, ID id, VALUE mclass)
RB_OBJ_WRITE(method, &data->me, me);
OBJ_INFECT(method, klass);
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->me, me);
OBJ_INFECT(method, klass);
return method;
}
@ -1691,7 +1687,6 @@ method_unbind(VALUE obj)
RB_OBJ_WRITE(method, &data->recv, Qundef);
RB_OBJ_WRITE(method, &data->klass, orig->klass);
RB_OBJ_WRITE(method, &data->me, rb_method_entry_clone(orig->me));
OBJ_INFECT(method, obj);
return method;
}
@ -2775,7 +2770,6 @@ method_inspect(VALUE method)
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
str = rb_sprintf("#<% "PRIsVALUE": ", rb_obj_class(method));
OBJ_INFECT_RAW(str, method);
mklass = data->klass;

View file

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

View file

@ -1853,7 +1853,6 @@ nurat_marshal_load(VALUE self, VALUE a)
VALUE num, den;
rb_check_frozen(self);
rb_check_trusted(self);
Check_Type(a, T_ARRAY);
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)
rb_str_buf_cat2(str, "n");
}
OBJ_INFECT(str, re);
return str;
}
@ -488,7 +487,6 @@ rb_reg_source(VALUE re)
rb_reg_check(re);
str = rb_str_dup(RREGEXP_SRC(re));
if (OBJ_TAINTED(re)) OBJ_TAINT(str);
return str;
}
@ -647,7 +645,6 @@ rb_reg_str_with_term(VALUE re, int term)
}
rb_enc_copy(str, re);
OBJ_INFECT(str, re);
return str;
}
@ -1337,7 +1334,6 @@ match_set_string(VALUE m, VALUE string, long pos, long len)
if (err) rb_memerror();
rmatch->regs.beg[0] = pos;
rmatch->regs.end[0] = pos + len;
OBJ_INFECT(match, string);
}
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);
if (err) rb_memerror();
}
else {
FL_UNSET(match, FL_TAINT);
}
if (set_backref_str) {
RMATCH(match)->str = rb_str_new4(str);
OBJ_INFECT(match, str);
}
RMATCH(match)->regexp = re;
rb_backref_set(match);
OBJ_INFECT(match, re);
return result;
}
@ -1685,18 +1675,12 @@ rb_reg_start_with_p(VALUE re, VALUE str)
onig_region_free(regs, 0);
if (err) rb_memerror();
}
else {
FL_UNSET(match, FL_TAINT);
}
RMATCH(match)->str = rb_str_new4(str);
OBJ_INFECT(match, str);
RMATCH(match)->regexp = re;
rb_backref_set(match);
OBJ_INFECT(match, re);
return true;
}
@ -1740,7 +1724,6 @@ rb_reg_nth_match(int nth, VALUE match)
end = END(nth);
len = end - start;
str = rb_str_subseq(RMATCH(match)->str, start, len);
OBJ_INFECT(str, match);
return str;
}
@ -1773,7 +1756,6 @@ rb_reg_match_pre(VALUE match)
regs = RMATCH_REGS(match);
if (BEG(0) == -1) return Qnil;
str = rb_str_subseq(RMATCH(match)->str, 0, BEG(0));
if (OBJ_TAINTED(match)) OBJ_TAINT(str);
return str;
}
@ -1803,7 +1785,6 @@ rb_reg_match_post(VALUE match)
str = RMATCH(match)->str;
pos = END(0);
str = rb_str_subseq(str, pos, RSTRING_LEN(str) - pos);
if (OBJ_TAINTED(match)) OBJ_TAINT(str);
return str;
}
@ -1855,7 +1836,6 @@ match_array(VALUE match, int start)
VALUE ary;
VALUE target;
int i;
int taint = OBJ_TAINTED(match);
match_check(match);
regs = RMATCH_REGS(match);
@ -1868,7 +1848,6 @@ match_array(VALUE match, int start)
}
else {
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);
}
}
@ -2129,8 +2108,6 @@ match_to_s(VALUE match)
match_check(match);
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;
}
@ -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,
options, err, sourcefile, sourceline);
OBJ_INFECT(obj, str);
if (ret == 0) reg_set_source(obj, str, str_enc);
return ret;
}
@ -3580,7 +3556,6 @@ rb_reg_quote(VALUE str)
t += rb_enc_mbcput(c, t, enc);
}
rb_str_resize(tmp, t - RSTRING_PTR(tmp));
OBJ_INFECT(tmp, str);
return tmp;
}

1
ruby.c
View file

@ -2227,7 +2227,6 @@ external_str_new_cstr(const char *p)
#if UTF8_PATH
VALUE str = rb_utf8_str_new_cstr(p);
str = str_conv_enc(str, NULL, rb_default_external_encoding());
OBJ_TAINT_RAW(str);
return str;
#else
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
#include "ruby/ruby.h"
@ -141,9 +136,6 @@ void
rb_check_safe_obj(VALUE x)
{
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

View file

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

View file

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

View file

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

View file

@ -41,6 +41,7 @@ describe "Array#concat" do
-> { ArraySpecs.frozen_array.concat([]) }.should raise_error(frozen_error_class)
end
ruby_version_is ''...'2.7' do
it "keeps tainted status" do
ary = [1, 2]
ary.taint
@ -96,6 +97,7 @@ describe "Array#concat" do
ary[2].untrusted?.should be_true
ary[3].untrusted?.should be_false
end
end
it "appends elements to an Array with enough capacity that has been shifted" do
ary = [1, 2, 3, 4, 5]

View file

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

View file

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

View file

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

View file

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

View file

@ -88,6 +88,7 @@ describe "Array#* with an integer" do
end
end
ruby_version_is ''...'2.7' do
it "copies the taint status of the original array even if the passed count is 0" do
ary = [1, 2, 3]
ary.taint
@ -126,6 +127,7 @@ describe "Array#* with an integer" do
(ary * 2).untrusted?.should == true
end
end
end
describe "Array#* with a string" do
it_behaves_like :array_join_with_string_separator, :*

View file

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

View file

@ -33,10 +33,12 @@ describe :array_pack_basic_non_float, shared: true do
[@obj, @obj].pack(d).should be_an_instance_of(String)
end
ruby_version_is ''...'2.7' do
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
describe :array_pack_basic_float, shared: true do
it "ignores whitespace in the format string" do
@ -49,10 +51,12 @@ describe :array_pack_basic_float, shared: true do
[1.2, 4.7].pack(d).should be_an_instance_of(String)
end
ruby_version_is ''...'2.7' do
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
describe :array_pack_no_platform, shared: true do
it "raises ArgumentError when the format modifier is '_'" do

View file

@ -1,4 +1,5 @@
describe :array_pack_taint, shared: true do
ruby_version_is ''...'2.7' do
it "returns a tainted string when a pack argument is tainted" do
["abcd".taint, 0x20].pack(pack_format("3C")).tainted?.should be_true
end
@ -31,3 +32,4 @@ describe :array_pack_taint, shared: true do
["abcd", 0x20].untrust.pack(pack_format("3C")).untrusted?.should be_false
end
end
end

View file

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

View file

@ -30,6 +30,7 @@ describe "Array#pop" do
array.pop.should == [1, 'two', 3.0, array, array, array, array]
end
ruby_version_is ''...'2.7' do
it "keeps taint status" do
a = [1, 2].taint
a.pop
@ -37,6 +38,7 @@ describe "Array#pop" do
a.pop
a.tainted?.should be_true
end
end
it "raises a #{frozen_error_class} on a frozen array" do
-> { ArraySpecs.frozen_array.pop }.should raise_error(frozen_error_class)
@ -46,6 +48,7 @@ describe "Array#pop" do
-> { ArraySpecs.empty_frozen_array.pop }.should raise_error(frozen_error_class)
end
ruby_version_is ''...'2.7' do
it "keeps untrusted status" do
a = [1, 2].untrust
a.pop
@ -53,6 +56,7 @@ describe "Array#pop" do
a.pop
a.untrusted?.should be_true
end
end
describe "passed a number n as an argument" do
it "removes and returns an array with the last n elements of the array" do
@ -132,6 +136,7 @@ describe "Array#pop" do
ArraySpecs::MyArray[1, 2, 3].pop(2).should be_an_instance_of(Array)
end
ruby_version_is ''...'2.7' do
it "returns an untainted array even if the array is tainted" do
ary = [1, 2].taint
ary.pop(2).tainted?.should be_false
@ -151,12 +156,14 @@ describe "Array#pop" do
ary.pop(2).untrusted?.should be_false
ary.pop(0).untrusted?.should be_false
end
end
it "raises a #{frozen_error_class} on a frozen array" do
-> { ArraySpecs.frozen_array.pop(2) }.should raise_error(frozen_error_class)
-> { ArraySpecs.frozen_array.pop(0) }.should raise_error(frozen_error_class)
end
ruby_version_is ''...'2.7' do
it "keeps untrusted status" do
a = [1, 2].untrust
a.pop(2)
@ -166,3 +173,4 @@ describe "Array#pop" do
end
end
end
end

View file

@ -18,6 +18,7 @@ describe :array_clone, shared: true do
b.__id__.should_not == a.__id__
end
ruby_version_is ''...'2.7' do
it "copies taint status from the original" do
a = [1, 2, 3, 4]
b = [1, 2, 3, 4]
@ -40,3 +41,4 @@ describe :array_clone, shared: true do
bb.untrusted?.should == false
end
end
end

View file

@ -42,6 +42,7 @@ describe :array_collect, shared: true do
}.should raise_error(ArgumentError)
end
ruby_version_is ''...'2.7' do
it "does not copy tainted status" do
a = [1, 2, 3]
a.taint
@ -53,6 +54,7 @@ describe :array_collect, shared: true do
a.untrust
a.send(@method){|x| x}.untrusted?.should be_false
end
end
before :all do
@object = [1, 2, 3, 4]
@ -94,6 +96,7 @@ describe :array_collect_b, shared: true do
a.should == ["1!", "2!", "3!"]
end
ruby_version_is ''...'2.7' do
it "keeps tainted status" do
a = [1, 2, 3]
a.taint
@ -108,6 +111,7 @@ describe :array_collect_b, shared: true do
a.send(@method){|x| x}
a.untrusted?.should be_true
end
end
describe "when frozen" do
it "raises a #{frozen_error_class}" do

View file

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

View file

@ -58,6 +58,7 @@ describe :array_join_with_default_separator, shared: true do
-> { ArraySpecs.empty_recursive_array.send(@method) }.should raise_error(ArgumentError)
end
ruby_version_is ''...'2.7' do
it "taints the result if the Array is tainted and non-empty" do
[1, 2].taint.send(@method).tainted?.should be_true
end
@ -85,6 +86,7 @@ describe :array_join_with_default_separator, shared: true do
s.should_receive(:to_s).and_return("str".untrust)
[s].send(@method).untrusted?.should be_true
end
end
it "uses the first encoding when other strings are compatible" do
ary1 = ArraySpecs.array_with_7bit_utf8_and_usascii_strings
@ -125,6 +127,7 @@ 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"
end
ruby_version_is ''...'2.7' do
describe "with a tainted separator" do
before :each do
@sep = ":".taint
@ -161,3 +164,4 @@ describe :array_join_with_string_separator, shared: true do
end
end
end
end

View file

@ -117,6 +117,7 @@ describe "Array#shift" do
ArraySpecs::MyArray[1, 2, 3].shift(2).should be_an_instance_of(Array)
end
ruby_version_is ''...'2.7' do
it "returns an untainted array even if the array is tainted" do
ary = [1, 2].taint
ary.shift(2).tainted?.should be_false
@ -132,3 +133,4 @@ describe "Array#shift" do
end
end
end
end

View file

@ -39,6 +39,37 @@ describe "Array#uniq" do
[x, y].uniq.should == [x, y]
end
ruby_version_is '2.7' do
it "compares elements with matching hash codes with #eql?" do
a = Array.new(2) do
obj = mock('0')
obj.should_receive(:hash).at_least(1).and_return(0)
def obj.eql?(o)
false
end
obj
end
a.uniq.should == a
a = Array.new(2) do
obj = mock('0')
obj.should_receive(:hash).at_least(1).and_return(0)
def obj.eql?(o)
true
end
obj
end
a.uniq.size.should == 1
end
end
ruby_version_is ''...'2.7' do
it "compares elements with matching hash codes with #eql?" do
a = Array.new(2) do
obj = mock('0')
@ -78,6 +109,7 @@ describe "Array#uniq" do
a[0].tainted?.should == true
a[1].tainted?.should == true
end
end
it "compares elements based on the value returned from the block" do
a = [1, 2, 3, 4]

View file

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

View file

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

View file

@ -31,6 +31,37 @@ describe 'Enumerable#uniq' do
[x, y].to_enum.uniq.should == [x, y]
end
ruby_version_is '2.7' do
it "compares elements with matching hash codes with #eql?" do
a = Array.new(2) do
obj = mock('0')
obj.should_receive(:hash).at_least(1).and_return(0)
def obj.eql?(o)
false
end
obj
end
a.uniq.should == a
a = Array.new(2) do
obj = mock('0')
obj.should_receive(:hash).at_least(1).and_return(0)
def obj.eql?(o)
true
end
obj
end
a.to_enum.uniq.size.should == 1
end
end
ruby_version_is ''...'2.7' do
it "compares elements with matching hash codes with #eql?" do
a = Array.new(2) do
obj = mock('0')
@ -70,6 +101,7 @@ describe 'Enumerable#uniq' do
a[0].tainted?.should == true
a[1].tainted?.should == true
end
end
context 'when yielded with multiple arguments' do
before :each do

View file

@ -32,11 +32,13 @@ describe "Hash#reject" do
HashSpecs::MyHash[1 => 2, 3 => 4].reject { true }.should be_kind_of(Hash)
end
ruby_version_is ''...'2.7' do
it "does not taint the resulting hash" do
h = { a: 1 }.taint
h.reject {false}.tainted?.should == false
end
end
end
it "processes entries with the same order as reject!" do
h = { a: 1, b: 2, c: 3, d: 4 }

View file

@ -149,6 +149,39 @@ describe :hash_eql_additional, shared: true do
h.send(@method, HashSpecs::MyHash[h]).should be_true
end
ruby_version_is '2.7' do
# Why isn't this true of eql? too ?
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)
def obj.eql?(o)
return true if self.equal?(o)
false
end
obj
end
{ a[0] => 1 }.send(@method, { a[1] => 1 }).should be_false
a = Array.new(2) do
obj = mock('0')
obj.should_receive(:hash).at_least(1).and_return(0)
def obj.eql?(o)
true
end
obj
end
{ a[0] => 1 }.send(@method, { a[1] => 1 }).should be_true
end
end
ruby_version_is ''...'2.7' do
# Why isn't this true of eql? too ?
it "compares keys with matching hash codes via eql?" do
a = Array.new(2) do
@ -190,6 +223,7 @@ describe :hash_eql_additional, shared: true do
a[0].tainted?.should be_true
a[1].tainted?.should be_true
end
end
it "compares the values in self to values in other hash" do
l_val = mock("left")

View file

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

View file

@ -27,6 +27,7 @@ describe "Hash#to_a" do
ent.should == pairs
end
ruby_version_is ''...'2.7' do
it "returns a tainted array if self is tainted" do
{}.taint.to_a.tainted?.should be_true
end
@ -35,3 +36,4 @@ describe "Hash#to_a" do
{}.untrust.to_a.untrusted?.should be_true
end
end
end

View file

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

View file

@ -108,9 +108,15 @@ describe "Kernel#clone" do
cloned.bar.should == ['a']
end
it 'copies frozen? and tainted?' do
o = ''.taint.freeze.clone
it 'copies frozen?' do
o = ''.freeze.clone
o.frozen?.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

View file

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

View file

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

View file

@ -2,6 +2,7 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Kernel#taint" do
ruby_version_is ''...'2.7' do
it "returns self" do
o = Object.new
o.taint.should equal(o)
@ -43,3 +44,4 @@ describe "Kernel#taint" do
end
end
end
end

View file

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

View file

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

View file

@ -2,6 +2,7 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Kernel#trust" do
ruby_version_is ''...'2.7' do
it "returns self" do
o = Object.new
o.trust.should equal(o)
@ -23,3 +24,4 @@ describe "Kernel#trust" do
o.trust.should equal(o)
end
end
end

View file

@ -2,6 +2,7 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Kernel#untaint" do
ruby_version_is ''...'2.7' do
it "returns self" do
o = Object.new
o.untaint.should equal(o)
@ -23,3 +24,4 @@ describe "Kernel#untaint" do
o.untaint.should equal(o)
end
end
end

View file

@ -2,6 +2,7 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Kernel#untrust" do
ruby_version_is ''...'2.7' do
it "returns self" do
o = Object.new
o.untrust.should equal(o)
@ -23,3 +24,4 @@ describe "Kernel#untrust" do
o.untrust.should equal(o)
end
end
end

View file

@ -2,6 +2,7 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Kernel#untrusted?" do
ruby_version_is ''...'2.7' do
it "returns the untrusted status of an object" do
o = mock('o')
o.untrusted?.should == false
@ -26,3 +27,4 @@ describe "Kernel#untrusted?" do
-> { d.untrust }.should_not raise_error(RuntimeError)
end
end
end

View file

@ -581,6 +581,7 @@ describe "Marshal.dump" do
-> { Marshal.dump(m) }.should raise_error(TypeError)
end
ruby_version_is ''...'2.7' do
it "returns an untainted string if object is untainted" do
Marshal.dump(Object.new).tainted?.should be_false
end
@ -605,3 +606,4 @@ describe "Marshal.dump" do
Marshal.dump([[Object.new.untrust]]).untrusted?.should be_true
end
end
end

View file

@ -182,6 +182,7 @@ describe :marshal_load, shared: true do
end
end
ruby_version_is ''...'2.7' do
it "returns an untainted object if source is untainted" do
x = Object.new
y = Marshal.send(@method, Marshal.dump(x))
@ -262,6 +263,7 @@ describe :marshal_load, shared: true do
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
MarshalSpec::DATA.each do |description, (object, marshal, attributes)|

View file

@ -6,6 +6,7 @@ describe "MatchData#post_match" do
$'.should == ': The Movie'
end
ruby_version_is ''...'2.7' do
it "keeps taint status from the source string" do
str = "THX1138: The Movie"
str.taint
@ -21,6 +22,7 @@ describe "MatchData#post_match" do
res.untrusted?.should be_true
$'.untrusted?.should be_true
end
end
it "sets the encoding to the encoding of the source String" do
str = "abc".force_encoding Encoding::EUC_JP

View file

@ -6,6 +6,7 @@ describe "MatchData#pre_match" do
$`.should == 'T'
end
ruby_version_is ''...'2.7' do
it "keeps taint status from the source string" do
str = "THX1138: The Movie"
str.taint
@ -21,6 +22,7 @@ describe "MatchData#pre_match" do
res.untrusted?.should be_true
$`.untrusted?.should be_true
end
end
it "sets the encoding to the encoding of the source String" do
str = "abc".force_encoding Encoding::EUC_JP

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -12,10 +12,12 @@ describe "String#capitalize" do
"123ABC".capitalize.should == "123abc"
end
ruby_version_is ''...'2.7' do
it "taints resulting string when self is tainted" do
"".taint.capitalize.tainted?.should == true
"hello".taint.capitalize.tainted?.should == true
end
end
describe "full Unicode case mapping" do
it "works for all of Unicode with no option" do

View file

@ -47,6 +47,7 @@ describe "String#center with length, padding" do
"radiology".center(8, '-').should == "radiology"
end
ruby_version_is ''...'2.7' do
it "taints result when self or padstr is tainted" do
"x".taint.center(4).tainted?.should == true
"x".taint.center(0).tainted?.should == true
@ -54,6 +55,7 @@ describe "String#center with length, padding" do
"x".taint.center(4, "*").tainted?.should == true
"x".center(4, "*".taint).tainted?.should == true
end
end
it "calls #to_int to convert length to an integer" do
"_".center(3.8, "^").should == "^_^"
@ -98,11 +100,13 @@ describe "String#center with length, padding" do
"foo".center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
end
ruby_version_is ''...'2.7' do
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(4, 'X'.taint).tainted?.should be_false
"hello".center(5, 'X'.taint).tainted?.should be_false
"hello".center(6, 'X'.taint).tainted?.should be_true
end
end
describe "with width" do
it "returns a String in the same encoding as the original" do

View file

@ -38,9 +38,11 @@ describe "String#chomp" do
"".chomp.should == ""
end
ruby_version_is ''...'2.7' do
it "taints the result if self is tainted" do
"abc".taint.chomp.tainted?.should be_true
end
end
it "returns subclass instances when called on a subclass" do
str = StringSpecs::MyString.new("hello\n").chomp
@ -63,9 +65,11 @@ describe "String#chomp" do
str.chomp(nil).should_not equal(str)
end
ruby_version_is ''...'2.7' do
it "taints the result if self is tainted" do
"abc".taint.chomp(nil).tainted?.should be_true
end
end
it "returns an empty String when self is empty" do
"".chomp(nil).should == ""
@ -93,9 +97,11 @@ describe "String#chomp" do
"abc\r\n\r\n\r\n".chomp("").should == "abc"
end
ruby_version_is ''...'2.7' do
it "taints the result if self is tainted" do
"abc".taint.chomp("").tainted?.should be_true
end
end
it "returns an empty String when self is empty" do
"".chomp("").should == ""
@ -115,9 +121,11 @@ describe "String#chomp" do
"abc\r\n\r\n".chomp("\n").should == "abc\r\n"
end
ruby_version_is ''...'2.7' do
it "taints the result if self is tainted" do
"abc".taint.chomp("\n").tainted?.should be_true
end
end
it "returns an empty String when self is empty" do
"".chomp("\n").should == ""
@ -151,6 +159,7 @@ describe "String#chomp" do
"".chomp("abc").should == ""
end
ruby_version_is ''...'2.7' do
it "taints the result if self is tainted" do
"abc".taint.chomp("abc").tainted?.should be_true
end
@ -158,6 +167,7 @@ describe "String#chomp" do
it "does not taint the result when the argument is tainted" do
"abc".chomp("abc".taint).tainted?.should be_false
end
end
it "returns an empty String when the argument equals self" do
"abc".chomp("abc").should == ""
@ -201,9 +211,11 @@ describe "String#chomp!" do
"".chomp!.should be_nil
end
ruby_version_is ''...'2.7' do
it "taints the result if self is tainted" do
"abc\n".taint.chomp!.tainted?.should be_true
end
end
it "returns subclass instances when called on a subclass" do
str = StringSpecs::MyString.new("hello\n").chomp!
@ -247,9 +259,11 @@ describe "String#chomp!" do
"abc\r\n\r\n\r\n".chomp!("").should == "abc"
end
ruby_version_is ''...'2.7' do
it "taints the result if self is tainted" do
"abc\n".taint.chomp!("").tainted?.should be_true
end
end
it "returns nil when self is empty" do
"".chomp!("").should be_nil
@ -269,9 +283,11 @@ describe "String#chomp!" do
"abc\r\n\r\n".chomp!("\n").should == "abc\r\n"
end
ruby_version_is ''...'2.7' do
it "taints the result if self is tainted" do
"abc\n".taint.chomp!("\n").tainted?.should be_true
end
end
it "returns nil when self is empty" do
"".chomp!("\n").should be_nil
@ -305,6 +321,7 @@ describe "String#chomp!" do
"".chomp!("abc").should be_nil
end
ruby_version_is ''...'2.7' do
it "taints the result if self is tainted" do
"abc".taint.chomp!("abc").tainted?.should be_true
end
@ -313,6 +330,7 @@ describe "String#chomp!" do
"abc".chomp!("abc".taint).tainted?.should be_false
end
end
end
it "raises a #{frozen_error_class} on a frozen instance when it is modified" do
a = "string\n\r"

View file

@ -49,6 +49,7 @@ describe "String#chop" do
s.chop.should_not equal(s)
end
ruby_version_is ''...'2.7' do
it "taints result when self is tainted" do
"hello".taint.chop.tainted?.should == true
"".taint.chop.tainted?.should == true
@ -58,6 +59,7 @@ describe "String#chop" do
"hello".untrust.chop.untrusted?.should == true
"".untrust.chop.untrusted?.should == true
end
end
it "returns subclass instances when called on a subclass" do
StringSpecs::MyString.new("hello\n").chop.should be_an_instance_of(StringSpecs::MyString)

View file

@ -25,6 +25,7 @@ describe "String#crypt" do
"mypassword".crypt(obj).should == "$2a$04$0WVaz0pV3jzfZ5G5tpmHWuBQGbkjzgtSc3gJbmdy0GAGMa45MFM2."
end
ruby_version_is ''...'2.7' do
it "taints the result if either salt or self is tainted" do
tainted_salt = "$2a$04$0WVaz0pV3jzfZ5G5tpmHWu"
tainted_str = "mypassword"
@ -37,6 +38,7 @@ describe "String#crypt" do
"mypassword".crypt(tainted_salt).tainted?.should == true
tainted_str.crypt(tainted_salt).tainted?.should == true
end
end
it "doesn't return subclass instances" do
StringSpecs::MyString.new("mypassword").crypt("$2a$04$0WVaz0pV3jzfZ5G5tpmHWu").should be_an_instance_of(String)
@ -83,6 +85,7 @@ describe "String#crypt" do
"".crypt(obj).should == "aaQSqAReePlq6"
end
ruby_version_is ''...'2.7' do
it "taints the result if either salt or self is tainted" do
tainted_salt = "aa"
tainted_str = "hello"
@ -95,6 +98,7 @@ describe "String#crypt" do
"hello".crypt(tainted_salt).tainted?.should == true
tainted_str.crypt(tainted_salt).tainted?.should == true
end
end
it "doesn't return subclass instances" do
StringSpecs::MyString.new("hello").crypt("aa").should be_an_instance_of(String)

View file

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

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