Bug #1929: str.dup.force_encodingが元のstrに影響を与えることがある
http://redmine.ruby-lang.org/issues/show/1929

起票者: Kazuhiko Shiozaki
ステータス: Open, 優先度: Normal
カテゴリ: core, Target version: 1.9.2
ruby -v: ruby 1.9.2dev (2009-08-09 trunk 24484) [x86_64-linux]

かずひこです。

tDiary trunk 3514をruby-trunkで動かすとカテゴリプラグインで日本語カテゴリのリンクをたどると
incompatible character encodings: ASCII-8BIT and UTF-8 (Encoding::CompatibilityError)
になります。
http://www.cozmixng.org/retro/projects/tdiary/tickets/171

つきつめていくと、どうやら ERB::Util.url_encodeの
    def url_encode(s)
      s.to_s.dup.force_encoding("ASCII-8BIT").gsub(/[^a-zA-Z0-9_\-.]/n) {
        sprintf("%%%02X", $&.unpack("C")[0])
      }
    end
で、元のsが影響をうけているようなのです。
http://vvvvvv.sakura.ne.jp/ds14050/diary/20090223.html#p01

例えば、url_encodeの呼び出し側を次のように修正するとエラーが再現しません。
-    a = @category.map {|c| "category=#{u c}"}.join(';')
+    a = @category.map {|c| "category=#{u ''+c}"}.join(';')

もしくは、url_encodeを次のように修正するとエラーが再現しません。
    def url_encode(s)
      "#{s}".force_encoding("ASCII-8BIT").gsub(/[^a-zA-Z0-9_\-.]/n) {
        sprintf("%%%02X", $&.unpack("C")[0])
      }
    end

短い再現コードが書けなかったのですが、どうぞよろしくお願いします。
かずひこ


----------------------------------------
http://redmine.ruby-lang.org