روبي 2.0.0 سلسلة # مباراة جدلية:تسلسل بايت غير صالح في أوتف-8
-
21-12-2019 - |
سؤال
أرى هذا كثيرا ولم أحسب حلا رشيقا.إذا كان إدخال المستخدم يحتوي على تسلسلات بايت غير صالحة ، فأنا بحاجة إلى أن أكون قادرا على عدم رفع استثناء.على سبيل المثال:
# @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
هل هذا خطأ مع روبي 2.0.0 أو أنا في عداد المفقودين شيء?
ما هو غريب هو أنه يبدو أن الترميز بشكل صحيح ، ولكن المباراة لا تزال تثير استثناء:
@raw_response.encode("UTF-8", :invalid=>:replace, :replace=>"?").encoding
=> #<Encoding:UTF-8>
المحلول
في روبي 2.0 ال encode
الطريقة هو عدم المرجع عند ترميز سلسلة لترميزها الحالي:
يرجى ملاحظة أن التحويل من ترميز
enc
إلى نفس الترميزenc
هو لا المرجع ، أي.يتم إرجاع جهاز الاستقبال دون أي تغييرات ، ولا يتم رفع أي استثناءات ، حتى إذا كانت هناك وحدات بايت غير صالحة.
تغير هذا في 2.1 ، والذي أضاف أيضا scrub
الطريقة كما أسهل طريقة للقيام بذلك.
إذا كنت غير قادر على الترقية إلى 2.1 ، سيكون لديك لترميز في ترميز مختلفة والعودة من أجل إزالة بايت غير صالحة ، شيء من هذا القبيل:
if ! s.valid_encoding?
s = s.encode("UTF-16be", :invalid=>:replace, :replace=>"?").encode('UTF-8')
end
نصائح أخرى
منذ أن كنت تستخدم القضبان وليس فقط روبي يمكنك أيضا استخدام TIDY_BYTES.يعمل هذا مع Ruby 2.0 وأيضا من المحتمل أن يعطيك البيانات المعقولة بدلا من مجرد استبدال الشخصيات.