From 25215d7285db10e2c04d903f251b791342e4dd6a Mon Sep 17 00:00:00 2001 From: wycats Date: Sun, 27 Jun 2010 21:12:10 -0700 Subject: Fix several known web encoding issues: * Specify accept-charset on all forms. All recent browsers, as well as IE5+, will use the encoding specified for form parameters * Unfortunately, IE5+ will not look at accept-charset unless at least one character in the form's values is not in the page's charset. Since the user can override the default charset (which Rails sets to UTF-8), we provide a hidden input containing a unicode character, forcing IE to look at the accept-charset. * Now that the vast majority of web input is UTF-8, we set the inbound parameters to UTF-8. This will eliminate many cases of incompatible encodings between ASCII-8BIT and UTF-8. * You can safely ignore params[:_snowman_] TODO: * Validate inbound text to confirm it is UTF-8 * Combine the whole_form implementations in form_helper_test and form_tag_helper_test --- actionpack/lib/action_dispatch/http/parameters.rb | 31 ++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/http/parameters.rb b/actionpack/lib/action_dispatch/http/parameters.rb index 0a37bd7fc1..add8cab2ab 100644 --- a/actionpack/lib/action_dispatch/http/parameters.rb +++ b/actionpack/lib/action_dispatch/http/parameters.rb @@ -6,7 +6,11 @@ module ActionDispatch module Parameters # Returns both GET and POST \parameters in a single hash. def parameters - @env["action_dispatch.request.parameters"] ||= request_parameters.merge(query_parameters).update(path_parameters).with_indifferent_access + @env["action_dispatch.request.parameters"] ||= begin + params = request_parameters.merge(query_parameters) + params.merge!(path_parameters) + encode_params(params).with_indifferent_access + end end alias :params :parameters @@ -32,6 +36,31 @@ module ActionDispatch end private + + # TODO: Validate that the characters are UTF-8. If they aren't, + # you'll get a weird error down the road, but our form handling + # should really prevent that from happening + def encode_params(params) + return params unless "ruby".encoding_aware? + + if params.is_a?(String) + return params.force_encoding("UTF-8").encode! + elsif !params.is_a?(Hash) + return params + end + + params.each do |k, v| + case v + when Hash + encode_params(v) + when Array + v.map! {|el| encode_params(el) } + else + encode_params(v) + end + end + end + # Convert nested Hash to HashWithIndifferentAccess def normalize_parameters(value) case value -- cgit v1.2.3