Commit 81d2a1ee604e43ebd329dca4487edeb19136d9a5
1 parent
3527cdd7
Exists in
master
and in
1 other branch
add utf8 monkey patches
Showing
1 changed file
with
89 additions
and
0 deletions
Show diff stats
| @@ -0,0 +1,89 @@ | @@ -0,0 +1,89 @@ | ||
| 1 | +unless RUBY_VERSION == '1.8.7' | ||
| 2 | + # Make sure the logger supports encodings properly. | ||
| 3 | + module ActiveSupport | ||
| 4 | + class BufferedLogger | ||
| 5 | + def add(severity, message = nil, progname = nil, &block) | ||
| 6 | + return if @level > severity | ||
| 7 | + message = (message || (block && block.call) || progname).to_s | ||
| 8 | + | ||
| 9 | + # If a newline is necessary then create a new message ending with a newline. | ||
| 10 | + # Ensures that the original message is not mutated. | ||
| 11 | + message = "#{message}\n" unless message[-1] == ?\n | ||
| 12 | + buffer << message.force_encoding(Encoding.default_external) | ||
| 13 | + auto_flush | ||
| 14 | + message | ||
| 15 | + end | ||
| 16 | + end | ||
| 17 | + end | ||
| 18 | + | ||
| 19 | + # This makes it so all parameters get converted to UTF-8 before they hit your app. If someone sends invalid UTF-8 to your server, raise an exception. | ||
| 20 | + # At UserVoice, we rescue this exception and show a custom error page. | ||
| 21 | + class ActionController::InvalidByteSequenceErrorFromParams < Encoding::InvalidByteSequenceError; end | ||
| 22 | + class ActionController::Base | ||
| 23 | + | ||
| 24 | + def force_utf8_params | ||
| 25 | + traverse = lambda do |object, block| | ||
| 26 | + if object.kind_of?(Hash) | ||
| 27 | + object.each_value { |o| traverse.call(o, block) } | ||
| 28 | + elsif object.kind_of?(Array) | ||
| 29 | + object.each { |o| traverse.call(o, block) } | ||
| 30 | + else | ||
| 31 | + block.call(object) | ||
| 32 | + end | ||
| 33 | + object | ||
| 34 | + end | ||
| 35 | + force_encoding = lambda do |o| | ||
| 36 | + if o.respond_to?(:force_encoding) | ||
| 37 | + o.force_encoding(Encoding::UTF_8) | ||
| 38 | + raise ActionController::InvalidByteSequenceErrorFromParams unless o.valid_encoding? | ||
| 39 | + end | ||
| 40 | + if o.respond_to?(:original_filename) | ||
| 41 | + o.original_filename.force_encoding(Encoding::UTF_8) | ||
| 42 | + raise ActionController::InvalidByteSequenceErrorFromParams unless o.original_filename.valid_encoding? | ||
| 43 | + end | ||
| 44 | + end | ||
| 45 | + traverse.call(params, force_encoding) | ||
| 46 | + path_str = request.path.to_s | ||
| 47 | + if path_str.respond_to?(:force_encoding) | ||
| 48 | + path_str.force_encoding(Encoding::UTF_8) | ||
| 49 | + raise ActionController::InvalidByteSequenceErrorFromParams unless path_str.valid_encoding? | ||
| 50 | + end | ||
| 51 | + end | ||
| 52 | + before_filter :force_utf8_params | ||
| 53 | + end | ||
| 54 | + | ||
| 55 | + | ||
| 56 | + # Serialized columns in AR don't support UTF-8 well, so set the encoding on those as well. | ||
| 57 | + class ActiveRecord::Base | ||
| 58 | + def unserialize_attribute_with_utf8(attr_name) | ||
| 59 | + traverse = lambda do |object, block| | ||
| 60 | + if object.kind_of?(Hash) | ||
| 61 | + object.each_value { |o| traverse.call(o, block) } | ||
| 62 | + elsif object.kind_of?(Array) | ||
| 63 | + object.each { |o| traverse.call(o, block) } | ||
| 64 | + else | ||
| 65 | + block.call(object) | ||
| 66 | + end | ||
| 67 | + object | ||
| 68 | + end | ||
| 69 | + force_encoding = lambda do |o| | ||
| 70 | + o.force_encoding(Encoding::UTF_8) if o.respond_to?(:force_encoding) | ||
| 71 | + end | ||
| 72 | + value = unserialize_attribute_without_utf8(attr_name) | ||
| 73 | + traverse.call(value, force_encoding) | ||
| 74 | + end | ||
| 75 | + alias_method_chain :unserialize_attribute, :utf8 | ||
| 76 | + end | ||
| 77 | + | ||
| 78 | + # Make sure the flash sets the encoding to UTF-8 as well. | ||
| 79 | + module ActionController | ||
| 80 | + module Flash | ||
| 81 | + class FlashHash | ||
| 82 | + def [](k) | ||
| 83 | + v = super | ||
| 84 | + v.is_a?(String) ? v.force_encoding("UTF-8") : v | ||
| 85 | + end | ||
| 86 | + end | ||
| 87 | + end | ||
| 88 | + end | ||
| 89 | +end |