[Pkg-puppet-devel] [facter] 136/352: (FACT-134) Normalize copies of fact string values
Stig Sandbeck Mathisen
ssm at debian.org
Sun Apr 6 22:21:39 UTC 2014
This is an automated email from the git hooks/post-receive script.
ssm pushed a commit to branch master
in repository facter.
commit 95928792b2023577729c34d1bc9c6545ddec8825
Author: Josh Cooper <josh at puppetlabs.com>
Date: Thu Jan 9 16:37:39 2014 -0800
(FACT-134) Normalize copies of fact string values
Previously, facter would fail to normalize a frozen, non-UTF8 encoded
string, such as the value returned by the `rubyversion` fact.
This commit changes the normalization module to make a copy of the
resolved value, and perform string encoding on that. It also undoes the
change to Factet::Util::Loader that dup'ed environment variables of the
form `FACTER_*`.
Paired-with: Andy Parker <andy at puppetlabs.com>
---
lib/facter/util/loader.rb | 2 +-
lib/facter/util/normalization.rb | 22 +++++++--------
lib/facter/util/resolution.rb | 2 --
spec/unit/util/normalization_spec.rb | 52 +++++++++++++++++++++---------------
spec/unit/util/resolution_spec.rb | 29 +++++++++++---------
5 files changed, 56 insertions(+), 51 deletions(-)
diff --git a/lib/facter/util/loader.rb b/lib/facter/util/loader.rb
index f08a971..a8fb88d 100644
--- a/lib/facter/util/loader.rb
+++ b/lib/facter/util/loader.rb
@@ -141,7 +141,7 @@ class Facter::Util::Loader
Facter.add($1) do
has_weight 1_000_000
- setcode { value.dup }
+ setcode { value }
end
# Short-cut, if we are only looking for one value.
diff --git a/lib/facter/util/normalization.rb b/lib/facter/util/normalization.rb
index 693deb8..f3149f6 100644
--- a/lib/facter/util/normalization.rb
+++ b/lib/facter/util/normalization.rb
@@ -15,7 +15,7 @@ module Facter
def normalize(value)
case value
when Integer, Float, TrueClass, FalseClass, NilClass
- true
+ value
when String
normalize_string(value)
when Array
@@ -52,20 +52,19 @@ module Facter
if converted != value
raise NormalizationError, "String #{value.inspect} is not valid UTF-8"
end
+ value
end
else
def normalize_string(value)
- unless value.encoding == Encoding::UTF_8
- begin
- value.encode!(Encoding::UTF_8)
- rescue EncodingError
- raise NormalizationError, "String encoding #{value.encoding} is not UTF-8 and could not be converted to UTF-8"
- end
- end
+ value = value.encode(Encoding::UTF_8)
unless value.valid_encoding?
raise NormalizationError, "String #{value.inspect} doesn't match the reported encoding #{value.encoding}"
end
+
+ value
+ rescue EncodingError
+ raise NormalizationError, "String encoding #{value.encoding} is not UTF-8 and could not be converted to UTF-8"
end
end
@@ -76,7 +75,7 @@ module Facter
# @param value [Array]
# @return [void]
def normalize_array(value)
- value.each do |elem|
+ value.collect do |elem|
normalize(elem)
end
end
@@ -88,10 +87,7 @@ module Facter
# @param value [Hash]
# @return [void]
def normalize_hash(value)
- value.each_pair do |k, v|
- normalize(k)
- normalize(v)
- end
+ Hash[value.collect { |k, v| [ normalize(k), normalize(v) ] } ]
end
end
end
diff --git a/lib/facter/util/resolution.rb b/lib/facter/util/resolution.rb
index 140e60b..4160c9b 100644
--- a/lib/facter/util/resolution.rb
+++ b/lib/facter/util/resolution.rb
@@ -442,8 +442,6 @@ class Facter::Util::Resolution
Facter.show_time "#{self.name}: #{"%.2f" % ms}ms"
Facter::Util::Normalization.normalize(result)
-
- return result
rescue Facter::Util::Normalization::NormalizationError => e
Facter.warn "Fact resolution #{self.name} resolved to an invalid value: #{e.message}"
nil
diff --git a/spec/unit/util/normalization_spec.rb b/spec/unit/util/normalization_spec.rb
index 9e7cb0e..34f9d10 100644
--- a/spec/unit/util/normalization_spec.rb
+++ b/spec/unit/util/normalization_spec.rb
@@ -7,23 +7,38 @@ describe Facter::Util::Normalization do
subject { described_class }
+ def utf16(str)
+ str.encode(Encoding::UTF_16LE)
+ end
+
+ def utf8(str)
+ str.encode(Encoding::UTF_8)
+ end
+
describe "validating strings" do
describe "and string encoding is supported", :if => String.instance_methods.include?(:encoding) do
it "accepts strings that are ASCII and match their encoding and converts them to UTF-8" do
str = "ASCII".encode(Encoding::ASCII)
- subject.normalize(str)
- expect(str.encoding).to eq(Encoding::UTF_8)
+ normalized_str = subject.normalize(str)
+ expect(normalized_str.encoding).to eq(Encoding::UTF_8)
end
it "accepts strings that are UTF-8 and match their encoding" do
str = "let's make a ☃!".encode(Encoding::UTF_8)
- subject.normalize(str)
+ expect(subject.normalize(str)).to eq(str)
end
it "converts valid non UTF-8 strings to UTF-8" do
str = "let's make a ☃!".encode(Encoding::UTF_16LE)
- subject.normalize(str)
- expect(str.encoding).to eq(Encoding::UTF_8)
+ enc = subject.normalize(str).encoding
+ expect(enc).to eq(Encoding::UTF_8)
+ end
+
+ it "normalizes a frozen string returning a non-frozen string" do
+ str = "factvalue".encode(Encoding::UTF_16LE).freeze
+ normalized_str = subject.normalize(str)
+ expect(normalized_str.encoding).to eq(Encoding::UTF_8)
+ expect(normalized_str).to_not be_frozen
end
it "rejects strings that are not UTF-8 and do not match their claimed encoding" do
@@ -44,7 +59,7 @@ describe Facter::Util::Normalization do
describe "and string encoding is not supported", :unless => String.instance_methods.include?(:encoding) do
it "accepts strings that are UTF-8 and match their encoding" do
str = "let's make a ☃!"
- subject.normalize(str)
+ expect(subject.normalize(str)).to eq(str)
end
it "rejects strings that are not UTF-8" do
@@ -56,34 +71,27 @@ describe Facter::Util::Normalization do
end
end
- describe "validating arrays" do
+ describe "normalizing arrays" do
it "normalizes each element in the array" do
- arr = ['first', 'second', ['third', 'fourth']]
+ arr = [utf16('first'), utf16('second'), [utf16('third'), utf16('fourth')]]
+ expected_arr = [utf8('first'), utf8('second'), [utf8('third'), utf8('fourth')]]
- subject.expects(:normalize).with('first')
- subject.expects(:normalize).with('second')
- subject.expects(:normalize).with(['third', 'fourth'])
-
- subject.normalize_array(arr)
+ expect(subject.normalize_array(arr)).to eq(expected_arr)
end
end
- describe "validating hashes" do
+ describe "normalizing hashes" do
it "normalizes each element in the array" do
- hsh = {'first' => 'second', 'third' => ['fourth', 'fifth']}
-
- subject.expects(:normalize).with('first')
- subject.expects(:normalize).with('second')
- subject.expects(:normalize).with('third')
- subject.expects(:normalize).with(['fourth', 'fifth'])
+ hsh = {utf16('first') => utf16('second'), utf16('third') => [utf16('fourth'), utf16('fifth')]}
+ expected_hsh = {utf8('first') => utf8('second'), utf8('third') => [utf8('fourth'), utf8('fifth')]}
- subject.normalize_hash(hsh)
+ expect(subject.normalize_hash(hsh)).to eq(expected_hsh)
end
end
[1, 1.0, true, false, nil].each do |val|
it "accepts #{val.inspect}:#{val.class}" do
- subject.normalize(val)
+ expect(subject.normalize(val)).to eq(val)
end
end
diff --git a/spec/unit/util/resolution_spec.rb b/spec/unit/util/resolution_spec.rb
index 51767df..755b252 100755
--- a/spec/unit/util/resolution_spec.rb
+++ b/spec/unit/util/resolution_spec.rb
@@ -181,6 +181,8 @@ describe Facter::Util::Resolution do
end
describe "when returning the value" do
+ let(:utf16_string) { "".encode(Encoding::UTF_16LE).freeze }
+
before do
@resolve = Facter::Util::Resolution.new("yay")
end
@@ -210,11 +212,12 @@ describe Facter::Util::Resolution do
@resolve.value.should == "yup"
end
- it "it validates the resolved value" do
+ it "it normalizes the resolved value" do
@resolve.setcode "/bin/foo"
- Facter::Util::Resolution.expects(:exec).once.returns ""
- Facter::Util::Normalization.expects(:normalize).with ""
- @resolve.value.should eq ""
+
+ Facter::Util::Resolution.expects(:exec).once.returns(utf16_string)
+
+ expect(@resolve.value).to eq(utf16_string.encode(Encoding::UTF_8))
end
end
@@ -230,11 +233,12 @@ describe Facter::Util::Resolution do
@resolve.value.should == "yup"
end
- it "it validates the resolved value" do
+ it "it normalizes the resolved value" do
@resolve.setcode "/bin/foo"
- Facter::Util::Resolution.expects(:exec).once.returns ""
- Facter::Util::Normalization.expects(:normalize).with ""
- @resolve.value.should eq ""
+
+ Facter::Util::Resolution.expects(:exec).once.returns(utf16_string)
+
+ expect(@resolve.value).to eq(utf16_string.encode(Encoding::UTF_8))
end
end
end
@@ -251,11 +255,10 @@ describe Facter::Util::Resolution do
@resolve.value.should == "yayness"
end
- it "it validates the resolved value" do
- @resolve.setcode "/bin/foo"
- Facter::Util::Resolution.expects(:exec).once.returns ""
- Facter::Util::Normalization.expects(:normalize).with ""
- @resolve.value.should eq ""
+ it "it normalizes the resolved value" do
+ @resolve.setcode { utf16_string }
+
+ expect(@resolve.value).to eq(utf16_string.encode(Encoding::UTF_8))
end
it "should use its limit method to determine the timeout, to avoid conflict when a 'timeout' method exists for some other reason" do
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-puppet/facter.git
More information about the Pkg-puppet-devel
mailing list