puppet 4.10.6-x86-mingw32 → 4.10.7-x86-mingw32
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.
- data/lib/puppet/application/device.rb +34 -26
- data/lib/puppet/functions/epp.rb +3 -0
- data/lib/puppet/generate/models/type/property.rb +1 -1
- data/lib/puppet/indirector/request.rb +4 -4
- data/lib/puppet/parser/ast/leaf.rb +1 -1
- data/lib/puppet/parser/functions/epp.rb +3 -0
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +1 -1
- data/lib/puppet/pops/model/model_tree_dumper.rb +1 -1
- data/lib/puppet/pops/patterns.rb +1 -1
- data/lib/puppet/pops/types/string_converter.rb +2 -4
- data/lib/puppet/pops/types/type_calculator.rb +1 -1
- data/lib/puppet/pops/types/type_formatter.rb +1 -1
- data/lib/puppet/pops/types/types.rb +56 -2
- data/lib/puppet/provider/package/aix.rb +1 -1
- data/lib/puppet/provider/package/yum.rb +1 -0
- data/lib/puppet/util/windows/api_types.rb +9 -5
- data/lib/puppet/util/windows/process.rb +9 -1
- data/lib/puppet/version.rb +1 -1
- data/spec/fixtures/unit/provider/package/yum/yum-check-update-plugin-output.txt +36 -0
- data/spec/integration/util/windows/process_spec.rb +45 -0
- data/spec/unit/functions/epp_spec.rb +5 -0
- data/spec/unit/indirector/request_spec.rb +41 -0
- data/spec/unit/parser/ast/leaf_spec.rb +3 -4
- data/spec/unit/pops/types/string_converter_spec.rb +22 -0
- data/spec/unit/provider/package/aix_spec.rb +8 -0
- data/spec/unit/provider/package/yum_spec.rb +10 -0
- data/spec/unit/util/windows/api_types_spec.rb +51 -0
- metadata +3614 -3586
- checksums.yaml +0 -7
@@ -65,50 +65,54 @@ puppet-device(8) -- Manage remote network devices
|
|
65
65
|
|
66
66
|
SYNOPSIS
|
67
67
|
--------
|
68
|
-
Retrieves
|
69
|
-
|
68
|
+
Retrieves catalogs from the Puppet master and applies them to remote devices.
|
69
|
+
|
70
|
+
This subcommand can be run manually; or periodically using cron,
|
71
|
+
a scheduled task, or a similar tool.
|
70
72
|
|
71
|
-
Currently must be run out periodically, using cron or something similar.
|
72
73
|
|
73
74
|
USAGE
|
74
75
|
-----
|
75
|
-
puppet device [-d|--debug] [--detailed-exitcodes]
|
76
|
+
puppet device [-d|--debug] [--detailed-exitcodes]
|
76
77
|
[-h|--help] [-l|--logdest syslog|<file>|console]
|
77
78
|
[-v|--verbose] [-w|--waitforcert <seconds>]
|
79
|
+
[--user=<user>] [-V|--version]
|
78
80
|
|
79
81
|
|
80
82
|
DESCRIPTION
|
81
83
|
-----------
|
82
|
-
|
83
|
-
retrieve
|
84
|
+
Devices require a proxy Puppet agent to request certificates, collect facts,
|
85
|
+
retrieve and apply catalogs, and store reports.
|
86
|
+
|
84
87
|
|
85
88
|
USAGE NOTES
|
86
89
|
-----------
|
87
|
-
|
90
|
+
Devices managed by the puppet-device subcommand on a Puppet agent are
|
91
|
+
configured in device.conf, which is located at $confdir/device.conf by default,
|
92
|
+
and is configurable with the $deviceconfig setting.
|
93
|
+
|
94
|
+
The device.conf file is an INI-like file, with one section per device:
|
95
|
+
|
96
|
+
[<DEVICE_CERTNAME>]
|
97
|
+
type <TYPE>
|
98
|
+
url <URL>
|
99
|
+
debug
|
88
100
|
|
89
|
-
|
90
|
-
type <type>
|
91
|
-
url <url>
|
101
|
+
The section name specifies the certname of the device.
|
92
102
|
|
93
|
-
|
94
|
-
* type: the current device type (the only value at this time is cisco)
|
95
|
-
* url: an url allowing to connect to the device
|
103
|
+
The values for the type and url properties are specific to each type of device.
|
96
104
|
|
97
|
-
|
98
|
-
|
105
|
+
The optional debug property specifies transport-level debugging,
|
106
|
+
and is limited to telnet and ssh transports.
|
107
|
+
|
108
|
+
See https://docs.puppet.com/puppet/latest/config_file_device.html for details.
|
99
109
|
|
100
|
-
with:
|
101
|
-
* scheme: either ssh or telnet
|
102
|
-
* user: username, can be omitted depending on the switch/router configuration
|
103
|
-
* password: the connection password
|
104
|
-
* query: this is device specific. Cisco devices supports an enable parameter whose
|
105
|
-
value would be the enable password.
|
106
110
|
|
107
111
|
OPTIONS
|
108
112
|
-------
|
109
|
-
Note that any setting that's valid in the configuration file
|
110
|
-
|
111
|
-
|
113
|
+
Note that any setting that's valid in the configuration file is also a valid
|
114
|
+
long argument. For example, 'server' is a valid configuration parameter, so
|
115
|
+
you can specify '--server <servername>' as an argument.
|
112
116
|
|
113
117
|
* --debug:
|
114
118
|
Enable full debugging.
|
@@ -133,6 +137,10 @@ parameter, so you can specify '--server <servername>' as an argument.
|
|
133
137
|
appending nature of logging. It must be appended manually to make the content
|
134
138
|
valid JSON.
|
135
139
|
|
140
|
+
* --user:
|
141
|
+
The user to run as. '--user=root' is required, even when run as root,
|
142
|
+
for runs that create device certificates or keys.
|
143
|
+
|
136
144
|
* --verbose:
|
137
145
|
Turn on verbose reporting.
|
138
146
|
|
@@ -141,8 +149,8 @@ parameter, so you can specify '--server <servername>' as an argument.
|
|
141
149
|
and it is enabled by default, with a value of 120 (seconds). This causes
|
142
150
|
+puppet agent+ to connect to the server every 2 minutes and ask it to sign a
|
143
151
|
certificate request. This is useful for the initial setup of a puppet
|
144
|
-
client. You can turn off waiting for certificates by specifying a time
|
145
|
-
|
152
|
+
client. You can turn off waiting for certificates by specifying a time of 0.
|
153
|
+
|
146
154
|
|
147
155
|
EXAMPLE
|
148
156
|
-------
|
data/lib/puppet/functions/epp.rb
CHANGED
@@ -21,6 +21,9 @@
|
|
21
21
|
# `epp('apache/vhost/_docroot.epp', { 'docroot' => '/var/www/html',
|
22
22
|
# 'virtual_docroot' => '/var/www/example' })`
|
23
23
|
#
|
24
|
+
# This function can also accept an absolute path, which can load a template file
|
25
|
+
# from anywhere on disk.
|
26
|
+
#
|
24
27
|
# Puppet produces a syntax error if you pass more parameters than are declared in
|
25
28
|
# the template's parameter tag. When passing parameters to a template that
|
26
29
|
# contains a parameter tag, use the same names as the tag's declared parameters.
|
@@ -40,7 +40,7 @@ module Puppet
|
|
40
40
|
values = property.value_collection.instance_variable_get('@values') || {}
|
41
41
|
values.each do |_, value|
|
42
42
|
if value.regex?
|
43
|
-
regexes <<
|
43
|
+
regexes << Puppet::Pops::Types::StringConverter.convert(value.name, '%p')
|
44
44
|
next
|
45
45
|
end
|
46
46
|
|
@@ -207,7 +207,7 @@ class Puppet::Indirector::Request
|
|
207
207
|
if primary_server = Puppet.settings[:server_list][0]
|
208
208
|
bound_server = primary_server[0]
|
209
209
|
else
|
210
|
-
bound_server =
|
210
|
+
bound_server = Puppet.settings[:server]
|
211
211
|
end
|
212
212
|
end
|
213
213
|
|
@@ -217,11 +217,11 @@ class Puppet::Indirector::Request
|
|
217
217
|
if primary_server = Puppet.settings[:server_list][0]
|
218
218
|
bound_port = primary_server[1]
|
219
219
|
else
|
220
|
-
bound_port =
|
220
|
+
bound_port = Puppet.settings[:masterport]
|
221
221
|
end
|
222
222
|
end
|
223
|
-
self.server = default_server || bound_server
|
224
|
-
self.port = default_port || bound_port
|
223
|
+
self.server = default_server || bound_server
|
224
|
+
self.port = default_port || bound_port
|
225
225
|
|
226
226
|
Puppet.debug "No more servers left, falling back to #{self.server}:#{self.port}" if Puppet.settings[:use_srv_records]
|
227
227
|
|
@@ -22,6 +22,9 @@ function like this:
|
|
22
22
|
`epp('apache/vhost/_docroot.epp', { 'docroot' => '/var/www/html',
|
23
23
|
'virtual_docroot' => '/var/www/example' })`
|
24
24
|
|
25
|
+
This function can also accept an absolute path, which can load a template file
|
26
|
+
from anywhere on disk.
|
27
|
+
|
25
28
|
Puppet produces a syntax error if you pass more parameters than are declared in
|
26
29
|
the template's parameter tag. When passing parameters to a template that
|
27
30
|
contains a parameter tag, use the same names as the tag's declared parameters.
|
data/lib/puppet/pops/patterns.rb
CHANGED
@@ -48,7 +48,7 @@ module Puppet::Pops::Patterns
|
|
48
48
|
|
49
49
|
# VAR_NAME matches the name part of a variable (The $ character is not included)
|
50
50
|
# Note, that only the final segment may start with an underscore.
|
51
|
-
VAR_NAME = %r{\A(?:(::)?[a-z]\w*)*(?:(::)?
|
51
|
+
VAR_NAME = %r{\A(?:((::)?[a-z]\w*)*(?:(::)?_\w*)?)\z}
|
52
52
|
|
53
53
|
# PARAM_NAME matches the name part of a parameter (The $ character is not included)
|
54
54
|
PARAM_NAME = %r{\A[a-z_]\w*\z}
|
@@ -826,12 +826,10 @@ class StringConverter
|
|
826
826
|
f = get_format(val_type, format_map)
|
827
827
|
case f.format
|
828
828
|
when :p
|
829
|
-
|
830
|
-
rx_s = rx_s.gsub(/\//, '\/') unless Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0')
|
831
|
-
str_regexp = "/#{rx_s}/"
|
829
|
+
str_regexp = PRegexpType.regexp_to_s_with_delimiters(val)
|
832
830
|
f.orig_fmt == '%p' ? str_regexp : Kernel.format(f.orig_fmt.gsub('p', 's'), str_regexp)
|
833
831
|
when :s
|
834
|
-
str_regexp =
|
832
|
+
str_regexp = PRegexpType.regexp_to_s(val)
|
835
833
|
str_regexp = puppet_quote(str_regexp) if f.alt?
|
836
834
|
f.orig_fmt == '%s' ? str_regexp : Kernel.format(f.orig_fmt, str_regexp)
|
837
835
|
else
|
@@ -507,7 +507,7 @@ class TypeFormatter
|
|
507
507
|
def string_Numeric(t) ; @bld << t.to_s ; end
|
508
508
|
|
509
509
|
# @api private
|
510
|
-
def string_Regexp(t) ; @bld << t
|
510
|
+
def string_Regexp(t) ; @bld << PRegexpType.regexp_to_s_with_delimiters(t); end
|
511
511
|
|
512
512
|
# @api private
|
513
513
|
def string_String(t)
|
@@ -1573,10 +1573,64 @@ class PRegexpType < PScalarType
|
|
1573
1573
|
|
1574
1574
|
attr_reader :pattern
|
1575
1575
|
|
1576
|
+
# @param regexp [Regexp] the regular expression
|
1577
|
+
# @return [String] the Regexp as a slash delimited string with slashes escaped
|
1578
|
+
def self.regexp_to_s_with_delimiters(regexp)
|
1579
|
+
regexp.options == 0 ? regexp.inspect : "/#{regexp.to_s}/"
|
1580
|
+
end
|
1581
|
+
|
1582
|
+
# @param regexp [Regexp] the regular expression
|
1583
|
+
# @return [String] the Regexp as a string without escaped slash
|
1584
|
+
def self.regexp_to_s(regexp)
|
1585
|
+
# Rubies < 2.0.0 retains escaped delimiters in the source string.
|
1586
|
+
@source_retains_escaped_slash ||= Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0')
|
1587
|
+
source = regexp.source
|
1588
|
+
if @source_retains_escaped_slash && source.include?('\\')
|
1589
|
+
# Restore corrupt string in rubies <2.0.0, i.e. turn '\/' into '/' but
|
1590
|
+
# don't touch valid escapes such as '\s', '\{' etc.
|
1591
|
+
escaped = false
|
1592
|
+
bld = ''
|
1593
|
+
source.each_codepoint do |codepoint|
|
1594
|
+
if escaped
|
1595
|
+
bld << 0x5c unless codepoint == 0x2f # '/'
|
1596
|
+
bld << codepoint
|
1597
|
+
escaped = false
|
1598
|
+
elsif codepoint == 0x5c # '\'
|
1599
|
+
escaped = true
|
1600
|
+
elsif codepoint <= 0x7f
|
1601
|
+
bld << codepoint
|
1602
|
+
else
|
1603
|
+
bld << [codepoint].pack('U')
|
1604
|
+
end
|
1605
|
+
end
|
1606
|
+
source = bld
|
1607
|
+
end
|
1608
|
+
append_flags_group(source, regexp.options)
|
1609
|
+
end
|
1610
|
+
|
1611
|
+
def self.append_flags_group(rx_string, options)
|
1612
|
+
if options == 0
|
1613
|
+
rx_string
|
1614
|
+
else
|
1615
|
+
bld = '(?'
|
1616
|
+
bld << 'i' if (options & Regexp::IGNORECASE) != 0
|
1617
|
+
bld << 'm' if (options & Regexp::MULTILINE) != 0
|
1618
|
+
bld << 'x' if (options & Regexp::EXTENDED) != 0
|
1619
|
+
unless options == (Regexp::IGNORECASE | Regexp::MULTILINE | Regexp::EXTENDED)
|
1620
|
+
bld << '-'
|
1621
|
+
bld << 'i' if (options & Regexp::IGNORECASE) == 0
|
1622
|
+
bld << 'm' if (options & Regexp::MULTILINE) == 0
|
1623
|
+
bld << 'x' if (options & Regexp::EXTENDED) == 0
|
1624
|
+
end
|
1625
|
+
bld << ':' << rx_string << ')'
|
1626
|
+
bld.freeze
|
1627
|
+
end
|
1628
|
+
end
|
1629
|
+
|
1576
1630
|
def initialize(pattern)
|
1577
1631
|
if pattern.is_a?(Regexp)
|
1578
1632
|
@regexp = pattern
|
1579
|
-
@pattern =
|
1633
|
+
@pattern = PRegexpType.regexp_to_s(pattern)
|
1580
1634
|
else
|
1581
1635
|
@pattern = pattern
|
1582
1636
|
end
|
@@ -1595,7 +1649,7 @@ class PRegexpType < PScalarType
|
|
1595
1649
|
end
|
1596
1650
|
|
1597
1651
|
def instance?(o, guard=nil)
|
1598
|
-
o.is_a?(Regexp) &&
|
1652
|
+
o.is_a?(Regexp) && @pattern.nil? || regexp == o
|
1599
1653
|
end
|
1600
1654
|
|
1601
1655
|
DEFAULT = PRegexpType.new(nil)
|
@@ -38,7 +38,7 @@ Puppet::Type.type(:package).provide :aix, :parent => Puppet::Provider::Package d
|
|
38
38
|
|
39
39
|
return unless packages.detect { |name, package| package.should(:ensure) == :latest }
|
40
40
|
|
41
|
-
sources = packages.collect { |name, package| package[:source] }.uniq
|
41
|
+
sources = packages.collect { |name, package| package[:source] }.uniq.compact
|
42
42
|
|
43
43
|
updates = {}
|
44
44
|
sources.each do |source|
|
@@ -92,6 +92,7 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
|
|
92
92
|
updates = Hash.new { |h, k| h[k] = [] }
|
93
93
|
body.split.each_slice(3) do |tuple|
|
94
94
|
break if tuple[0] =~ /^(Obsoleting|Security:|Update)/
|
95
|
+
break unless tuple[1].match(/^(?:(\d+):)?(\S+)-(\S+)$/)
|
95
96
|
hash = update_to_hash(*tuple[0..1])
|
96
97
|
# Create entries for both the package name without a version and a
|
97
98
|
# version since yum considers those as mostly interchangeable.
|
@@ -53,17 +53,21 @@ module Puppet::Util::Windows::APITypes
|
|
53
53
|
alias_method :read_word, :read_uint16
|
54
54
|
alias_method :read_array_of_wchar, :read_array_of_uint16
|
55
55
|
|
56
|
-
def read_wide_string(char_length, dst_encoding = Encoding::UTF_8)
|
56
|
+
def read_wide_string(char_length, dst_encoding = Encoding::UTF_8, encode_options = {})
|
57
57
|
# char_length is number of wide chars (typically excluding NULLs), *not* bytes
|
58
58
|
str = get_bytes(0, char_length * 2).force_encoding('UTF-16LE')
|
59
|
-
str.encode(dst_encoding)
|
59
|
+
str.encode(dst_encoding, str.encoding, encode_options)
|
60
|
+
rescue Exception => e
|
61
|
+
Puppet.debug "Unable to convert value #{str.dump} to encoding #{dst_encoding} due to #{e.inspect}"
|
62
|
+
raise
|
60
63
|
end
|
61
64
|
|
62
65
|
# @param max_char_length [Integer] Maximum number of wide chars to return (typically excluding NULLs), *not* bytes
|
63
66
|
# @param null_terminator [Symbol] Number of number of null wchar characters, *not* bytes, that determine the end of the string
|
64
67
|
# null_terminator = :single_null, then the terminating sequence is two bytes of zero. This is UNIT16 = 0
|
65
68
|
# null_terminator = :double_null, then the terminating sequence is four bytes of zero. This is UNIT32 = 0
|
66
|
-
|
69
|
+
# @param encode_options [Hash] Accepts the same option hash that may be passed to String#encode in Ruby
|
70
|
+
def read_arbitrary_wide_string_up_to(max_char_length = 512, null_terminator = :single_null, encode_options = {})
|
67
71
|
if null_terminator != :single_null && null_terminator != :double_null
|
68
72
|
raise "Unable to read wide strings with #{null_terminator} terminal nulls"
|
69
73
|
end
|
@@ -73,11 +77,11 @@ module Puppet::Util::Windows::APITypes
|
|
73
77
|
|
74
78
|
# Look for a null terminating characters; if found, read up to that null (exclusive)
|
75
79
|
(0...max_char_length - terminator_width).each do |i|
|
76
|
-
return read_wide_string(i) if send(reader_method, (i * 2)) == 0
|
80
|
+
return read_wide_string(i, Encoding::UTF_8, encode_options) if send(reader_method, (i * 2)) == 0
|
77
81
|
end
|
78
82
|
|
79
83
|
# String is longer than the max; read just to the max
|
80
|
-
read_wide_string(max_char_length)
|
84
|
+
read_wide_string(max_char_length, Encoding::UTF_8, encode_options)
|
81
85
|
end
|
82
86
|
|
83
87
|
def read_win32_local_pointer(&block)
|
@@ -236,9 +236,17 @@ module Puppet::Util::Windows::Process
|
|
236
236
|
def get_environment_strings
|
237
237
|
env_ptr = GetEnvironmentStringsW()
|
238
238
|
|
239
|
-
|
239
|
+
# pass :invalid => :replace to the Ruby String#encode to use replacement characters
|
240
|
+
pairs = env_ptr.read_arbitrary_wide_string_up_to(65534, :double_null, { :invalid => :replace })
|
240
241
|
.split(?\x00)
|
241
242
|
.reject { |env_str| env_str.nil? || env_str.empty? || env_str[0] == '=' }
|
243
|
+
.reject do |env_str|
|
244
|
+
# reject any string containing the Unicode replacement character
|
245
|
+
if env_str.include?("\uFFFD")
|
246
|
+
Puppet.warning("Discarding environment variable #{env_str} which contains invalid bytes")
|
247
|
+
true
|
248
|
+
end
|
249
|
+
end
|
242
250
|
.map { |env_pair| env_pair.split('=', 2) }
|
243
251
|
Hash[ pairs ]
|
244
252
|
ensure
|
data/lib/puppet/version.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
Loaded plugins: fastestmirror
|
2
|
+
Loading mirror speeds from cached hostfile
|
3
|
+
|
4
|
+
NetworkManager.x86_64 1:1.0.0-14.git20150121.b4ea599c.el7 base
|
5
|
+
NetworkManager-glib.x86_64 1:1.0.0-14.git20150121.b4ea599c.el7 base
|
6
|
+
NetworkManager-tui.x86_64 1:1.0.0-14.git20150121.b4ea599c.el7 base
|
7
|
+
alsa-firmware.noarch 1.0.28-2.el7 base
|
8
|
+
alsa-lib.x86_64 1.0.28-2.el7 base
|
9
|
+
audit.x86_64 2.4.1-5.el7 base
|
10
|
+
audit-libs.x86_64 2.4.1-5.el7 base
|
11
|
+
authconfig.x86_64 6.2.8-9.el7 base
|
12
|
+
avahi.x86_64 0.6.31-14.el7 base
|
13
|
+
avahi-autoipd.x86_64 0.6.31-14.el7 base
|
14
|
+
avahi-libs.x86_64 0.6.31-14.el7 base
|
15
|
+
bash.x86_64 4.2.46-12.el7 base
|
16
|
+
bind-libs-lite.x86_64 32:9.9.4-18.el7_1.1 updates
|
17
|
+
bind-license.noarch 32:9.9.4-18.el7_1.1 updates
|
18
|
+
binutils.x86_64 2.23.52.0.1-30.el7_1.2 updates
|
19
|
+
biosdevname.x86_64 0.6.1-2.el7 base
|
20
|
+
btrfs-progs.x86_64 3.16.2-1.el7 base
|
21
|
+
ca-certificates.noarch 2015.2.4-70.0.el7_1 updates
|
22
|
+
centos-logos.noarch 70.0.6-2.el7.centos updates
|
23
|
+
centos-release.x86_64 7-1.1503.el7.centos.2.8 base
|
24
|
+
cpp.x86_64 4.8.3-9.el7 base
|
25
|
+
cronie.x86_64 1.4.11-13.el7 base
|
26
|
+
cronie-anacron.x86_64 1.4.11-13.el7 base
|
27
|
+
cryptsetup-libs.x86_64 1.6.6-3.el7 base
|
28
|
+
dbus.x86_64 1:1.6.12-11.el7 base
|
29
|
+
dbus-libs.x86_64 1:1.6.12-11.el7 base
|
30
|
+
device-mapper.x86_64 7:1.02.93-3.el7 base
|
31
|
+
device-mapper-event.x86_64 7:1.02.93-3.el7 base
|
32
|
+
device-mapper-event-libs.x86_64 7:1.02.93-3.el7 base
|
33
|
+
device-mapper-libs.x86_64 7:1.02.93-3.el7 base
|
34
|
+
Random plugin output
|
35
|
+
Loaded plugins: fastestmirror, product-id, fake-plugin
|
36
|
+
Random plugin failed, is the mirror available?
|
@@ -34,6 +34,51 @@ describe "Puppet::Util::Windows::Process", :if => Puppet.features.microsoft_wind
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
describe "when reading environment variables" do
|
38
|
+
after :each do
|
39
|
+
# spec\integration\test\test_helper_spec.rb calls set_environment_strings
|
40
|
+
# after :all and thus needs access to the real APIs once again
|
41
|
+
Puppet::Util::Windows::Process.unstub(:GetEnvironmentStringsW)
|
42
|
+
Puppet::Util::Windows::Process.unstub(:FreeEnvironmentStringsW)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "will ignore only keys or values with corrupt byte sequences" do
|
46
|
+
arraydest = []
|
47
|
+
Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(arraydest))
|
48
|
+
|
49
|
+
env_vars = {}
|
50
|
+
|
51
|
+
# Create a UTF-16LE version of the below null separated environment string
|
52
|
+
# "a=b\x00c=d\x00e=\xDD\xDD\x00f=g\x00\x00"
|
53
|
+
env_var_block =
|
54
|
+
"a=b\x00".encode(Encoding::UTF_16LE) +
|
55
|
+
"c=d\x00".encode(Encoding::UTF_16LE) +
|
56
|
+
'e='.encode(Encoding::UTF_16LE) + "\xDD\xDD".force_encoding(Encoding::UTF_16LE) + "\x00".encode(Encoding::UTF_16LE) +
|
57
|
+
"f=g\x00\x00".encode(Encoding::UTF_16LE)
|
58
|
+
|
59
|
+
env_var_block_bytes = env_var_block.bytes.to_a
|
60
|
+
|
61
|
+
FFI::MemoryPointer.new(:byte, env_var_block_bytes.count) do |ptr|
|
62
|
+
# uchar here is synonymous with byte
|
63
|
+
ptr.put_array_of_uchar(0, env_var_block_bytes)
|
64
|
+
|
65
|
+
# stub the block of memory that the Win32 API would typically return via pointer
|
66
|
+
Puppet::Util::Windows::Process.expects(:GetEnvironmentStringsW).returns(ptr)
|
67
|
+
# stub out the real API call to free memory, else process crashes
|
68
|
+
Puppet::Util::Windows::Process.expects(:FreeEnvironmentStringsW)
|
69
|
+
|
70
|
+
env_vars = Puppet::Util::Windows::Process.get_environment_strings
|
71
|
+
end
|
72
|
+
|
73
|
+
# based on corrupted memory, the e=\xDD\xDD should have been removed from the set
|
74
|
+
expect(env_vars).to eq({'a' => 'b', 'c' => 'd', 'f' => 'g'})
|
75
|
+
|
76
|
+
# and Puppet should emit a warning about it
|
77
|
+
expect(arraydest.last.level).to eq(:warning)
|
78
|
+
expect(arraydest.last.message).to eq("Discarding environment variable e=\uFFFD which contains invalid bytes")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
37
82
|
describe "when setting environment variables" do
|
38
83
|
it "can properly handle env var values with = in them" do
|
39
84
|
begin
|