web-dev-qa-db-ja.com

Ruby 2.0.0 String#Match ArgumentError:UTF-8の無効なバイトシーケンス

私はこれをよく見ますが、優雅な解決策を見つけていません。ユーザー入力に無効なバイトシーケンスが含まれている場合、例外を発生させないようにする必要があります。例えば:

# @raw_response comes from user and contains invalid UTF-8
# for example: @raw_response = "\xBF"  
regex.match(@raw_response)
ArgumentError: invalid byte sequence in UTF-8

多数の同様の質問が行われ、結果は文字列のエンコードまたは強制エンコードのようです。しかし、これらのどちらも私にとっては機能しません:

regex.match(@raw_response.force_encoding("UTF-8"))
ArgumentError: invalid byte sequence in UTF-8

または

regex.match(@raw_response.encode("UTF-8", :invalid=>:replace, :replace=>"?"))
ArgumentError: invalid byte sequence in UTF-8

これはRuby 2.0.0のバグですか、それとも何か不足していますか?

奇妙なことに、正しくエンコードされているように見えますが、一致は引き続き例外を発生させます。

@raw_response.encode("UTF-8", :invalid=>:replace, :replace=>"?").encoding
 => #<Encoding:UTF-8>
26
Tom Rossi

Ruby 2.0では、 encode method は、文字列を現在のエンコードにエンコードする場合、何もしません:

エンコーディングencから同じエンコーディングencへの変換はノーオペレーションであることに注意してください。つまり、無効なバイトがあったとしても、レシーバは変更なしで返され、例外は発生しません。 。

これは2.1で変更され、これを行う簡単な方法として scrub method も追加されました。

2.1にアップグレードできない場合は、次のような無効なバイトを削除するために、別のエンコーディングにエンコードして戻す必要があります。

if ! s.valid_encoding?
  s = s.encode("UTF-16be", :invalid=>:replace, :replace=>"?").encode('UTF-8')
end
44
matt

RailsだけでなくRubyを使用しているので、 tidy_bytes も使用できます。これはRuby 2.0であり、おそらく単なる置換文字の代わりに賢明なデータを返すでしょう。

6
Yogh