Проблема кодировки Ruby UTF8 - PullRequest
2 голосов
/ 02 декабря 2010

У меня есть приложение Ruby / Rails.

В моей базе данных postgresql есть таблица исполнителей, которую я хочу запросить по имени.У меня есть художники с португальскими символами и т. Д., И у меня есть некоторые вопросы, связанные с ними.

Например, одна группа называется Legião Urbana.Если я запрашиваю строку «legiã» из своего приложения, я получаю следующие параметры:

{"action"=>"search_artist", "q"=>"legi\343", "controller"=>"home"}

Однако я получаю сообщение об ошибке

Artist.all(:conditions => "name LIKE '%#{params[:q]}%'")

PGError: ERROR:  invalid byte sequence for encoding "UTF8": 0xe32527

Что мне делать, чтобыпреобразовать в UTF8 или исправить это как-нибудь?

Ответы [ 2 ]

5 голосов
/ 02 декабря 2010

Вам необходимо знать, какова кодировка этого параметра в строке запроса.

Ruby 1.9 включает поддержку строк, помеченных их кодировками. В Ruby 1.9 вы могли бы:

params[:q].encoding # Rails 3 on 1.9 generally presents strings in UTF-8
params[:q].encode('utf-8') # ask Ruby to re-encode it to UTF-8

Затем вам нужно преобразовать параметр из этой кодировки в UTF-8 перед выполнением интерполяции строк (синтаксис #{...}).

Или вам нужно передать параметр как параметр SQL, , а не , используя интерполяцию строк.

Конечно, это поднимает вопрос безопасности: если вы не знаете, как правильно кодировать текст для использования в SQL, вы должны никогда не выполнять интерполяцию строк для построения фрагментов строк SQL. Поскольку SQL-фрагменты с параметрами быстро и легко сделать в Rails, вы должны их использовать.

# Rails 2
Artist.all(:conditions => ['name like ?', "%#{params[:q]}%"])
Artist.all(:conditions => ['name like :q', { :q=> "%#{params[:q]}%" }])

# Rails 3
Artist.where('name like ?', "%#{params[:q]}")
Artist.where('name like :q', :q => "%#{params[:q]}")

Внедрение SQL - это проблема безопасности, которая возникает, когда вы выполняете интерполяцию строк и кодируете строки таким образом, чтобы построить правильные фрагменты SQL для некоторых входных строк, но не для других. В языках / средах, где с параметрами труднее работать, было бы приемлемо выполнять строковую интерполяцию или построение строк (если по-прежнему легко выполнять строковую интерполяцию или построение строк), если вы тщательно исследуете, как вы необходимы для кодирования интерполированных строк для построения правильных фрагментов SQL независимо от входной строки. Поскольку SQL-инъекцию легко избежать с помощью Rails через упорядоченные или именованные параметры (см. Четыре примера выше), у вас не должно возникнуть проблем с обеспечением безопасности всех ваших фрагментов SQL.

4 голосов
/ 02 декабря 2010

Я думаю, что это может сделать

require 'iconv'
Iconv.conv("UTF8", "LATIN1", params[:q])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...