From 0559e91d4d9e6ab8f994d787a18c146e929d65a2 Mon Sep 17 00:00:00 2001 From: Tim Wade Date: Wed, 4 Apr 2018 12:20:57 -0700 Subject: [PATCH] Force UTF-8 encoding on task results Since task results are stored as binary blobs, they can be set as strings in whatever encoding you like. This can create problems for the API, which blindly tries to convert all attributes to JSON - any value containing ASCII with ansi escape codes will fail with a conversion error. It seems reasonable to expect that all string values should be encoded as UTF-8 - the alternative is for the API to have to force the encoding on every single string that comes its way. This change forces incoming values to be converted to UTF-8 prior to being stored. It will also convert outgoing values in the case that they have already been persisted prior to this change - though this extra check I'm sure could eventually be removed. Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1557731 --- app/models/miq_task.rb | 4 +++- spec/models/miq_task_spec.rb | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/app/models/miq_task.rb b/app/models/miq_task.rb index e23528ff155..699e5e47120 100644 --- a/app/models/miq_task.rb +++ b/app/models/miq_task.rb @@ -233,12 +233,14 @@ def task_results serializer_name = binary_blob.data_type serializer_name = "Marshal" unless serializer_name == "YAML" # YAML or Marshal, for now serializer = serializer_name.constantize - return serializer.load(binary_blob.binary) + result = serializer.load(binary_blob.binary) + return result.kind_of?(String) ? result.force_encoding("UTF-8") : result end nil end def task_results=(value) + value = value.force_encoding("UTF-8") if value.kind_of?(String) self.binary_blob = BinaryBlob.new(:name => "task_results", :data_type => "YAML") binary_blob.binary = YAML.dump(value) end diff --git a/spec/models/miq_task_spec.rb b/spec/models/miq_task_spec.rb index d709a677a5d..37e91243166 100644 --- a/spec/models/miq_task_spec.rb +++ b/spec/models/miq_task_spec.rb @@ -485,6 +485,29 @@ end end + describe "#task_results" do + it "forces UTF-8 encoding" do + task = FactoryGirl.create( + :miq_task, + :binary_blob => BinaryBlob.new( + :name => "task_results", + :data_type => "YAML", + :binary => YAML.dump("\xC3\xA4".force_encoding("ASCII-8BIT")) + ) + ) + + expect(task.task_results).to eq("ä") + end + end + + describe "#task_results=" do + it "forces UTF-8 encoding" do + task = FactoryGirl.create(:miq_task, :task_results => "\xC3\xA4".force_encoding("ASCII-8BIT")) + + expect(task.task_results).to eq("ä") + end + end + private def create_test_task(name, status, updated)