From 19292a70fb553895693f496ef2bd09ade4ab7890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 20 Dec 2011 11:06:37 +0100 Subject: Do not hard code encoding to UTF8 --- actionpack/lib/action_view/template.rb | 96 +++++++++++++++------------- actionpack/lib/action_view/template/error.rb | 6 +- 2 files changed, 54 insertions(+), 48 deletions(-) diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index 10797c010f..c760726cdf 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -173,6 +173,52 @@ module ActionView @inspect ||= defined?(Rails.root) ? identifier.sub("#{Rails.root}/", '') : identifier end + # This method is responsible for properly setting he encoding of the + # source. Until this point, we assume that the source is BINARY data. + # If no additional information is supplied, we assume the encoding is + # the same as Encoding.default_external. + # + # The user can also specify the encoding via a comment on the first + # line of the template (# encoding: NAME-OF-ENCODING). This will work + # with any template engine, as we process out the encoding comment + # before passing the source on to the template engine, leaving a + # blank line in its stead. + def encode! + return unless source.encoding == Encoding::BINARY + + if source.encoding_aware? + # Look for # encoding: *. If we find one, we'll encode the + # String in that encoding, otherwise, we'll use the + # default external encoding. + if source.sub!(/\A#{ENCODING_FLAG}/, '') + encoding = magic_encoding = $1 + else + encoding = Encoding.default_external + end + + # Tag the source with the default external encoding + # or the encoding specified in the file + source.force_encoding(encoding) + + # If the user didn't specify an encoding, and the handler + # handles encodings, we simply pass the String as is to + # the handler (with the default_external tag) + if !magic_encoding && @handler.respond_to?(:handles_encoding?) && @handler.handles_encoding? + source + # Otherwise, if the String is valid in the encoding, + # encode immediately to default_internal. This means + # that if a handler doesn't handle encodings, it will + # always get Strings in the default_internal + elsif source.valid_encoding? + source.encode! + # Otherwise, since the String is invalid in the encoding + # specified, raise an exception + else + raise WrongEncodingError.new(source, encoding) + end + end + end + protected # Compile a template. This method ensures a template is compiled @@ -195,15 +241,7 @@ module ActionView end # Among other things, this method is responsible for properly setting - # the encoding of the source. Until this point, we assume that the - # source is BINARY data. If no additional information is supplied, - # we assume the encoding is the same as Encoding.default_external. - # - # The user can also specify the encoding via a comment on the first - # line of the template (# encoding: NAME-OF-ENCODING). This will work - # with any template engine, as we process out the encoding comment - # before passing the source on to the template engine, leaving a - # blank line in its stead. + # the encoding of the compiled template. # # If the template engine handles encodings, we send the encoded # String to the engine without further processing. This allows @@ -215,40 +253,8 @@ module ActionView # In general, this means that templates will be UTF-8 inside of Rails, # regardless of the original source encoding. def compile(view, mod) #:nodoc: + encode! method_name = self.method_name - - if source.encoding_aware? - # Look for # encoding: *. If we find one, we'll encode the - # String in that encoding, otherwise, we'll use the - # default external encoding. - if source.sub!(/\A#{ENCODING_FLAG}/, '') - encoding = magic_encoding = $1 - else - encoding = Encoding.default_external - end - - # Tag the source with the default external encoding - # or the encoding specified in the file - source.force_encoding(encoding) - - # If the user didn't specify an encoding, and the handler - # handles encodings, we simply pass the String as is to - # the handler (with the default_external tag) - if !magic_encoding && @handler.respond_to?(:handles_encoding?) && @handler.handles_encoding? - source - # Otherwise, if the String is valid in the encoding, - # encode immediately to default_internal. This means - # that if a handler doesn't handle encodings, it will - # always get Strings in the default_internal - elsif source.valid_encoding? - source.encode! - # Otherwise, since the String is invalid in the encoding - # specified, raise an exception - else - raise WrongEncodingError.new(source, encoding) - end - end - code = @handler.call(self) # Make sure that the resulting String to be evalled is in the @@ -297,7 +303,11 @@ module ActionView raise e else assigns = view.respond_to?(:assigns) ? view.assigns : {} - template = @virtual_path ? refresh(view) : self + template = self + unless template.source + template = refresh(view) + template.encode! + end raise Template::Error.new(template, assigns, e) end end diff --git a/actionpack/lib/action_view/template/error.rb b/actionpack/lib/action_view/template/error.rb index ee74bb47d3..587e37a84f 100644 --- a/actionpack/lib/action_view/template/error.rb +++ b/actionpack/lib/action_view/template/error.rb @@ -89,14 +89,10 @@ module ActionView line_counter = start_on_line return unless source_code = source_code[start_on_line..end_on_line] - extract = source_code.sum do |line| + source_code.sum do |line| line_counter += 1 "#{indent}#{line_counter}: #{line}\n" end - - extract.force_encoding("UTF-8") if extract.respond_to?(:encode!) - - extract end def sub_template_of(template_path) -- cgit v1.2.3