Je vois beaucoup cela et je n'ai pas trouvé de solution gracieuse. Si l'entrée utilisateur contient des séquences d'octets invalides, je dois pouvoir ne pas déclencher d'exception. Par exemple:
# @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
De nombreuses questions similaires ont été posées et le résultat semble coder ou forcer le codage de la chaîne. Aucun de ces travaux pour moi cependant:
regex.match(@raw_response.force_encoding("UTF-8"))
ArgumentError: invalid byte sequence in UTF-8
ou
regex.match(@raw_response.encode("UTF-8", :invalid=>:replace, :replace=>"?"))
ArgumentError: invalid byte sequence in UTF-8
Est-ce un bogue avec Ruby 2.0.0 ou est-ce que je manque quelque chose?
Ce qui est étrange, c'est qu'il semble encoder correctement, mais la correspondance continue de soulever une exception:
@raw_response.encode("UTF-8", :invalid=>:replace, :replace=>"?").encoding
=> #<Encoding:UTF-8>
Dans Ruby 2.0 la méthode encode
est un no-op lors du codage d'une chaîne dans son codage actuel:
Veuillez noter que la conversion d'un codage
enc
vers le même codageenc
est un no-op, c'est-à-dire que le récepteur est retourné sans aucune modification, et aucune exception n'est levée, même s'il y a des octets invalides .
Cela a changé en 2.1, qui a également ajouté la méthode scrub
comme un moyen plus facile de le faire.
Si vous ne parvenez pas à effectuer la mise à niveau vers 2.1, vous devrez encoder dans un autre encodage et inverser afin de supprimer les octets invalides, quelque chose comme:
if ! s.valid_encoding?
s = s.encode("UTF-16be", :invalid=>:replace, :replace=>"?").encode('UTF-8')
end
Puisque vous utilisez Rails et pas seulement Ruby vous pouvez également utiliser tidy_bytes . Cela fonctionne avec Ruby 2.0 et vous donnera probablement des données sensibles au lieu de simplement remplacer des caractères.