tainted string should be tainted.

* hash.c (hash_aset_str): create frozen string for tainted objects.
  (should not use fsting table on this case).


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59310 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2017-07-11 07:42:27 +00:00
Родитель d2dd18ed16
Коммит 5168fb54e3
2 изменённых файлов: 34 добавлений и 9 удалений

32
hash.c
Просмотреть файл

@ -1516,20 +1516,34 @@ hash_aset(st_data_t *key, st_data_t *val, struct update_arg *arg, int existing)
return ST_CONTINUE;
}
static VALUE
fstring_existing_str(VALUE str)
{
st_data_t fstr;
st_table *tbl = rb_vm_fstring_table();
if (st_lookup(tbl, str, &fstr)) {
if (rb_objspace_garbage_object_p(fstr)) {
return rb_fstring(str);
}
else {
return (VALUE)fstr;
}
}
else {
return Qnil;
}
}
static int
hash_aset_str(st_data_t *key, st_data_t *val, struct update_arg *arg, int existing)
{
if (!existing && !RB_OBJ_FROZEN(*key)) {
st_data_t fstr;
st_table *tbl = rb_vm_fstring_table();
VALUE k;
if (st_lookup(tbl, *key, &fstr)) {
if (rb_objspace_garbage_object_p(fstr)) {
*key = rb_fstring(*key);
}
else {
*key = (VALUE)fstr;
}
if (!RB_OBJ_TAINTED(*key) &&
(k = fstring_existing_str(*key)) != Qnil) {
*key = k;
}
else {
*key = rb_str_new_frozen(*key);

Просмотреть файл

@ -300,6 +300,17 @@ class TestHash < Test::Unit::TestCase
assert_same "ABC".freeze, a.keys[0]
end
def test_tainted_string_key
str = 'str'.taint
h = {}
h[str] = nil
key = h.keys.first
assert_equal true, str.tainted?
assert_equal false, str.frozen?
assert_equal true, key.tainted?
assert_equal true, key.frozen?
end
def test_EQUAL # '=='
h1 = @cls[ "a" => 1, "c" => 2 ]
h2 = @cls[ "a" => 1, "c" => 2, 7 => 35 ]