cloudsmith-api 0.53.3 → 0.53.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -4
- data/README.md +4 -4
- data/build.json +1 -1
- data/docs/EntitlementsCreate.md +3 -0
- data/docs/EntitlementsPartialUpdate.md +3 -0
- data/docs/EntitlementsRefresh.md +3 -0
- data/docs/RepositoryToken.md +4 -0
- data/docs/RepositoryTokenRefresh.md +4 -0
- data/docs/RepositoryTokenSyncTokens.md +4 -0
- data/lib/cloudsmith-api/models/entitlements_create.rb +31 -1
- data/lib/cloudsmith-api/models/entitlements_partial_update.rb +31 -1
- data/lib/cloudsmith-api/models/entitlements_refresh.rb +31 -1
- data/lib/cloudsmith-api/models/repository_token.rb +41 -1
- data/lib/cloudsmith-api/models/repository_token_refresh.rb +41 -1
- data/lib/cloudsmith-api/models/repository_token_sync_tokens.rb +41 -1
- data/lib/cloudsmith-api/version.rb +1 -1
- data/spec/models/entitlements_create_spec.rb +18 -0
- data/spec/models/entitlements_partial_update_spec.rb +18 -0
- data/spec/models/entitlements_refresh_spec.rb +18 -0
- data/spec/models/repository_token_refresh_spec.rb +24 -0
- data/spec/models/repository_token_spec.rb +24 -0
- data/spec/models/repository_token_sync_tokens_spec.rb +24 -0
- data/vendor/bundle/ruby/2.6.0/cache/crack-0.4.4.gem +0 -0
- data/vendor/bundle/ruby/2.6.0/extensions/x86_64-linux/2.6.0/autotest-fsevent-0.2.17/gem_make.out +1 -1
- data/vendor/bundle/ruby/2.6.0/extensions/x86_64-linux/2.6.0/ffi-1.13.1/gem_make.out +2 -2
- data/vendor/bundle/ruby/2.6.0/extensions/x86_64-linux/2.6.0/json-2.3.1/gem_make.out +1 -1
- data/vendor/bundle/ruby/2.6.0/gems/{crack-0.4.3 → crack-0.4.4}/lib/crack.rb +0 -0
- data/vendor/bundle/ruby/2.6.0/gems/{crack-0.4.3 → crack-0.4.4}/lib/crack/json.rb +5 -18
- data/vendor/bundle/ruby/2.6.0/gems/{crack-0.4.3 → crack-0.4.4}/lib/crack/util.rb +0 -0
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.4/lib/crack/version.rb +3 -0
- data/vendor/bundle/ruby/2.6.0/gems/{crack-0.4.3 → crack-0.4.4}/lib/crack/xml.rb +0 -0
- data/vendor/bundle/ruby/2.6.0/gems/ffi-1.13.1/ext/ffi_c/Makefile +3 -3
- data/vendor/bundle/ruby/2.6.0/specifications/{crack-0.4.3.gemspec → crack-0.4.4.gemspec} +3 -15
- data/vendor/bundle/ruby/2.6.0/specifications/sys-uname-1.2.1.gemspec +1 -1
- metadata +102 -177
- data/vendor/bundle/ruby/2.6.0/bin/safe_yaml +0 -27
- data/vendor/bundle/ruby/2.6.0/cache/crack-0.4.3.gem +0 -0
- data/vendor/bundle/ruby/2.6.0/cache/safe_yaml-1.0.5.gem +0 -0
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/.gitignore +0 -8
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/.travis.yml +0 -14
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/Gemfile +0 -5
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/History +0 -25
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/LICENSE +0 -20
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/README.md +0 -46
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/crack.gemspec +0 -20
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/lib/crack/version.rb +0 -3
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/script/bootstrap +0 -21
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/script/release +0 -42
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/script/test +0 -25
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/test/data/large_dataset.json +0 -139988
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/test/data/twittersearch-firefox.json +0 -1
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/test/data/twittersearch-ie.json +0 -1
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/test/hash_test.rb +0 -26
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/test/json_test.rb +0 -91
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/test/parser_test.rb +0 -27
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/test/string_test.rb +0 -31
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/test/test_helper.rb +0 -3
- data/vendor/bundle/ruby/2.6.0/gems/crack-0.4.3/test/xml_test.rb +0 -514
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/.gitignore +0 -3
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/.travis.yml +0 -48
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/CHANGES.md +0 -154
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/Gemfile +0 -11
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/LICENSE.txt +0 -22
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/README.md +0 -191
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/Rakefile +0 -26
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/bin/safe_yaml +0 -75
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/bundle_install_all_ruby_versions.sh +0 -11
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml.rb +0 -94
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/deep.rb +0 -34
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/libyaml_checker.rb +0 -36
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/load.rb +0 -181
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/parse/date.rb +0 -37
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/parse/hexadecimal.rb +0 -12
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/parse/sexagesimal.rb +0 -26
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/psych_handler.rb +0 -99
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/psych_resolver.rb +0 -52
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/resolver.rb +0 -94
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/safe_to_ruby_visitor.rb +0 -29
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/store.rb +0 -39
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/syck_hack.rb +0 -36
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/syck_node_monkeypatch.rb +0 -43
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/syck_resolver.rb +0 -38
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform.rb +0 -41
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_boolean.rb +0 -21
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_date.rb +0 -13
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_float.rb +0 -33
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_integer.rb +0 -26
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_nil.rb +0 -18
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_symbol.rb +0 -17
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/transformation_map.rb +0 -47
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/lib/safe_yaml/version.rb +0 -3
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/run_specs_all_ruby_versions.sh +0 -38
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/safe_yaml.gemspec +0 -19
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/exploit.1.9.2.yaml +0 -2
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/exploit.1.9.3.yaml +0 -2
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/issue48.txt +0 -20
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/issue49.yml +0 -0
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/libyaml_checker_spec.rb +0 -69
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/psych_resolver_spec.rb +0 -10
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/resolver_specs.rb +0 -278
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/safe_yaml_spec.rb +0 -731
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/spec_helper.rb +0 -42
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/store_spec.rb +0 -57
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/support/exploitable_back_door.rb +0 -29
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/syck_resolver_spec.rb +0 -10
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/transform/base64_spec.rb +0 -11
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/transform/to_date_spec.rb +0 -60
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/transform/to_float_spec.rb +0 -42
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/transform/to_integer_spec.rb +0 -64
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/transform/to_symbol_spec.rb +0 -51
- data/vendor/bundle/ruby/2.6.0/gems/safe_yaml-1.0.5/spec/yaml_spec.rb +0 -15
- data/vendor/bundle/ruby/2.6.0/specifications/safe_yaml-1.0.5.gemspec +0 -23
@@ -1,731 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe YAML do
|
4
|
-
def safe_load_round_trip(object, options={})
|
5
|
-
yaml = object.to_yaml
|
6
|
-
if SafeYAML::YAML_ENGINE == "psych"
|
7
|
-
YAML.safe_load(yaml, nil, options)
|
8
|
-
else
|
9
|
-
YAML.safe_load(yaml, options)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
before :each do
|
14
|
-
# Need to require this here (as opposed to somewhere up higher in the file)
|
15
|
-
# to ensure that safe_yaml isn't loaded and therefore YAML isn't monkey-
|
16
|
-
# patched, for tests that require only safe_yaml/load.
|
17
|
-
require "safe_yaml"
|
18
|
-
require "exploitable_back_door"
|
19
|
-
|
20
|
-
SafeYAML.restore_defaults!
|
21
|
-
end
|
22
|
-
|
23
|
-
after :each do
|
24
|
-
SafeYAML.restore_defaults!
|
25
|
-
end
|
26
|
-
|
27
|
-
describe "unsafe_load" do
|
28
|
-
if SafeYAML::YAML_ENGINE == "psych" && RUBY_VERSION >= "1.9.3"
|
29
|
-
it "allows exploits through objects defined in YAML w/ !ruby/hash via custom :[]= methods" do
|
30
|
-
backdoor = YAML.unsafe_load("--- !ruby/hash:ExploitableBackDoor\nfoo: bar\n")
|
31
|
-
expect(backdoor).to be_exploited_through_setter
|
32
|
-
end
|
33
|
-
|
34
|
-
it "allows exploits through objects defined in YAML w/ !ruby/object via the :init_with method" do
|
35
|
-
backdoor = YAML.unsafe_load("--- !ruby/object:ExploitableBackDoor\nfoo: bar\n")
|
36
|
-
expect(backdoor).to be_exploited_through_init_with
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
it "allows exploits through objects w/ sensitive instance variables defined in YAML w/ !ruby/object" do
|
41
|
-
backdoor = YAML.unsafe_load("--- !ruby/object:ExploitableBackDoor\nfoo: bar\n")
|
42
|
-
expect(backdoor).to be_exploited_through_ivars
|
43
|
-
end
|
44
|
-
|
45
|
-
context "with special whitelisted tags defined" do
|
46
|
-
before :each do
|
47
|
-
SafeYAML::whitelist!(OpenStruct)
|
48
|
-
end
|
49
|
-
|
50
|
-
it "effectively ignores the whitelist (since everything is whitelisted)" do
|
51
|
-
result = YAML.unsafe_load <<-YAML.unindent
|
52
|
-
--- !ruby/object:OpenStruct
|
53
|
-
table:
|
54
|
-
:backdoor: !ruby/object:ExploitableBackDoor
|
55
|
-
foo: bar
|
56
|
-
YAML
|
57
|
-
|
58
|
-
expect(result).to be_a(OpenStruct)
|
59
|
-
expect(result.backdoor).to be_exploited_through_ivars
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
describe "safe_load" do
|
65
|
-
it "does NOT allow exploits through objects defined in YAML w/ !ruby/hash" do
|
66
|
-
object = YAML.safe_load("--- !ruby/hash:ExploitableBackDoor\nfoo: bar\n")
|
67
|
-
expect(object).not_to be_a(ExploitableBackDoor)
|
68
|
-
end
|
69
|
-
|
70
|
-
it "does NOT allow exploits through objects defined in YAML w/ !ruby/object" do
|
71
|
-
object = YAML.safe_load("--- !ruby/object:ExploitableBackDoor\nfoo: bar\n")
|
72
|
-
expect(object).not_to be_a(ExploitableBackDoor)
|
73
|
-
end
|
74
|
-
|
75
|
-
context "for YAML engine #{SafeYAML::YAML_ENGINE}" do
|
76
|
-
if SafeYAML::YAML_ENGINE == "psych"
|
77
|
-
let(:options) { nil }
|
78
|
-
let(:arguments) { ["foo: bar", nil, options] }
|
79
|
-
|
80
|
-
context "when no tags are whitelisted" do
|
81
|
-
it "constructs a SafeYAML::PsychHandler to resolve nodes as they're parsed, for optimal performance" do
|
82
|
-
expect(Psych::Parser).to receive(:new).with an_instance_of(SafeYAML::PsychHandler)
|
83
|
-
# This won't work now; we just want to ensure Psych::Parser#parse was in fact called.
|
84
|
-
YAML.safe_load(*arguments) rescue nil
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
context "when whitelisted tags are specified" do
|
89
|
-
let(:options) {
|
90
|
-
{ :whitelisted_tags => ["foo"] }
|
91
|
-
}
|
92
|
-
|
93
|
-
it "instead uses Psych to construct a full tree before examining the nodes" do
|
94
|
-
expect(Psych).to receive(:parse)
|
95
|
-
# This won't work now; we just want to ensure Psych::Parser#parse was in fact called.
|
96
|
-
YAML.safe_load(*arguments) rescue nil
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
if SafeYAML::YAML_ENGINE == "syck"
|
102
|
-
it "uses Syck internally to parse YAML" do
|
103
|
-
expect(YAML).to receive(:parse).with("foo: bar")
|
104
|
-
# This won't work now; we just want to ensure YAML::parse was in fact called.
|
105
|
-
YAML.safe_load("foo: bar") rescue nil
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
it "loads a plain ol' YAML document just fine" do
|
111
|
-
result = YAML.safe_load <<-YAML.unindent
|
112
|
-
foo:
|
113
|
-
number: 1
|
114
|
-
boolean: true
|
115
|
-
nil: ~
|
116
|
-
string: Hello, there!
|
117
|
-
symbol: :blah
|
118
|
-
sequence:
|
119
|
-
- hi
|
120
|
-
- bye
|
121
|
-
YAML
|
122
|
-
|
123
|
-
expect(result).to eq({
|
124
|
-
"foo" => {
|
125
|
-
"number" => 1,
|
126
|
-
"boolean" => true,
|
127
|
-
"nil" => nil,
|
128
|
-
"string" => "Hello, there!",
|
129
|
-
"symbol" => ":blah",
|
130
|
-
"sequence" => ["hi", "bye"]
|
131
|
-
}
|
132
|
-
})
|
133
|
-
end
|
134
|
-
|
135
|
-
it "works for YAML documents with anchors and aliases" do
|
136
|
-
result = YAML.safe_load <<-YAML
|
137
|
-
- &id001 {}
|
138
|
-
- *id001
|
139
|
-
- *id001
|
140
|
-
YAML
|
141
|
-
|
142
|
-
expect(result).to eq([{}, {}, {}])
|
143
|
-
end
|
144
|
-
|
145
|
-
it "works for YAML documents with binary tagged keys" do
|
146
|
-
result = YAML.safe_load <<-YAML
|
147
|
-
? !!binary >
|
148
|
-
Zm9v
|
149
|
-
: "bar"
|
150
|
-
? !!binary >
|
151
|
-
YmFy
|
152
|
-
: "baz"
|
153
|
-
YAML
|
154
|
-
|
155
|
-
expect(result).to eq({"foo" => "bar", "bar" => "baz"})
|
156
|
-
end
|
157
|
-
|
158
|
-
it "works for YAML documents with binary tagged values" do
|
159
|
-
result = YAML.safe_load <<-YAML
|
160
|
-
"foo": !!binary >
|
161
|
-
YmFy
|
162
|
-
"bar": !!binary >
|
163
|
-
YmF6
|
164
|
-
YAML
|
165
|
-
|
166
|
-
expect(result).to eq({"foo" => "bar", "bar" => "baz"})
|
167
|
-
end
|
168
|
-
|
169
|
-
it "works for YAML documents with binary tagged array values" do
|
170
|
-
result = YAML.safe_load <<-YAML
|
171
|
-
- !binary |-
|
172
|
-
Zm9v
|
173
|
-
- !binary |-
|
174
|
-
YmFy
|
175
|
-
YAML
|
176
|
-
|
177
|
-
expect(result).to eq(["foo", "bar"])
|
178
|
-
end
|
179
|
-
|
180
|
-
it "works for YAML documents with sections" do
|
181
|
-
result = YAML.safe_load <<-YAML
|
182
|
-
mysql: &mysql
|
183
|
-
adapter: mysql
|
184
|
-
pool: 30
|
185
|
-
login: &login
|
186
|
-
username: user
|
187
|
-
password: password123
|
188
|
-
development: &development
|
189
|
-
<<: *mysql
|
190
|
-
<<: *login
|
191
|
-
host: localhost
|
192
|
-
YAML
|
193
|
-
|
194
|
-
expect(result).to eq({
|
195
|
-
"mysql" => {
|
196
|
-
"adapter" => "mysql",
|
197
|
-
"pool" => 30
|
198
|
-
},
|
199
|
-
"login" => {
|
200
|
-
"username" => "user",
|
201
|
-
"password" => "password123"
|
202
|
-
},
|
203
|
-
"development" => {
|
204
|
-
"adapter" => "mysql",
|
205
|
-
"pool" => 30,
|
206
|
-
"username" => "user",
|
207
|
-
"password" => "password123",
|
208
|
-
"host" => "localhost"
|
209
|
-
}
|
210
|
-
})
|
211
|
-
end
|
212
|
-
|
213
|
-
it "correctly prefers explicitly defined values over default values from included sections" do
|
214
|
-
# Repeating this test 100 times to increase the likelihood of running into an issue caused by
|
215
|
-
# non-deterministic hash key enumeration.
|
216
|
-
100.times do
|
217
|
-
result = YAML.safe_load <<-YAML
|
218
|
-
defaults: &defaults
|
219
|
-
foo: foo
|
220
|
-
bar: bar
|
221
|
-
baz: baz
|
222
|
-
custom:
|
223
|
-
<<: *defaults
|
224
|
-
bar: custom_bar
|
225
|
-
baz: custom_baz
|
226
|
-
YAML
|
227
|
-
|
228
|
-
expect(result["custom"]).to eq({
|
229
|
-
"foo" => "foo",
|
230
|
-
"bar" => "custom_bar",
|
231
|
-
"baz" => "custom_baz"
|
232
|
-
})
|
233
|
-
end
|
234
|
-
end
|
235
|
-
|
236
|
-
it "works with multi-level inheritance" do
|
237
|
-
result = YAML.safe_load <<-YAML
|
238
|
-
defaults: &defaults
|
239
|
-
foo: foo
|
240
|
-
bar: bar
|
241
|
-
baz: baz
|
242
|
-
custom: &custom
|
243
|
-
<<: *defaults
|
244
|
-
bar: custom_bar
|
245
|
-
baz: custom_baz
|
246
|
-
grandcustom: &grandcustom
|
247
|
-
<<: *custom
|
248
|
-
YAML
|
249
|
-
|
250
|
-
expect(result).to eq({
|
251
|
-
"defaults" => { "foo" => "foo", "bar" => "bar", "baz" => "baz" },
|
252
|
-
"custom" => { "foo" => "foo", "bar" => "custom_bar", "baz" => "custom_baz" },
|
253
|
-
"grandcustom" => { "foo" => "foo", "bar" => "custom_bar", "baz" => "custom_baz" }
|
254
|
-
})
|
255
|
-
end
|
256
|
-
|
257
|
-
it "returns false when parsing an empty document" do
|
258
|
-
expect([
|
259
|
-
YAML.safe_load(""),
|
260
|
-
YAML.safe_load(" "),
|
261
|
-
YAML.safe_load("\n")
|
262
|
-
]).to eq([false, false, false])
|
263
|
-
end
|
264
|
-
|
265
|
-
it "returns nil when parsing a single value representing nil" do
|
266
|
-
expect([
|
267
|
-
YAML.safe_load("~"),
|
268
|
-
YAML.safe_load("null")
|
269
|
-
]).to eq([nil, nil])
|
270
|
-
end
|
271
|
-
|
272
|
-
context "with custom initializers defined" do
|
273
|
-
before :each do
|
274
|
-
if SafeYAML::YAML_ENGINE == "psych"
|
275
|
-
SafeYAML::OPTIONS[:custom_initializers] = {
|
276
|
-
"!set" => lambda { Set.new },
|
277
|
-
"!hashiemash" => lambda { Hashie::Mash.new }
|
278
|
-
}
|
279
|
-
else
|
280
|
-
SafeYAML::OPTIONS[:custom_initializers] = {
|
281
|
-
"tag:yaml.org,2002:set" => lambda { Set.new },
|
282
|
-
"tag:yaml.org,2002:hashiemash" => lambda { Hashie::Mash.new }
|
283
|
-
}
|
284
|
-
end
|
285
|
-
end
|
286
|
-
|
287
|
-
it "will use a custom initializer to instantiate an array-like class upon deserialization" do
|
288
|
-
result = YAML.safe_load <<-YAML.unindent
|
289
|
-
--- !set
|
290
|
-
- 1
|
291
|
-
- 2
|
292
|
-
- 3
|
293
|
-
YAML
|
294
|
-
|
295
|
-
expect(result).to be_a(Set)
|
296
|
-
expect(result.to_a).to match_array([1, 2, 3])
|
297
|
-
end
|
298
|
-
|
299
|
-
it "will use a custom initializer to instantiate a hash-like class upon deserialization" do
|
300
|
-
result = YAML.safe_load <<-YAML.unindent
|
301
|
-
--- !hashiemash
|
302
|
-
foo: bar
|
303
|
-
YAML
|
304
|
-
|
305
|
-
expect(result).to be_a(Hashie::Mash)
|
306
|
-
expect(result.to_hash).to eq({ "foo" => "bar" })
|
307
|
-
end
|
308
|
-
end
|
309
|
-
|
310
|
-
context "with special whitelisted tags defined" do
|
311
|
-
before :each do
|
312
|
-
SafeYAML::whitelist!(OpenStruct)
|
313
|
-
|
314
|
-
# Necessary for deserializing OpenStructs properly.
|
315
|
-
SafeYAML::OPTIONS[:deserialize_symbols] = true
|
316
|
-
end
|
317
|
-
|
318
|
-
it "will allow objects to be deserialized for whitelisted tags" do
|
319
|
-
result = YAML.safe_load("--- !ruby/object:OpenStruct\ntable:\n foo: bar\n")
|
320
|
-
expect(result).to be_a(OpenStruct)
|
321
|
-
expect(result.instance_variable_get(:@table)).to eq({ "foo" => "bar" })
|
322
|
-
end
|
323
|
-
|
324
|
-
it "will not deserialize objects without whitelisted tags" do
|
325
|
-
result = YAML.safe_load("--- !ruby/hash:ExploitableBackDoor\nfoo: bar\n")
|
326
|
-
expect(result).not_to be_a(ExploitableBackDoor)
|
327
|
-
expect(result).to eq({ "foo" => "bar" })
|
328
|
-
end
|
329
|
-
|
330
|
-
it "will not allow non-whitelisted objects to be embedded within objects with whitelisted tags" do
|
331
|
-
result = YAML.safe_load <<-YAML.unindent
|
332
|
-
--- !ruby/object:OpenStruct
|
333
|
-
table:
|
334
|
-
:backdoor: !ruby/object:ExploitableBackDoor
|
335
|
-
foo: bar
|
336
|
-
YAML
|
337
|
-
|
338
|
-
expect(result).to be_a(OpenStruct)
|
339
|
-
expect(result.backdoor).not_to be_a(ExploitableBackDoor)
|
340
|
-
expect(result.backdoor).to eq({ "foo" => "bar" })
|
341
|
-
end
|
342
|
-
|
343
|
-
context "with the :raise_on_unknown_tag option enabled" do
|
344
|
-
before :each do
|
345
|
-
SafeYAML::OPTIONS[:raise_on_unknown_tag] = true
|
346
|
-
end
|
347
|
-
|
348
|
-
after :each do
|
349
|
-
SafeYAML.restore_defaults!
|
350
|
-
end
|
351
|
-
|
352
|
-
it "raises an exception if a non-nil, non-whitelisted tag is encountered" do
|
353
|
-
expect {
|
354
|
-
YAML.safe_load <<-YAML.unindent
|
355
|
-
--- !ruby/object:Unknown
|
356
|
-
foo: bar
|
357
|
-
YAML
|
358
|
-
}.to raise_error
|
359
|
-
end
|
360
|
-
|
361
|
-
it "checks all tags, even those within objects with trusted tags" do
|
362
|
-
expect {
|
363
|
-
YAML.safe_load <<-YAML.unindent
|
364
|
-
--- !ruby/object:OpenStruct
|
365
|
-
table:
|
366
|
-
:backdoor: !ruby/object:Unknown
|
367
|
-
foo: bar
|
368
|
-
YAML
|
369
|
-
}.to raise_error
|
370
|
-
end
|
371
|
-
|
372
|
-
it "does not raise an exception as long as all tags are whitelisted" do
|
373
|
-
result = YAML.safe_load <<-YAML.unindent
|
374
|
-
--- !ruby/object:OpenStruct
|
375
|
-
table:
|
376
|
-
:backdoor:
|
377
|
-
string: foo
|
378
|
-
integer: 1
|
379
|
-
float: 3.14
|
380
|
-
symbol: :bar
|
381
|
-
date: 2013-02-20
|
382
|
-
array: []
|
383
|
-
hash: {}
|
384
|
-
YAML
|
385
|
-
|
386
|
-
expect(result).to be_a(OpenStruct)
|
387
|
-
expect(result.backdoor).to eq({
|
388
|
-
"string" => "foo",
|
389
|
-
"integer" => 1,
|
390
|
-
"float" => 3.14,
|
391
|
-
"symbol" => :bar,
|
392
|
-
"date" => Date.parse("2013-02-20"),
|
393
|
-
"array" => [],
|
394
|
-
"hash" => {}
|
395
|
-
})
|
396
|
-
end
|
397
|
-
|
398
|
-
it "does not raise an exception on the non-specific '!' tag" do
|
399
|
-
result = nil
|
400
|
-
expect { result = YAML.safe_load "--- ! 'foo'" }.to_not raise_error
|
401
|
-
expect(result).to eq("foo")
|
402
|
-
end
|
403
|
-
|
404
|
-
context "with whitelisted custom class" do
|
405
|
-
class SomeClass
|
406
|
-
attr_accessor :foo
|
407
|
-
end
|
408
|
-
let(:instance) { SomeClass.new }
|
409
|
-
|
410
|
-
before do
|
411
|
-
SafeYAML::whitelist!(SomeClass)
|
412
|
-
instance.foo = 'with trailing whitespace: '
|
413
|
-
end
|
414
|
-
|
415
|
-
it "does not raise an exception on the non-specific '!' tag" do
|
416
|
-
result = nil
|
417
|
-
expect { result = YAML.safe_load(instance.to_yaml) }.to_not raise_error
|
418
|
-
expect(result.foo).to eq('with trailing whitespace: ')
|
419
|
-
end
|
420
|
-
end
|
421
|
-
end
|
422
|
-
end
|
423
|
-
|
424
|
-
context "when options are passed direclty to #load which differ from the defaults" do
|
425
|
-
let(:default_options) { {} }
|
426
|
-
|
427
|
-
before :each do
|
428
|
-
SafeYAML::OPTIONS.merge!(default_options)
|
429
|
-
end
|
430
|
-
|
431
|
-
context "(for example, when symbol deserialization is enabled by default)" do
|
432
|
-
let(:default_options) { { :deserialize_symbols => true } }
|
433
|
-
|
434
|
-
it "goes with the default option when it is not overridden" do
|
435
|
-
silence_warnings do
|
436
|
-
expect(YAML.load(":foo: bar")).to eq({ :foo => "bar" })
|
437
|
-
end
|
438
|
-
end
|
439
|
-
|
440
|
-
it "allows the default option to be overridden on a per-call basis" do
|
441
|
-
silence_warnings do
|
442
|
-
expect(YAML.load(":foo: bar", :deserialize_symbols => false)).to eq({ ":foo" => "bar" })
|
443
|
-
expect(YAML.load(":foo: bar", :deserialize_symbols => true)).to eq({ :foo => "bar" })
|
444
|
-
end
|
445
|
-
end
|
446
|
-
end
|
447
|
-
|
448
|
-
context "(or, for example, when certain tags are whitelisted)" do
|
449
|
-
let(:default_options) {
|
450
|
-
{
|
451
|
-
:deserialize_symbols => true,
|
452
|
-
:whitelisted_tags => SafeYAML::YAML_ENGINE == "psych" ?
|
453
|
-
["!ruby/object:OpenStruct"] :
|
454
|
-
["tag:ruby.yaml.org,2002:object:OpenStruct"]
|
455
|
-
}
|
456
|
-
}
|
457
|
-
|
458
|
-
it "goes with the default option when it is not overridden" do
|
459
|
-
result = safe_load_round_trip(OpenStruct.new(:foo => "bar"))
|
460
|
-
expect(result).to be_a(OpenStruct)
|
461
|
-
expect(result.foo).to eq("bar")
|
462
|
-
end
|
463
|
-
|
464
|
-
it "allows the default option to be overridden on a per-call basis" do
|
465
|
-
result = safe_load_round_trip(OpenStruct.new(:foo => "bar"), :whitelisted_tags => [])
|
466
|
-
expect(result).to eq({ "table" => { :foo => "bar" } })
|
467
|
-
|
468
|
-
result = safe_load_round_trip(OpenStruct.new(:foo => "bar"), :deserialize_symbols => false, :whitelisted_tags => [])
|
469
|
-
expect(result).to eq({ "table" => { ":foo" => "bar" } })
|
470
|
-
end
|
471
|
-
end
|
472
|
-
end
|
473
|
-
end
|
474
|
-
|
475
|
-
describe "unsafe_load_file" do
|
476
|
-
if SafeYAML::YAML_ENGINE == "psych" && RUBY_VERSION >= "1.9.3"
|
477
|
-
it "allows exploits through objects defined in YAML w/ !ruby/hash via custom :[]= methods" do
|
478
|
-
backdoor = YAML.unsafe_load_file "spec/exploit.1.9.3.yaml"
|
479
|
-
expect(backdoor).to be_exploited_through_setter
|
480
|
-
end
|
481
|
-
end
|
482
|
-
|
483
|
-
if SafeYAML::YAML_ENGINE == "psych" && RUBY_VERSION >= "1.9.2"
|
484
|
-
it "allows exploits through objects defined in YAML w/ !ruby/object via the :init_with method" do
|
485
|
-
backdoor = YAML.unsafe_load_file "spec/exploit.1.9.2.yaml"
|
486
|
-
expect(backdoor).to be_exploited_through_init_with
|
487
|
-
end
|
488
|
-
end
|
489
|
-
|
490
|
-
it "allows exploits through objects w/ sensitive instance variables defined in YAML w/ !ruby/object" do
|
491
|
-
backdoor = YAML.unsafe_load_file "spec/exploit.1.9.2.yaml"
|
492
|
-
expect(backdoor).to be_exploited_through_ivars
|
493
|
-
end
|
494
|
-
end
|
495
|
-
|
496
|
-
describe "safe_load_file" do
|
497
|
-
it "does NOT allow exploits through objects defined in YAML w/ !ruby/hash" do
|
498
|
-
object = YAML.safe_load_file "spec/exploit.1.9.3.yaml"
|
499
|
-
expect(object).not_to be_a(ExploitableBackDoor)
|
500
|
-
end
|
501
|
-
|
502
|
-
it "does NOT allow exploits through objects defined in YAML w/ !ruby/object" do
|
503
|
-
object = YAML.safe_load_file "spec/exploit.1.9.2.yaml"
|
504
|
-
expect(object).not_to be_a(ExploitableBackDoor)
|
505
|
-
end
|
506
|
-
|
507
|
-
it "returns false when parsing an empty file" do
|
508
|
-
expect(YAML.safe_load_file("spec/issue49.yml")).to eq(false)
|
509
|
-
end
|
510
|
-
end
|
511
|
-
|
512
|
-
describe "load" do
|
513
|
-
let(:options) { {} }
|
514
|
-
|
515
|
-
let (:arguments) {
|
516
|
-
if SafeYAML::MULTI_ARGUMENT_YAML_LOAD
|
517
|
-
["foo: bar", nil, options]
|
518
|
-
else
|
519
|
-
["foo: bar", options]
|
520
|
-
end
|
521
|
-
}
|
522
|
-
|
523
|
-
context "as long as a :default_mode has been specified" do
|
524
|
-
it "doesn't issue a warning for safe mode, since an explicit mode has been set" do
|
525
|
-
SafeYAML::OPTIONS[:default_mode] = :safe
|
526
|
-
expect(Kernel).not_to receive(:warn)
|
527
|
-
YAML.load(*arguments)
|
528
|
-
end
|
529
|
-
|
530
|
-
it "doesn't issue a warning for unsafe mode, since an explicit mode has been set" do
|
531
|
-
SafeYAML::OPTIONS[:default_mode] = :unsafe
|
532
|
-
expect(Kernel).not_to receive(:warn)
|
533
|
-
YAML.load(*arguments)
|
534
|
-
end
|
535
|
-
end
|
536
|
-
|
537
|
-
context "when the :safe options is specified" do
|
538
|
-
let(:safe_mode) { true }
|
539
|
-
let(:options) { { :safe => safe_mode } }
|
540
|
-
|
541
|
-
it "doesn't issue a warning" do
|
542
|
-
expect(Kernel).not_to receive(:warn)
|
543
|
-
YAML.load(*arguments)
|
544
|
-
end
|
545
|
-
|
546
|
-
it "calls #safe_load if the :safe option is set to true" do
|
547
|
-
expect(YAML).to receive(:safe_load)
|
548
|
-
YAML.load(*arguments)
|
549
|
-
end
|
550
|
-
|
551
|
-
context "when the :safe option is set to false" do
|
552
|
-
let(:safe_mode) { false }
|
553
|
-
|
554
|
-
it "calls #unsafe_load if the :safe option is set to false" do
|
555
|
-
expect(YAML).to receive(:unsafe_load)
|
556
|
-
YAML.load(*arguments)
|
557
|
-
end
|
558
|
-
end
|
559
|
-
end
|
560
|
-
|
561
|
-
it "issues a warning when the :safe option is omitted" do
|
562
|
-
silence_warnings do
|
563
|
-
expect(Kernel).to receive(:warn)
|
564
|
-
YAML.load(*arguments)
|
565
|
-
end
|
566
|
-
end
|
567
|
-
|
568
|
-
it "only issues a warning once (to avoid spamming an app's output)" do
|
569
|
-
silence_warnings do
|
570
|
-
expect(Kernel).to receive(:warn).once
|
571
|
-
2.times { YAML.load(*arguments) }
|
572
|
-
end
|
573
|
-
end
|
574
|
-
|
575
|
-
it "defaults to safe mode if the :safe option is omitted" do
|
576
|
-
silence_warnings do
|
577
|
-
expect(YAML).to receive(:safe_load)
|
578
|
-
YAML.load(*arguments)
|
579
|
-
end
|
580
|
-
end
|
581
|
-
|
582
|
-
context "with the default mode set to :unsafe" do
|
583
|
-
before :each do
|
584
|
-
SafeYAML::OPTIONS[:default_mode] = :unsafe
|
585
|
-
end
|
586
|
-
|
587
|
-
it "defaults to unsafe mode if the :safe option is omitted" do
|
588
|
-
silence_warnings do
|
589
|
-
expect(YAML).to receive(:unsafe_load)
|
590
|
-
YAML.load(*arguments)
|
591
|
-
end
|
592
|
-
end
|
593
|
-
|
594
|
-
it "calls #safe_load if the :safe option is set to true" do
|
595
|
-
expect(YAML).to receive(:safe_load)
|
596
|
-
YAML.load(*(arguments + [{ :safe => true }]))
|
597
|
-
end
|
598
|
-
end
|
599
|
-
end
|
600
|
-
|
601
|
-
describe "load_file" do
|
602
|
-
let(:filename) { "spec/exploit.1.9.2.yaml" } # doesn't really matter
|
603
|
-
|
604
|
-
it "issues a warning if the :safe option is omitted" do
|
605
|
-
silence_warnings do
|
606
|
-
expect(Kernel).to receive(:warn)
|
607
|
-
YAML.load_file(filename)
|
608
|
-
end
|
609
|
-
end
|
610
|
-
|
611
|
-
it "doesn't issue a warning as long as the :safe option is specified" do
|
612
|
-
expect(Kernel).not_to receive(:warn)
|
613
|
-
YAML.load_file(filename, :safe => true)
|
614
|
-
end
|
615
|
-
|
616
|
-
it "defaults to safe mode if the :safe option is omitted" do
|
617
|
-
silence_warnings do
|
618
|
-
expect(YAML).to receive(:safe_load_file)
|
619
|
-
YAML.load_file(filename)
|
620
|
-
end
|
621
|
-
end
|
622
|
-
|
623
|
-
it "calls #safe_load_file if the :safe option is set to true" do
|
624
|
-
expect(YAML).to receive(:safe_load_file)
|
625
|
-
YAML.load_file(filename, :safe => true)
|
626
|
-
end
|
627
|
-
|
628
|
-
it "calls #unsafe_load_file if the :safe option is set to false" do
|
629
|
-
expect(YAML).to receive(:unsafe_load_file)
|
630
|
-
YAML.load_file(filename, :safe => false)
|
631
|
-
end
|
632
|
-
|
633
|
-
context "with arbitrary object deserialization enabled by default" do
|
634
|
-
before :each do
|
635
|
-
SafeYAML::OPTIONS[:default_mode] = :unsafe
|
636
|
-
end
|
637
|
-
|
638
|
-
it "defaults to unsafe mode if the :safe option is omitted" do
|
639
|
-
silence_warnings do
|
640
|
-
expect(YAML).to receive(:unsafe_load_file)
|
641
|
-
YAML.load_file(filename)
|
642
|
-
end
|
643
|
-
end
|
644
|
-
|
645
|
-
it "calls #safe_load if the :safe option is set to true" do
|
646
|
-
expect(YAML).to receive(:safe_load_file)
|
647
|
-
YAML.load_file(filename, :safe => true)
|
648
|
-
end
|
649
|
-
end
|
650
|
-
|
651
|
-
it "handles files starting with --- (see issue #48)" do
|
652
|
-
expect(YAML.load_file("spec/issue48.txt", :safe => true)).to eq({
|
653
|
-
"title" => "Blah",
|
654
|
-
"key" => "value"
|
655
|
-
})
|
656
|
-
end
|
657
|
-
|
658
|
-
it "handles content starting with --- (see issue #48)" do
|
659
|
-
yaml = File.read("spec/issue48.txt")
|
660
|
-
expect(YAML.load(yaml, :safe => true)).to eq({
|
661
|
-
"title" => "Blah",
|
662
|
-
"key" => "value"
|
663
|
-
})
|
664
|
-
end
|
665
|
-
end
|
666
|
-
|
667
|
-
describe "whitelist!" do
|
668
|
-
context "not a class" do
|
669
|
-
it "should raise" do
|
670
|
-
expect { SafeYAML::whitelist! :foo }.to raise_error(/not a Class/)
|
671
|
-
expect(SafeYAML::OPTIONS[:whitelisted_tags]).to be_empty
|
672
|
-
end
|
673
|
-
end
|
674
|
-
|
675
|
-
context "anonymous class" do
|
676
|
-
it "should raise" do
|
677
|
-
expect { SafeYAML::whitelist! Class.new }.to raise_error(/cannot be anonymous/)
|
678
|
-
expect(SafeYAML::OPTIONS[:whitelisted_tags]).to be_empty
|
679
|
-
end
|
680
|
-
end
|
681
|
-
|
682
|
-
context "with a Class as its argument" do
|
683
|
-
it "should configure correctly" do
|
684
|
-
expect { SafeYAML::whitelist! OpenStruct }.to_not raise_error
|
685
|
-
expect(SafeYAML::OPTIONS[:whitelisted_tags].grep(/OpenStruct\Z/)).not_to be_empty
|
686
|
-
end
|
687
|
-
|
688
|
-
it "successfully deserializes the specified class" do
|
689
|
-
SafeYAML.whitelist!(OpenStruct)
|
690
|
-
|
691
|
-
# necessary for properly assigning OpenStruct attributes
|
692
|
-
SafeYAML::OPTIONS[:deserialize_symbols] = true
|
693
|
-
|
694
|
-
result = safe_load_round_trip(OpenStruct.new(:foo => "bar"))
|
695
|
-
expect(result).to be_a(OpenStruct)
|
696
|
-
expect(result.foo).to eq("bar")
|
697
|
-
end
|
698
|
-
|
699
|
-
it "works for ranges" do
|
700
|
-
SafeYAML.whitelist!(Range)
|
701
|
-
expect(safe_load_round_trip(1..10)).to eq(1..10)
|
702
|
-
end
|
703
|
-
|
704
|
-
it "works for regular expressions" do
|
705
|
-
SafeYAML.whitelist!(Regexp)
|
706
|
-
expect(safe_load_round_trip(/foo/)).to eq(/foo/)
|
707
|
-
end
|
708
|
-
|
709
|
-
it "works for multiple classes" do
|
710
|
-
SafeYAML.whitelist!(Range, Regexp)
|
711
|
-
expect(safe_load_round_trip([(1..10), /bar/])).to eq([(1..10), /bar/])
|
712
|
-
end
|
713
|
-
|
714
|
-
it "works for arbitrary Exception subclasses" do
|
715
|
-
class CustomException < Exception
|
716
|
-
attr_reader :custom_message
|
717
|
-
|
718
|
-
def initialize(custom_message)
|
719
|
-
@custom_message = custom_message
|
720
|
-
end
|
721
|
-
end
|
722
|
-
|
723
|
-
SafeYAML.whitelist!(CustomException)
|
724
|
-
|
725
|
-
ex = safe_load_round_trip(CustomException.new("blah"))
|
726
|
-
expect(ex).to be_a(CustomException)
|
727
|
-
expect(ex.custom_message).to eq("blah")
|
728
|
-
end
|
729
|
-
end
|
730
|
-
end
|
731
|
-
end
|