]> source.dussan.org Git - redmine.git/commitdiff
Make sure that strings of serialized settings are UTF-8 encoded (#19305).
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Sun, 8 Mar 2015 16:28:19 +0000 (16:28 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Sun, 8 Mar 2015 16:28:19 +0000 (16:28 +0000)
git-svn-id: http://svn.redmine.org/redmine/trunk@14067 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/models/setting.rb
test/unit/setting_test.rb

index ca280ebcd208f16eef7ee7b1e155d6ac57e782fd..cc4131bec1be18884b03cb60ad9f9a2d705c6d5c 100644 (file)
@@ -91,7 +91,10 @@ class Setting < ActiveRecord::Base
   def value
     v = read_attribute(:value)
     # Unserialize serialized settings
-    v = YAML::load(v) if available_settings[name]['serialized'] && v.is_a?(String)
+    if available_settings[name]['serialized'] && v.is_a?(String)
+      v = YAML::load(v)
+      force_utf8_strings(v)
+    end
     v = v.to_sym if available_settings[name]['format'] == 'symbol' && !v.blank?
     v
   end
@@ -238,6 +241,23 @@ END_SRC
   load_plugin_settings
 
 private
+
+  def force_utf8_strings(arg)
+    if arg.is_a?(String)
+      arg.force_encoding('UTF-8')
+    elsif arg.is_a?(Array)
+      arg.each do |a|
+        force_utf8_strings(a)
+      end
+    elsif arg.is_a?(Hash)
+      arg.each do |k,v|
+        force_utf8_strings(k)
+        force_utf8_strings(v)
+      end
+    end
+    arg
+  end
+
   # Returns the Setting instance for the setting named name
   # (record found in database or new record with default value)
   def self.find_or_default(name)
index 46383e8672355745020dfb0aa601dcaf1e86634e..d2dee6d6b7e449e7478316d919b81a86b44b41b9 100644 (file)
@@ -1,3 +1,5 @@
+# encoding: utf-8
+#
 # Redmine - project management software
 # Copyright (C) 2006-2015  Jean-Philippe Lang
 #
@@ -101,4 +103,18 @@ class SettingTest < ActiveSupport::TestCase
       assert_equal [10, 25, 50], Setting.per_page_options_array
     end
   end
+
+  def test_serialized_setting_should_be_loaded_as_utf8_encoded_strings
+    scm = 'исправлено'
+    scm.force_encoding('BINARY')
+    Setting.enabled_scm = [scm]
+    Setting.clear_cache
+
+    s = Setting.enabled_scm
+    assert_equal ['исправлено'], s
+    assert_equal 'UTF-8', s.first.encoding.name
+  ensure
+    Setting.where(:name => 'enabled_scm').delete_all
+    Setting.clear_cache
+  end
 end