Ruby 2.0.0 String#Match ArgumentError :séquence d'octets invalide en UTF-8
-
21-12-2019 - |
Question
Je vois cela souvent et je n'ai pas trouvé de solution gracieuse.Si l'entrée utilisateur contient des séquences d'octets non valides, je dois pouvoir faire en sorte qu'elle ne déclenche pas 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 être un codage ou un codage forcé de la chaîne.Cependant, aucun de ces éléments ne fonctionne pour moi :
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 bug avec Ruby 2.0.0 ou est-ce que j'ai raté quelque chose ?
Ce qui est étrange, c'est que le codage semble correct, mais la correspondance continue de générer une exception :
@raw_response.encode("UTF-8", :invalid=>:replace, :replace=>"?").encoding
=> #<Encoding:UTF-8>
La solution
Dans Ruby 2.0, le encode
méthode est un non-op lors de l'encodage d'une chaîne selon son encodage actuel :
Veuillez noter que la conversion à partir d'un encodage
enc
au même encodageenc
est un no-op, c'est-à-direle récepteur est renvoyé sans aucune modification et aucune exception n'est générée, même s'il y a des octets invalides.
Cela a changé dans la version 2.1, qui a également ajouté le scrub
méthode comme un moyen plus simple de le faire.
Si vous ne parvenez pas à passer à la version 2.1, vous devrez encoder dans un encodage différent et inversement 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
Autres conseils
Depuis que vous utilisez des rails et non seulement Ruby, vous pouvez également utiliser Tidy_bytes.Cela fonctionne avec Ruby 2.0 et vous donnera également des données sensibles au dos au lieu de simplement des caractères de remplacement.