Skip to content

Instantly share code, notes, and snippets.

@yob
Created July 18, 2009 08:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save yob/149473 to your computer and use it in GitHub Desktop.
Save yob/149473 to your computer and use it in GitHub Desktop.
# coding: utf-8
class ApplicationController < ActionController::Base
before_filter :normalise_param_encodings
# On M17N aware VMs, ensure params from the user are marked with an appropriate encoding.
#
# As of Rails 2.3, Rack returns all params with an ASCII-8BIT encoding, which causes an
# exception if a param is mixed with a UTF-8 string or ERB template. Hopefully that will be
# fixed at some point and this won't be necessary any more.
#
# I've read in a few places that most browsers seem to submit data to the server in the same
# encoding as the last page it received from that server. My brief testing on FF 3.0.x
# confirmed this (for FF at least). FF also doesn't seem to explicitly specify the charset
# on either GET or POST requests (unless they're via AJAX).
#
# Since we always serve UTF-8, I'm going to assume all data we get is the same. If it isn't,
# I sanitise it.
#
# In *theory*, request.content_charset would contain the charset of the request, but it
# never seems to.
#
# As well as marking the strings as UTF-8, I also ensure they contain valid utf-8 data. The
# iconv technique for doing this is based on
# http://po-ru.com/diary/fixing-invalid-utf-8-in-ruby-revisited/
#
def normalise_param_encodings
return unless String.method_defined?(:force_encoding)
normalise_object_encoding(params)
end
def normalise_object_encoding(obj)
case obj
when String
unless obj.frozen?
obj.force_encoding(Encoding::UTF_8)
ic = Iconv.new('UTF-8//IGNORE', 'UTF-8')
obj.replace(ic.iconv(obj + ' ')[0..-2])
end
when Array
obj.each { |o| normalise_object_encoding(o) }
when Hash
obj.each { |k,v| normalise_object_encoding(v) }
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment