From 21dbe868f8d0445ed28f58bd4e9efce21551b040 Mon Sep 17 00:00:00 2001 From: nobu Date: Thu, 23 Jul 2015 01:25:49 +0000 Subject: string.c: taint flags * include/ruby/ruby.h: add raw FL macros, which assume always the argument object is not a special constant. * internal.h (STR_EMBED_P, STR_SHARED_P): valid only for T_STRING. * string.c: deal with taint flags directly across String instances. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51353 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 9 +++++++++ include/ruby/ruby.h | 18 +++++++++++++----- internal.h | 4 ++-- string.c | 37 +++++++++++++++++-------------------- 4 files changed, 41 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3500817f98..5aba460930 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Thu Jul 23 10:25:46 2015 Nobuyoshi Nakada + + * include/ruby/ruby.h: add raw FL macros, which assume always the + argument object is not a special constant. + + * internal.h (STR_EMBED_P, STR_SHARED_P): valid only for T_STRING. + + * string.c: deal with taint flags directly across String instances. + Thu Jul 23 09:05:28 2015 Nobuyoshi Nakada * parse.y (lambda_body): pop cmdarg stack for lookahead diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index bad0b3f1cc..8405f4c624 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -1165,20 +1165,28 @@ struct RStruct { #define FL_ABLE(x) (!SPECIAL_CONST_P(x) && BUILTIN_TYPE(x) != T_NODE) #define FL_TEST_RAW(x,f) (RBASIC(x)->flags&(f)) #define FL_TEST(x,f) (FL_ABLE(x)?FL_TEST_RAW((x),(f)):0) +#define FL_ANY_RAW(x,f) FL_TEST_RAW((x),(f)) #define FL_ANY(x,f) FL_TEST((x),(f)) +#define FL_ALL_RAW(x,f) (FL_TEST_RAW((x),(f)) == (f)) #define FL_ALL(x,f) (FL_TEST((x),(f)) == (f)) -#define FL_SET(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags |= (f);} while (0) -#define FL_UNSET(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags &= ~(f);} while (0) -#define FL_REVERSE(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags ^= (f);} while (0) +#define FL_SET_RAW(x,f) (RBASIC(x)->flags |= (f)) +#define FL_SET(x,f) (FL_ABLE(x) ? FL_SET_RAW(x, f) : 0) +#define FL_UNSET_RAW(x,f) (RBASIC(x)->flags &= ~(f)) +#define FL_UNSET(x,f) (FL_ABLE(x) ? FL_UNSET_RAW(x, f) : 0) +#define FL_REVERSE_RAW(x,f) (RBASIC(x)->flags ^= (f)) +#define FL_REVERSE(x,f) (FL_ABLE(x) ? FL_REVERSE_RAW(x, f) : 0) #define OBJ_TAINTABLE(x) (FL_ABLE(x) && BUILTIN_TYPE(x) != T_BIGNUM && BUILTIN_TYPE(x) != T_FLOAT) +#define OBJ_TAINTED_RAW(x) FL_TEST_RAW(x, FL_TAINT) #define OBJ_TAINTED(x) (!!FL_TEST((x), FL_TAINT)) -#define OBJ_TAINT(x) (OBJ_TAINTABLE(x) ? (RBASIC(x)->flags |= FL_TAINT) : 0) +#define OBJ_TAINT_RAW(x) FL_SET_RAW(x, FL_TAINT) +#define OBJ_TAINT(x) (OBJ_TAINTABLE(x) ? OBJ_TAINT_RAW(x) : 0) #define OBJ_UNTRUSTED(x) OBJ_TAINTED(x) #define OBJ_UNTRUST(x) OBJ_TAINT(x) +#define OBJ_INFECT_RAW(x,s) FL_SET_RAW(x, OBJ_TAINTED_RAW(s)) #define OBJ_INFECT(x,s) ( \ (OBJ_TAINTABLE(x) && FL_ABLE(s)) ? \ - RBASIC(x)->flags |= RBASIC(s)->flags & FL_TAINT : 0) + OBJ_INFECT_RAW(x, s) : 0) #define OBJ_FROZEN(x) (FL_ABLE(x) ? !!(RBASIC(x)->flags&FL_FREEZE) : 1) #define OBJ_FREEZE_RAW(x) (RBASIC(x)->flags |= FL_FREEZE) diff --git a/internal.h b/internal.h index 5ba73847fa..c2e5a5b757 100644 --- a/internal.h +++ b/internal.h @@ -1114,8 +1114,8 @@ VALUE rb_external_str_with_enc(VALUE str, rb_encoding *eenc); #endif #define STR_NOEMBED FL_USER1 #define STR_SHARED FL_USER2 /* = ELTS_SHARED */ -#define STR_EMBED_P(str) (!FL_TEST((str), STR_NOEMBED)) -#define STR_SHARED_P(s) FL_ALL((s), STR_NOEMBED|ELTS_SHARED) +#define STR_EMBED_P(str) (!FL_TEST_RAW((str), STR_NOEMBED)) +#define STR_SHARED_P(s) FL_ALL_RAW((s), STR_NOEMBED|ELTS_SHARED) #define is_ascii_string(str) (rb_enc_str_coderange(str) == ENC_CODERANGE_7BIT) #define is_broken_string(str) (rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN) size_t rb_str_memsize(VALUE); diff --git a/string.c b/string.c index f6d305c7ff..8b11cc6ec9 100644 --- a/string.c +++ b/string.c @@ -1168,7 +1168,7 @@ rb_obj_as_string(VALUE obj) str = rb_funcall(obj, id_to_s, 0); if (!RB_TYPE_P(str, T_STRING)) return rb_any_to_s(obj); - if (OBJ_TAINTED(obj)) OBJ_TAINT(str); + OBJ_INFECT(str, obj); return str; } @@ -1514,8 +1514,7 @@ rb_str_plus(VALUE str1, VALUE str2) memcpy(ptr3+len1, ptr2, len2); TERM_FILL(&ptr3[len1+len2], rb_enc_mbminlen(enc)); - if (OBJ_TAINTED(str1) || OBJ_TAINTED(str2)) - OBJ_TAINT(str3); + FL_SET_RAW(str3, OBJ_TAINTED_RAW(str1) | OBJ_TAINTED_RAW(str2)); ENCODING_CODERANGE_SET(str3, rb_enc_to_index(enc), ENC_CODERANGE_AND(ENC_CODERANGE(str1), ENC_CODERANGE(str2))); RB_GC_GUARD(str1); @@ -4221,7 +4220,7 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str) if (NIL_P(hash)) { StringValue(repl); } - if (OBJ_TAINTED(repl)) tainted = 1; + tainted = OBJ_TAINTED_RAW(repl); } pat = get_pat_quoted(argv[0], 1); @@ -4281,7 +4280,7 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str) } rb_str_modify(str); rb_enc_associate(str, enc); - if (OBJ_TAINTED(repl)) tainted = 1; + tainted |= OBJ_TAINTED_RAW(repl); if (ENC_CODERANGE_UNKNOWN < cr && cr < ENC_CODERANGE_BROKEN) { int cr2 = ENC_CODERANGE(repl); if (cr2 == ENC_CODERANGE_BROKEN || @@ -4305,7 +4304,7 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str) STR_SET_LEN(str, len); TERM_FILL(&RSTRING_PTR(str)[len], TERM_LEN(str)); ENC_CODERANGE_SET(str, cr); - if (tainted) OBJ_TAINT(str); + FL_SET_RAW(str, tainted); return str; } @@ -4391,7 +4390,7 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang) else { mode = MAP; } - if (OBJ_TAINTED(repl)) tainted = 1; + tainted = OBJ_TAINTED_RAW(repl); break; default: rb_check_arity(argc, 1, 2); @@ -4454,8 +4453,7 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang) val = repl; } - - if (OBJ_TAINTED(val)) tainted = 1; + tainted |= OBJ_TAINTED_RAW(val); len = beg0 - offset; /* copy pre-match substr */ if (len) { @@ -4489,11 +4487,11 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang) } else { RBASIC_SET_CLASS(dest, rb_obj_class(str)); - OBJ_INFECT(dest, str); + tainted |= OBJ_TAINTED_RAW(str); str = dest; } - if (tainted) OBJ_TAINT(str); + FL_SET_RAW(str, tainted); return str; } @@ -4723,7 +4721,7 @@ str_byte_substr(VALUE str, long beg, long len) } } - OBJ_INFECT(str2, str); + OBJ_INFECT_RAW(str2, str); return str2; } @@ -4848,7 +4846,7 @@ rb_str_reverse(VALUE str) } } STR_SET_LEN(rev, RSTRING_LEN(str)); - OBJ_INFECT(rev, str); + OBJ_INFECT_RAW(rev, str); str_enc_copy(rev, str); ENC_CODERANGE_SET(rev, cr); @@ -5145,7 +5143,7 @@ rb_str_inspect(VALUE str) if (p > prev) str_buf_cat(result, prev, p - prev); str_buf_cat2(result, "\""); - OBJ_INFECT(result, str); + OBJ_INFECT_RAW(result, str); return result; } @@ -5285,7 +5283,7 @@ rb_str_dump(VALUE str) snprintf(q, qend-q, ".force_encoding(\"%s\")", enc->name); enc = rb_ascii8bit_encoding(); } - OBJ_INFECT(result, str); + OBJ_INFECT_RAW(result, str); /* result from dump is ASCII */ rb_enc_associate(result, enc); ENC_CODERANGE_SET(result, ENC_CODERANGE_7BIT); @@ -7812,8 +7810,7 @@ rb_str_crypt(VALUE str, VALUE salt) rb_sys_fail("crypt"); } result = rb_str_new_cstr(res); - OBJ_INFECT(result, str); - OBJ_INFECT(result, salt); + FL_SET_RAW(result, OBJ_TAINTED_RAW(str) | OBJ_TAINTED_RAW(salt)); return result; } @@ -7986,8 +7983,8 @@ rb_str_justify(int argc, VALUE *argv, VALUE str, char jflag) } TERM_FILL(p, rb_enc_mbminlen(enc)); STR_SET_LEN(res, p-RSTRING_PTR(res)); - OBJ_INFECT(res, str); - if (!NIL_P(pad)) OBJ_INFECT(res, pad); + OBJ_INFECT_RAW(res, str); + if (!NIL_P(pad)) OBJ_INFECT_RAW(res, pad); rb_enc_associate(res, enc); if (argc == 2) cr = ENC_CODERANGE_AND(cr, ENC_CODERANGE(pad)); @@ -8247,7 +8244,7 @@ rb_str_b(VALUE str) { VALUE str2 = str_alloc(rb_cString); str_replace_shared_without_enc(str2, str); - OBJ_INFECT(str2, str); + OBJ_INFECT_RAW(str2, str); ENC_CODERANGE_CLEAR(str2); return str2; } -- cgit v1.2.3