Ruby (Rails) освобождает строку - отменить Array.to_s - PullRequest
4 голосов
/ 08 марта 2011

Взломал пару библиотек, и возникла проблема, когда строка получала "двойной выход".

например: Фиксированный пример

 > x = ['a']
 => ["a"] 
 > x.to_s
 => "[\"a\"]" 
 > 

Затем снова до

\"\[\\\"s\\\"\]\"

Это происходило при работе с заголовками http. У меня есть заголовок, который будет массивом, но библиотека http делает свой собственный символ, экранирующий значение array.to_s.

Обходной путь, который я нашел, состоял в том, чтобы преобразовать массив в строку самостоятельно, а затем «отменить» to_s. Вот так: formatted_value = value.to_s

if value.instance_of?(Array)
  formatted_value = formatted_value.gsub(/\\/,"") #remove backslash                                                 
  formatted_value = formatted_value.gsub(/"/,"")  #remove single quote
  formatted_value = formatted_value.gsub(/\[/,"") #remove [                                                                                                     
  formatted_value = formatted_value.gsub(/\]/,"") #remove ]   
end
value = formatted_value

... Должен быть лучший способ ... (без необходимости мартышки-патча для драгоценных камней, которые я использую). (да, это разрыв, если моя строка действительно содержит эти строки.)

Предложения

** ОБНОВЛЕНИЕ 2 **

Хорошо. По-прежнему возникают проблемы в этом районе, но теперь я думаю, что выяснил основную проблему. Он сериализует мой массив в json после вызова to_s. По крайней мере, это похоже на то, что я вижу.

[ 'а']. To_s.to_json

Я вызываю метод в геме, который возвращает результаты to_s, а затем вызываю to_json для него.

1 Ответ

8 голосов
/ 08 марта 2011

Я отредактировал свой ответ из-за вашего отредактированного вопроса:

Я все еще не могу дублировать ваши результаты!

>> x = ['a']
=> ["a"]
>> x.to_s
=> "a"

Но когда я изменяю последний вызов на это:

>> x.inspect
=> "[\"a\"]"

Итак, я предполагаю, что это то, что вы делаете?

это не обязательно экранирование значений - per se .Он хранит строку следующим образом:

%{["a"]}

, а точнее:

'["a"]'

В любом случае.Это должно сработать, чтобы исключить его:

>> x = ['a']
=> ["a"]
>> y = x.inspect
=> "[\"a\"]"
>> z = Array.class_eval(y)
=> ["a"]
>> x == z
=> true

Я скептически отношусь к безопасности использования class_eval, но с осторожностью относитесь к пользовательским данным, поскольку это может привести к непреднамеренным побочным эффектам (ипод этим я подразумеваю атаки с внедрением кода), если только вы не уверены, что знаете, откуда исходные данные поступили или что им было разрешено.

...