2015-03-28 9 views
11

Mam kontrolera API, który odbiera informacje o ścieżce pliku multimedialnego i tagów id3, i zapisuje je do instancji Active Record za pomocą PostgreSQL/Rails.Radzenie sobie z "ciąg zawiera bajt null" wysłany od użytkowników

Czasami jednak użytkownik wysyła ciągi takie jak:

"genre"=>"Hip-Hop\u0000Hip-Hop/Rap" 

i poręcze/PostgreSQL nie są dokładnie zadowolony, że gdy próbuje się utrzymywać na save:

An ArgumentError occurred in internals#receive: 

string contains null byte 
activerecord (3.2.21) lib/active_record/connection_adapters/postgresql_adapter.rb:1172:in `send_query_prepared' 

Jak mogę czyścić ciąg w Ruby, aby całkowicie usunąć puste bajty?

+0

Wygląda na to, że odbierasz tekst w kodowaniu UTF-16. Zamiast próbować "oczyścić", polecam potwierdzenie tego przez nadawcę, a jeśli tak jest, użyj kodowania Ruby, aby przekonwertować tekst na UTF-8. Willy-nilly pozbycie się postaci nie pomoże, jeśli pojawi się na innych znakach diakrytycznych. Ponadto zarówno Ruby, jak i PostgreSQL mogą być niezadowolone, jeśli spróbujesz zapisać ciąg zakodowany w jedną stronę w polu zdefiniowanym dla innego typu kodowania, więc musisz być dokładny. –

+1

Niestety użytkownicy są na całym świecie i nie mogę ich poprosić o zmianę tych rzeczy, więc poprawka musi być po stronie serwera, nawet dlatego, że dane te są wysyłane przez nasze aplikacje i osoby trzecie. –

+1

Możliwe jest sprawdzenie łańcucha, aby sprawdzić, czy możliwe jest określenie jego kodowania. Czasami możesz mieć szczęście i otrzymać ciąg, który jest właściwie jednym kodowaniem, co ułatwia dotarcie tam, gdzie idziesz. Czasami dostajesz ciąg znaków, który zawiera wiele kodowań, a następnie musisz to zakodować, ale nie wiesz, jak to zrobić. Poproszenie ludzi o zmianę na ciebie nie jest prawdopodobne, chyba że będą potrzebować twojego API/usługi źle. Jest to bardzo gnarly królik-dziura, w którą można wpaść i może to doprowadzić do bardzo trudnej sytuacji. –

Odpowiedz

12

Prawdopodobna jest metoda na String. Możesz po prostu zrobić string.gsub("\u0000", ''), aby się ich pozbyć.

http://ruby-doc.org/core-2.1.1/String.html#method-i-gsub

+0

Czy istnieje powód, aby nie używać 'string.delete (" \ u0000 ")'? –

+0

Nie, to też byłoby dobrze, podobnie jak "string.tr". W rzeczywistości "tr" i "delete" są w tym przypadku bardziej odpowiednie niż "gsub" – tpbowden

Powiązane problemy