Reputation: 32933
I have some data values that come in from a form, which are "stringified" versions of different data types - strings, arrays, hashes etc: they're all the result of calling "inspect" on the original data.
When I get them back, i want to save them into the object again in their original pre-inspect form - ie as a hash, an array, a symbol etc.
Obviously, i could just call "eval" on each value, but this data is from a form and so is susceptible to "Bobby Tables" sql injection, or even just a Ruby call like "User.delete_all" (which is harder to police - at least Rails has some methods for sanitizing sql). It's in an admin section of the site, and only a couple of trustworthy people will ever use it, but I'd still like to find a safer way.
To make things harder, this is in Ruby 1.8.6 and Rails 2.2.2 (Just don't - I know!).
Is there a way to reverse the "inspect" method without calling eval
, or is this logically the same thing? Here's some example values that I want to convert.
"\"Instrument Home\"" => "Instrument Home"
":foo" => :foo
"[\"1311089\", \"1311128\", \"1310802\"]" => ["1311089", "1311128", "1310802"]
"{:foo=>\"bar\"}" => {:foo => "bar"}
EDIT: here's what my form looks like:
and how the form is set up:
<% @digilearning_module.metadata_keys_and_values.each do |num, hash| %>
<tr>
<td><%= text_field_tag "digilearning_module[metadata_keys_and_values][#{num}][key]", hash[:key].inspect %></td>
<td>=></td>
<td><%= text_area_tag "digilearning_module[metadata_keys_and_values][#{num}][value]", hash[:value].inspect %></td>
</tr>
<% end %>
and how the data comes back in (i've omitted most of the values from the big array, for clarity).
params[:digilearning_module][:metadata_keys_and_values] = {
"1"=>{"value"=>"[\"1311089\", \"1311128\", \"1310802\"]", "key"=>":tablet_compatible_child_mod_numbers"},
"2"=>{"value"=>"\"Instrument Home\"", "key"=>":special_category"}
}
When I process this, i discard the numbers which are just there to seperate the key and value out into a hash. Then I read the keys and data values back in as the keys and values of the hash which is actually saved into the db: so for the above I would want to end up with
{:tablet_compatible_child_mod_numbers => ["1311089", "1311128", "1310802"], :special_category => "Instrument Home"}
Upvotes: 0
Views: 1032
Reputation: 168081
If you don't need symbol types, then a popular way to do that that I see on Stack Overlow is to use JSON instead of Ruby objects. You can map between Ruby objects and JSON, and safely encode and decode JSON.
Upvotes: 2