Issue #11386 has been updated by Usaku NAKAMURA.


なるほど、とは思ったのですが、
「次にぼくは『特異メソッドを定義したStringオブジェクトをrb_fstring()に渡すと問題がある』と言うッ!」
という感じです。(そして次はインスタンス変数)

----------------------------------------
Bug #11386: taint flag about rb_fstring()
https://bugs.ruby-lang.org/issues/11386#change-53517

* Author: Usaku NAKAMURA
* Status: Open
* Priority: Normal
* Assignee: 
* ruby -v: 
* Backport: 2.0.0: DONTNEED, 2.1: REQUIRED, 2.2: REQUIRED
----------------------------------------
r51261以降、mswinのtest-allでfailureが出るようになった件を調査していて発見したのですが、
rb_fstring()にはtaintフラグを保存しないという問題があります。

原因は2つあって、

1. sharedなStringオブジェクトを登録する際にtaintフラグをコピーしないバグがある
2. 既に同じバイト列・エンコーディングで表現可能なStringオブジェクトが登録されている場合それを返すが、
   引数のtaintフラグと返すオブジェクトのtaintフラグの違いを評価していない

というものです。

前者は以下のパッチで直るのでどうでもいいんですが、後者はrb_fstring()の仕様がどうなのか、
という問題であると思います。
r51261より前のように、SymbolやRubyレベルでは見えないStringオブジェクトのみを扱っているのならば特に問題ではないのでr51261のような使い方を禁止するべきなのか、
rb_fstring()を変更してtaintフラグを適切に扱うようにすべきなのか、どちらでしょうか?

~~~diff
Index: string.c
===================================================================
--- string.c	(リビジョン 51334)
+++ string.c	(作業コピー)
@@ -245,8 +245,10 @@ fstr_update_callback(st_data_t *key, st_data_t *va
     }
     else {
 	if (STR_SHARED_P(str)) { /* str should not be shared */
-	    str = rb_enc_str_new(RSTRING_PTR(str), RSTRING_LEN(str), STR_ENC_GET(str));
-	    OBJ_FREEZE(str);
+	    VALUE newstr = rb_enc_str_new(RSTRING_PTR(str), RSTRING_LEN(str), STR_ENC_GET(str));
+	    OBJ_INFECT(newstr, str);
+	    OBJ_FREEZE(newstr);
+	    str = newstr;
 	}
 	else {
 	    str = rb_str_new_frozen(str);

~~~

---Files--------------------------------
0001-string.c-keep-taintedness.patch (2.08 KB)
0002-tests-for-fstring-taintedness.patch (2.61 KB)


-- 
https://bugs.ruby-lang.org/