puppet 4.10.1 → 4.10.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (120) hide show
  1. data/ext/project_data.yaml +1 -1
  2. data/lib/puppet.rb +40 -28
  3. data/lib/puppet/application/agent.rb +1 -1
  4. data/lib/puppet/application/apply.rb +1 -1
  5. data/lib/puppet/application/cert.rb +1 -1
  6. data/lib/puppet/application/describe.rb +1 -1
  7. data/lib/puppet/application/device.rb +1 -1
  8. data/lib/puppet/application/doc.rb +3 -3
  9. data/lib/puppet/application/filebucket.rb +1 -1
  10. data/lib/puppet/application/inspect.rb +2 -2
  11. data/lib/puppet/application/lookup.rb +1 -1
  12. data/lib/puppet/application/master.rb +1 -1
  13. data/lib/puppet/application/resource.rb +7 -7
  14. data/lib/puppet/defaults.rb +1 -1
  15. data/lib/puppet/etc.rb +75 -39
  16. data/lib/puppet/face/ca.rb +1 -1
  17. data/lib/puppet/face/catalog.rb +1 -1
  18. data/lib/puppet/face/certificate.rb +1 -1
  19. data/lib/puppet/face/certificate_request.rb +1 -1
  20. data/lib/puppet/face/certificate_revocation_list.rb +1 -1
  21. data/lib/puppet/face/config.rb +1 -1
  22. data/lib/puppet/face/epp.rb +1 -1
  23. data/lib/puppet/face/facts.rb +1 -1
  24. data/lib/puppet/face/file.rb +1 -1
  25. data/lib/puppet/face/help.rb +1 -1
  26. data/lib/puppet/face/key.rb +1 -1
  27. data/lib/puppet/face/man.rb +2 -2
  28. data/lib/puppet/face/module.rb +1 -1
  29. data/lib/puppet/face/node.rb +1 -1
  30. data/lib/puppet/face/parser.rb +1 -1
  31. data/lib/puppet/face/plugin.rb +1 -1
  32. data/lib/puppet/face/report.rb +1 -1
  33. data/lib/puppet/face/resource.rb +1 -1
  34. data/lib/puppet/face/resource_type.rb +1 -1
  35. data/lib/puppet/face/status.rb +1 -1
  36. data/lib/puppet/feature/base.rb +1 -1
  37. data/lib/puppet/functions/eyaml_lookup_key.rb +16 -12
  38. data/lib/puppet/functions/hiera.rb +9 -2
  39. data/lib/puppet/functions/hiera_array.rb +9 -2
  40. data/lib/puppet/functions/hiera_hash.rb +10 -2
  41. data/lib/puppet/functions/hiera_include.rb +17 -3
  42. data/lib/puppet/functions/hocon_data.rb +6 -0
  43. data/lib/puppet/functions/json_data.rb +4 -0
  44. data/lib/puppet/functions/yaml_data.rb +4 -0
  45. data/lib/puppet/generate/models/type/type.rb +6 -5
  46. data/lib/puppet/generate/templates/type/pcore.erb +1 -1
  47. data/lib/puppet/module_tool/skeleton/templates/generator/examples/init.pp.erb +1 -1
  48. data/lib/puppet/parser/functions/create_resources.rb +8 -0
  49. data/lib/puppet/parser/scope.rb +2 -2
  50. data/lib/puppet/pops/adapters.rb +10 -4
  51. data/lib/puppet/pops/evaluator/runtime3_resource_support.rb +0 -2
  52. data/lib/puppet/pops/evaluator/runtime3_support.rb +31 -0
  53. data/lib/puppet/pops/issues.rb +8 -0
  54. data/lib/puppet/pops/loader/loader.rb +4 -0
  55. data/lib/puppet/pops/loader/module_loaders.rb +0 -2
  56. data/lib/puppet/pops/loader/static_loader.rb +1 -1
  57. data/lib/puppet/pops/loader/type_definition_instantiator.rb +1 -1
  58. data/lib/puppet/pops/loader/typed_name.rb +1 -0
  59. data/lib/puppet/pops/loaders.rb +7 -15
  60. data/lib/puppet/pops/lookup/environment_data_provider.rb +1 -1
  61. data/lib/puppet/pops/lookup/hiera_config.rb +3 -1
  62. data/lib/puppet/pops/lookup/interpolation.rb +2 -1
  63. data/lib/puppet/pops/lookup/lookup_key.rb +1 -1
  64. data/lib/puppet/pops/lookup/module_data_provider.rb +10 -2
  65. data/lib/puppet/pops/lookup/sub_lookup.rb +10 -9
  66. data/lib/puppet/pops/parser/lexer2.rb +20 -3
  67. data/lib/puppet/pops/pcore.rb +2 -2
  68. data/lib/puppet/pops/resource/resource_type_impl.rb +2 -2
  69. data/lib/puppet/pops/semantic_error.rb +12 -0
  70. data/lib/puppet/pops/serialization/deserializer.rb +7 -4
  71. data/lib/puppet/pops/types/p_type_set_type.rb +2 -2
  72. data/lib/puppet/pops/types/string_converter.rb +5 -17
  73. data/lib/puppet/pops/types/type_set_reference.rb +1 -1
  74. data/lib/puppet/pops/validation/checker4_0.rb +4 -0
  75. data/lib/puppet/pops/validation/validator_factory_4_0.rb +1 -0
  76. data/lib/puppet/provider/nameservice.rb +12 -4
  77. data/lib/puppet/provider/package/yum.rb +8 -8
  78. data/lib/puppet/provider/user/useradd.rb +1 -1
  79. data/lib/puppet/reference/configuration.rb +1 -1
  80. data/lib/puppet/resource.rb +9 -11
  81. data/lib/puppet/resource/type_collection.rb +1 -0
  82. data/lib/puppet/type/exec.rb +32 -26
  83. data/lib/puppet/type/file/mode.rb +4 -0
  84. data/lib/puppet/util/character_encoding.rb +77 -74
  85. data/lib/puppet/util/monkey_patches.rb +3 -1
  86. data/lib/puppet/util/windows/api_types.rb +3 -0
  87. data/lib/puppet/util/windows/file.rb +1 -1
  88. data/lib/puppet/version.rb +1 -1
  89. data/locales/puppet.pot +31 -7
  90. data/spec/integration/faces/documentation_spec.rb +2 -2
  91. data/spec/integration/parser/pcore_resource_spec.rb +15 -0
  92. data/spec/integration/resource/type_collection_spec.rb +6 -0
  93. data/spec/lib/puppet/face/1.0.0/huzzah.rb +1 -1
  94. data/spec/lib/puppet/face/basetest.rb +1 -1
  95. data/spec/lib/puppet/face/huzzah.rb +1 -1
  96. data/spec/lib/puppet/face/version_matching.rb +1 -1
  97. data/spec/lib/puppet_spec/character_encoding.rb +12 -0
  98. data/spec/lib/puppet_spec/compiler.rb +7 -0
  99. data/spec/shared_examples/rhel_package_provider.rb +10 -11
  100. data/spec/unit/application/resource_spec.rb +22 -1
  101. data/spec/unit/configurer/fact_handler_spec.rb +2 -1
  102. data/spec/unit/etc_spec.rb +361 -153
  103. data/spec/unit/functions/lookup_spec.rb +118 -2
  104. data/spec/unit/parser/functions/create_resources_spec.rb +47 -6
  105. data/spec/unit/parser/scope_spec.rb +8 -0
  106. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +40 -0
  107. data/spec/unit/pops/loaders/loaders_spec.rb +141 -79
  108. data/spec/unit/pops/lookup/interpolation_spec.rb +49 -9
  109. data/spec/unit/pops/lookup/lookup_spec.rb +32 -0
  110. data/spec/unit/pops/parser/lexer2_spec.rb +28 -0
  111. data/spec/unit/pops/types/p_object_type_spec.rb +1 -1
  112. data/spec/unit/pops/types/p_type_set_type_spec.rb +1 -1
  113. data/spec/unit/pops/types/string_converter_spec.rb +21 -0
  114. data/spec/unit/pops/validator/validator_spec.rb +43 -0
  115. data/spec/unit/provider/nameservice/directoryservice_spec.rb +2 -0
  116. data/spec/unit/provider/nameservice_spec.rb +113 -3
  117. data/spec/unit/provider/user/useradd_spec.rb +13 -0
  118. data/spec/unit/resource/catalog_spec.rb +21 -0
  119. data/spec/unit/util/character_encoding_spec.rb +193 -52
  120. metadata +4 -2
@@ -364,6 +364,19 @@ describe Puppet::Type.type(:user).provider(:useradd) do
364
364
  Shadow::Passwd.expects(:getspnam).with('myuser').returns shadow_entry
365
365
  expect(provider.send(property)).to eq(expected_value)
366
366
  end
367
+
368
+ # nameservice provider instances are initialized with a @canonical_name
369
+ # instance variable to track the original name of the instance on disk
370
+ # before converting it to UTF-8 if appropriate. When re-querying the
371
+ # system for attributes of this user such as password info, we need to
372
+ # supply the pre-UTF8-converted value.
373
+ it "should query using the canonical_name attribute of the user", :if => Puppet.features.libshadow? do
374
+ canonical_name = [253, 241].pack('C*').force_encoding(Encoding::EUC_KR)
375
+ provider = described_class.new(:name => '??', :canonical_name => canonical_name)
376
+
377
+ Shadow::Passwd.expects(:getspnam).with(canonical_name).returns shadow_entry
378
+ provider.password
379
+ end
367
380
  end
368
381
  end
369
382
 
@@ -972,6 +972,27 @@ describe Puppet::Resource::Catalog, "when converting a resource catalog to pson"
972
972
  expect(message).to be_a(String)
973
973
  expect(message).to eql('2016-09-15T08:32:16.123 UTC')
974
974
  end
975
+
976
+ it 'should convert param containing array with :undef entries' do
977
+ catalog = compile_to_catalog("notify {'foo': message => [ 10, undef, 20 ] }")
978
+ catalog2 = Puppet::Resource::Catalog.from_data_hash(JSON.parse(catalog.to_json))
979
+ message = catalog2.resource('notify', 'foo')['message']
980
+ expect(message).to be_a(Array)
981
+ expect(message[0]).to eql(10)
982
+ expect(message[1]).to eql(nil)
983
+ expect(message[2]).to eql(20)
984
+ end
985
+
986
+ it 'should convert param containing hash with :undef entries' do
987
+ catalog = compile_to_catalog("notify {'foo': message => {a => undef, b => 10}}")
988
+ catalog2 = Puppet::Resource::Catalog.from_data_hash(JSON.parse(catalog.to_json))
989
+ message = catalog2.resource('notify', 'foo')['message']
990
+ expect(message).to be_a(Hash)
991
+ expect(message.has_key?('a')).to eql(true)
992
+ expect(message['a']).to eql(nil)
993
+ expect(message['b']).to eql(10)
994
+ end
995
+
975
996
  end
976
997
 
977
998
  end
@@ -1,14 +1,20 @@
1
1
  #! /usr/bin/env ruby
2
2
  require 'spec_helper'
3
3
  require 'puppet/util/character_encoding'
4
+ require 'puppet_spec/character_encoding'
4
5
 
5
6
  describe Puppet::Util::CharacterEncoding do
6
- describe "::convert_to_utf_8!" do
7
+ describe "::convert_to_utf_8" do
7
8
  context "when passed a string that is already UTF-8" do
8
9
  context "with valid encoding" do
9
- it "should return the string unaltered" do
10
- utf8_string = "\u06FF\u2603"
11
- expect(Puppet::Util::CharacterEncoding.convert_to_utf_8!(utf8_string)).to eq(utf8_string)
10
+ let(:utf8_string) { "\u06FF\u2603".force_encoding(Encoding::UTF_8) }
11
+
12
+ it "should return the string unmodified" do
13
+ expect(Puppet::Util::CharacterEncoding.convert_to_utf_8(utf8_string)).to eq("\u06FF\u2603".force_encoding(Encoding::UTF_8))
14
+ end
15
+
16
+ it "should not mutate the original string" do
17
+ expect(utf8_string).to eq("\u06FF\u2603".force_encoding(Encoding::UTF_8))
12
18
  end
13
19
  end
14
20
 
@@ -16,73 +22,208 @@ describe Puppet::Util::CharacterEncoding do
16
22
  let(:invalid_utf8_string) { "\xfd\xf1".force_encoding(Encoding::UTF_8) }
17
23
 
18
24
  it "should issue a debug message" do
19
- Puppet.expects(:debug).with(regexp_matches(/not valid UTF-8/))
20
- Puppet::Util::CharacterEncoding.convert_to_utf_8!(invalid_utf8_string)
25
+ Puppet.expects(:debug).with(regexp_matches(/encoding is invalid/))
26
+ Puppet::Util::CharacterEncoding.convert_to_utf_8(invalid_utf8_string)
21
27
  end
22
28
 
23
- it "should return nil" do
24
- expect(Puppet::Util::CharacterEncoding.convert_to_utf_8!(invalid_utf8_string)).to be_nil
29
+ it "should return the string unmodified" do
30
+ expect(Puppet::Util::CharacterEncoding.convert_to_utf_8(invalid_utf8_string)).to eq("\xfd\xf1".force_encoding(Encoding::UTF_8))
31
+ end
32
+
33
+ it "should not mutate the original string" do
34
+ Puppet::Util::CharacterEncoding.convert_to_utf_8(invalid_utf8_string)
35
+ expect(invalid_utf8_string).to eq("\xfd\xf1".force_encoding(Encoding::UTF_8))
25
36
  end
26
37
  end
27
38
  end
28
39
 
29
- context "when passed a string not in UTF-8 encoding" do
30
- context "the bytes of which represent valid UTF-8" do
31
- # I think this effectively what the ruby Etc module is doing when it
32
- # returns strings read in from /etc/passwd and /etc/group
33
- let(:iso_8859_1_string) { [225, 154, 160].pack('C*').force_encoding(Encoding::ISO_8859_1) }
34
- let(:result) { Puppet::Util::CharacterEncoding.convert_to_utf_8!(iso_8859_1_string) }
40
+ context "when passed a string in BINARY encoding" do
41
+ context "that is valid in Encoding.default_external" do
42
+ # When received as BINARY are not transcodable, but by "guessing"
43
+ # Encoding.default_external can transcode to UTF-8
44
+ let(:win_31j) { [130, 187].pack('C*') } # pack('C*') returns string in BINARY
45
+
46
+ it "should be able to convert to UTF-8 by labeling as Encoding.default_external" do
47
+ # そ - HIRAGANA LETTER SO
48
+ # In Windows_31J: \x82 \xbb - 130 187
49
+ # In Unicode: \u305d - \xe3 \x81 \x9d - 227 129 157
50
+ result = PuppetSpec::CharacterEncoding.with_external_encoding(Encoding::Windows_31J) do
51
+ Puppet::Util::CharacterEncoding.convert_to_utf_8(win_31j)
52
+ end
53
+ expect(result).to eq("\u305d")
54
+ expect(result.bytes.to_a).to eq([227, 129, 157])
55
+ end
56
+
57
+ it "should not mutate the original string" do
58
+ PuppetSpec::CharacterEncoding.with_external_encoding(Encoding::Windows_31J) do
59
+ Puppet::Util::CharacterEncoding.convert_to_utf_8(win_31j)
60
+ end
61
+ expect(win_31j).to eq([130, 187].pack('C*'))
62
+ end
63
+ end
64
+
65
+ context "that is invalid in Encoding.default_external" do
66
+ let(:invalid_win_31j) { [255, 254, 253].pack('C*') } # these bytes are not valid windows_31j
35
67
 
36
- it "should set external encoding to UTF-8" do
37
- expect(result.encoding).to eq(Encoding::UTF_8)
68
+ it "should return the string umodified" do
69
+ result = PuppetSpec::CharacterEncoding.with_external_encoding(Encoding::Windows_31J) do
70
+ Puppet::Util::CharacterEncoding.convert_to_utf_8(invalid_win_31j)
71
+ end
72
+ expect(result.bytes.to_a).to eq([255, 254, 253])
73
+ expect(result.encoding).to eq(Encoding::BINARY)
38
74
  end
39
75
 
40
- it "should not modify the bytes (transcode) the string" do
41
- expect(result.bytes.to_a).to eq([225, 154, 160])
76
+ it "should not mutate the original string" do
77
+ PuppetSpec::CharacterEncoding.with_external_encoding(Encoding::Windows_31J) do
78
+ Puppet::Util::CharacterEncoding.convert_to_utf_8(invalid_win_31j)
79
+ end
80
+ expect(invalid_win_31j).to eq([255, 254, 253].pack('C*'))
81
+ end
82
+
83
+ it "should issue a debug message that the string was not transcodable" do
84
+ Puppet.expects(:debug).with(regexp_matches(/cannot be transcoded/))
85
+ PuppetSpec::CharacterEncoding.with_external_encoding(Encoding::Windows_31J) do
86
+ Puppet::Util::CharacterEncoding.convert_to_utf_8(invalid_win_31j)
87
+ end
42
88
  end
43
89
  end
44
90
 
45
- context "the bytes of which do not represent valid UTF-8" do
46
- it "should transcode the string to UTF-8 if it is transcodable" do
47
- # http://www.fileformat.info/info/unicode/char/3050/index.htm
48
- # ぐ - HIRAGANA LETTER GU
49
- # In Shift_JIS: \x82 \xae - 130 174
50
- # In Unicode: \u3050 - \xe3 \x81 \x90 - 227 129 144
51
- # if we were only ruby > 2.3.0, we could do String.new("\x82\xae", :encoding => Encoding::Shift_JIS)
52
- as_shift_jis = [130, 174].pack('C*').force_encoding(Encoding::Shift_JIS)
53
- as_utf8 = "\u3050"
54
-
55
- # this is not valid UTF-8
56
- expect(as_shift_jis.dup.force_encoding(Encoding::UTF_8).valid_encoding?).to be_falsey
57
-
58
- result = Puppet::Util::CharacterEncoding.convert_to_utf_8!(as_shift_jis)
59
- expect(result).to eq(as_utf8)
60
- # largely redundant but reinforces the point - this was transcoded:
61
- expect(result.bytes.to_a).to eq([227, 129, 144])
91
+ context "Given a string labeled as neither UTF-8 nor BINARY" do
92
+ context "that is transcodable" do
93
+ let (:shift_jis) { [130, 174].pack('C*').force_encoding(Encoding::Shift_JIS) }
94
+
95
+ it "should return a copy of the string transcoded to UTF-8 if it is transcodable" do
96
+ # http://www.fileformat.info/info/unicode/char/3050/index.htm
97
+ # - HIRAGANA LETTER GU
98
+ # In Shift_JIS: \x82 \xae - 130 174
99
+ # In Unicode: \u3050 - \xe3 \x81 \x90 - 227 129 144
100
+ # if we were only ruby > 2.3.0, we could do String.new("\x82\xae", :encoding => Encoding::Shift_JIS)
101
+
102
+ result = Puppet::Util::CharacterEncoding.convert_to_utf_8(shift_jis)
103
+ expect(result).to eq("\u3050".force_encoding(Encoding::UTF_8))
104
+ # largely redundant but reinforces the point - this was transcoded:
105
+ expect(result.bytes.to_a).to eq([227, 129, 144])
106
+ end
107
+
108
+ it "should not mutate the original string" do
109
+ Puppet::Util::CharacterEncoding.convert_to_utf_8(shift_jis)
110
+ expect(shift_jis).to eq([130, 174].pack('C*').force_encoding(Encoding::Shift_JIS))
111
+ end
62
112
  end
63
113
 
64
- context "if it is not transcodable" do
65
- let(:as_ascii) { [254, 241].pack('C*').force_encoding(Encoding::ASCII) }
66
- it "should issue a debug message and return nil if not transcodable" do
67
- # An admittedly contrived case, but perhaps not so improbable
68
- # http://www.fileformat.info/info/unicode/char/5e0c/index.htm
69
- # Han Character 'rare; hope, expect, strive for'
70
- # In EUC_KR: \xfd \xf1 - 253 241
71
- # In Unicode: \u5e0c - \xe5 \xb8 \x8c - 229 184 140
72
-
73
- # If the original system value is in EUC_KR, and puppet (ruby) is run
74
- # in ISO_8859_1, this value will be read in as ASCII, with invalid
75
- # escape sequences in that encoding. It is also not valid unicode
76
- # as-is. This scenario is one we can't recover from, so fail.
77
- Puppet.expects(:debug).with(regexp_matches(/not valid UTF-8/))
78
- Puppet::Util::CharacterEncoding.convert_to_utf_8!(as_ascii)
114
+ context "when not transcodable" do
115
+ # An admittedly contrived case, but perhaps not so improbable
116
+ # http://www.fileformat.info/info/unicode/char/5e0c/index.htm
117
+ # Han Character 'rare; hope, expect, strive for'
118
+ # In EUC_KR: \xfd \xf1 - 253 241
119
+ # In Unicode: \u5e0c - \xe5 \xb8 \x8c - 229 184 140
120
+
121
+ # In this case, this EUC_KR character has been read in as ASCII and is
122
+ # invalid in that encoding. This would raise an EncodingError
123
+ # exception on transcode but we catch this issue a debug message -
124
+ # leaving the original string unaltered.
125
+ let(:euc_kr) { [253, 241].pack('C*').force_encoding(Encoding::ASCII) }
126
+
127
+ it "should issue a debug message" do
128
+ Puppet.expects(:debug).with(regexp_matches(/cannot be transcoded/))
129
+ Puppet::Util::CharacterEncoding.convert_to_utf_8(euc_kr)
130
+ end
131
+
132
+ it "should return the original string unmodified" do
133
+ result = Puppet::Util::CharacterEncoding.convert_to_utf_8(euc_kr)
134
+ expect(result).to eq([253, 241].pack('C*').force_encoding(Encoding::ASCII))
79
135
  end
80
136
 
81
- it "should return nil" do
82
- expect(Puppet::Util::CharacterEncoding.convert_to_utf_8!(as_ascii)).to be_nil
137
+ it "should not mutate the original string" do
138
+ Puppet::Util::CharacterEncoding.convert_to_utf_8(euc_kr)
139
+ expect(euc_kr).to eq([253, 241].pack('C*').force_encoding(Encoding::ASCII))
83
140
  end
84
141
  end
85
142
  end
86
143
  end
87
144
  end
145
+
146
+ describe "::override_encoding_to_utf_8" do
147
+ context "given a string with bytes that represent valid UTF-8" do
148
+ # ☃ - unicode snowman
149
+ # \u2603 - \xe2 \x98 \x83 - 226 152 131
150
+ let(:snowman) { [226, 152, 131].pack('C*') }
151
+
152
+ it "should return a copy of the string with external encoding of the string to UTF-8" do
153
+ result = Puppet::Util::CharacterEncoding.override_encoding_to_utf_8(snowman)
154
+ expect(result).to eq("\u2603")
155
+ expect(result.encoding).to eq(Encoding::UTF_8)
156
+ end
157
+
158
+ it "should not modify the original string" do
159
+ Puppet::Util::CharacterEncoding.override_encoding_to_utf_8(snowman)
160
+ expect(snowman).to eq([226, 152, 131].pack('C*'))
161
+ end
162
+ end
163
+
164
+ context "given a string with bytes that do not represent valid UTF-8" do
165
+ # Ø - Latin capital letter O with stroke
166
+ # In ISO-8859-1: \xd8 - 216
167
+ # Invalid in UTF-8 without transcoding
168
+ let(:oslash) { [216].pack('C*').force_encoding(Encoding::ISO_8859_1) }
169
+ let(:foo) { 'foo' }
170
+ it "should issue a debug message" do
171
+ Puppet.expects(:debug).with(regexp_matches(/not valid UTF-8/))
172
+ Puppet::Util::CharacterEncoding.override_encoding_to_utf_8(oslash)
173
+ end
174
+
175
+ it "should return the original string unmodified" do
176
+ result = Puppet::Util::CharacterEncoding.override_encoding_to_utf_8(oslash)
177
+ expect(result).to eq([216].pack('C*').force_encoding(Encoding::ISO_8859_1))
178
+ end
179
+
180
+ it "should not modify the string" do
181
+ Puppet::Util::CharacterEncoding.override_encoding_to_utf_8(oslash)
182
+ expect(oslash).to eq([216].pack('C*').force_encoding(Encoding::ISO_8859_1))
183
+ end
184
+ end
185
+ end
186
+
187
+ describe "::scrub" do
188
+ let(:utf_8_string_to_scrub) { "\xfdfoo".force_encoding(Encoding::UTF_8) } # invalid in UTF-8
189
+ # The invalid-ness of this string comes from unpaired surrogates, ie:
190
+ # "any value in the range D80016 to DBFF16 not followed by a value in the
191
+ # range DC0016 to DFFF16, or any value in the range DC0016 to DFFF16 not
192
+ # preceded by a value in the range D80016 to DBFF16"
193
+ # http://unicode.org/faq/utf_bom.html#utf16-7
194
+ # "a\ud800b"
195
+ # We expect the "b" to be replaced as that is what makes the string invalid
196
+ let(:utf_16LE_string_to_scrub) { [97, 237, 160, 128, 98].pack('C*').force_encoding(Encoding::UTF_16LE) } # invalid in UTF-16
197
+ let(:invalid_non_utf) { "foo\u2603".force_encoding(Encoding::EUC_KR) } # EUC_KR foosnowman!
198
+
199
+ it "should defer to String#scrub if defined", :if => String.method_defined?(:scrub) do
200
+ result = Puppet::Util::CharacterEncoding.scrub(utf_8_string_to_scrub)
201
+ # The result should have the UTF-8 replacement character if we're using Ruby scrub
202
+ expect(result).to eq("\uFFFDfoo".force_encoding(Encoding::UTF_8))
203
+ expect(result.bytes.to_a).to eq([239, 191, 189, 102, 111, 111])
204
+ end
205
+
206
+ context "when String#scrub is not defined" do
207
+ it "should still issue unicode replacement characters if the string is UTF-8" do
208
+ utf_8_string_to_scrub.stubs(:respond_to?).with(:scrub).returns(false)
209
+ result = Puppet::Util::CharacterEncoding.scrub(utf_8_string_to_scrub)
210
+ expect(result).to eq("\uFFFDfoo".force_encoding(Encoding::UTF_8))
211
+ end
212
+
213
+ it "should still issue unicode replacement characters if the string is UTF-16LE" do
214
+ utf_16LE_string_to_scrub.stubs(:respond_to?).with(:scrub).returns(false)
215
+ result = Puppet::Util::CharacterEncoding.scrub(utf_16LE_string_to_scrub)
216
+ # Bytes of replacement character on UTF_16LE are [253, 255]
217
+ # We just check for bytes because something (ruby?) interprets this array of bytes as:
218
+ # (97) (237 160) (128 253 255) rather than (97) (237 160 128) (253 255)
219
+ expect(result).to eq([97, 237, 160, 128, 253, 255].pack('C*').force_encoding(Encoding::UTF_16LE))
220
+ end
221
+
222
+ it "should issue '?' characters if the string is not one of UTF_8 or UTF_16LE" do
223
+ invalid_non_utf.stubs(:respond_to?).with(:scrub).returns(false)
224
+ result = Puppet::Util::CharacterEncoding.scrub(invalid_non_utf)
225
+ expect(result).to eq("foo???".force_encoding(Encoding::EUC_KR))
226
+ end
227
+ end
228
+ end
88
229
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppet
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.10.1
4
+ version: 4.10.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-05-01 00:00:00.000000000 Z
12
+ date: 2017-06-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: facter
@@ -2091,6 +2091,7 @@ files:
2091
2091
  - spec/lib/puppet/indirector/indirector_testing/msgpack.rb
2092
2092
  - spec/lib/puppet/indirector_proxy.rb
2093
2093
  - spec/lib/puppet/indirector_testing.rb
2094
+ - spec/lib/puppet_spec/character_encoding.rb
2094
2095
  - spec/lib/puppet_spec/compiler.rb
2095
2096
  - spec/lib/puppet_spec/files.rb
2096
2097
  - spec/lib/puppet_spec/fixtures.rb
@@ -3372,6 +3373,7 @@ test_files:
3372
3373
  - spec/lib/puppet/indirector/indirector_testing/msgpack.rb
3373
3374
  - spec/lib/puppet/indirector_proxy.rb
3374
3375
  - spec/lib/puppet/indirector_testing.rb
3376
+ - spec/lib/puppet_spec/character_encoding.rb
3375
3377
  - spec/lib/puppet_spec/compiler.rb
3376
3378
  - spec/lib/puppet_spec/files.rb
3377
3379
  - spec/lib/puppet_spec/fixtures.rb