[前][次][番号順一覧][スレッド一覧]

ruby-changes:47196

From: ko1 <ko1@a...>
Date: Tue, 11 Jul 2017 16:42:36 +0900 (JST)
Subject: [ruby-changes:47196] ko1:r59310 (trunk): tainted string should be tainted.

ko1	2017-07-11 16:42:27 +0900 (Tue, 11 Jul 2017)

  New Revision: 59310

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59310

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

  Modified files:
    trunk/hash.c
    trunk/test/ruby/test_hash.rb
Index: hash.c
===================================================================
--- hash.c	(revision 59309)
+++ hash.c	(revision 59310)
@@ -1516,20 +1516,34 @@ hash_aset(st_data_t *key, st_data_t *val https://github.com/ruby/ruby/blob/trunk/hash.c#L1516
     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);
Index: test/ruby/test_hash.rb
===================================================================
--- test/ruby/test_hash.rb	(revision 59309)
+++ test/ruby/test_hash.rb	(revision 59310)
@@ -300,6 +300,17 @@ class TestHash < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_hash.rb#L300
     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 ]

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]