Ruby 2.0.0 String#Coincidencia de argumentoError:secuencia de bytes no válida en UTF-8
-
21-12-2019 - |
Pregunta
Veo esto mucho y no he encontrado una solución elegante.Si la entrada del usuario contiene secuencias de bytes no válidas, necesito poder evitar que genere una excepción.Por ejemplo:
# @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
Se han formulado numerosas preguntas similares y el resultado parece ser codificar o forzar la codificación de la cadena.Sin embargo, ninguno de estos funciona para mí:
regex.match(@raw_response.force_encoding("UTF-8"))
ArgumentError: invalid byte sequence in UTF-8
o
regex.match(@raw_response.encode("UTF-8", :invalid=>:replace, :replace=>"?"))
ArgumentError: invalid byte sequence in UTF-8
¿Es esto un error con Ruby 2.0.0 o me falta algo?
Lo extraño es que parece estar codificando correctamente, pero la coincidencia continúa generando una excepción:
@raw_response.encode("UTF-8", :invalid=>:replace, :replace=>"?").encoding
=> #<Encoding:UTF-8>
Solución
En Rubí 2.0 el encode
método no funciona al codificar una cadena con su codificación actual:
Tenga en cuenta que la conversión de una codificación
enc
a la misma codificaciónenc
es una operación no operativa, es decirel receptor se devuelve sin ningún cambio y no se generan excepciones, incluso si hay bytes no válidos.
Esto cambió en 2.1, que también agregó el scrub
método como una manera más fácil de hacer esto.
Si no puede actualizar a 2.1, tendrá que codificar en una codificación diferente y viceversa para eliminar bytes no válidos, algo como:
if ! s.valid_encoding?
s = s.encode("UTF-16be", :invalid=>:replace, :replace=>"?").encode('UTF-8')
end
Otros consejos
Dado que está usando rieles y no solo ruby, también puede usarla Tyid_Bytes.Esto funciona con Ruby 2.0 y también le dará datos sensibles en lugar de solo los caracteres de reemplazo.