diff options
Diffstat (limited to 'vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec')
18 files changed, 1493 insertions, 0 deletions
diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/exploit.1.9.2.yaml b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/exploit.1.9.2.yaml new file mode 100644 index 0000000..bdd70cc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/exploit.1.9.2.yaml @@ -0,0 +1,2 @@ +--- !ruby/object:ExploitableBackDoor +foo: bar diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/exploit.1.9.3.yaml b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/exploit.1.9.3.yaml new file mode 100644 index 0000000..c24e04b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/exploit.1.9.3.yaml @@ -0,0 +1,2 @@ +--- !ruby/hash:ExploitableBackDoor +foo: bar diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/issue48.txt b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/issue48.txt new file mode 100644 index 0000000..97d1f68 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/issue48.txt @@ -0,0 +1,20 @@ +--- +title: Blah +key: value +--- + +I'm going to inject a bunch of YAML-looking stuff below and it should all just get ignored. + +foo: bar + +- foo +- bar + +:foo +42 +~ + +--- +text: | + Look, I'm another YAML document! +--- diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/issue49.yml b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/issue49.yml new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/issue49.yml diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/libyaml_checker_spec.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/libyaml_checker_spec.rb new file mode 100644 index 0000000..b5b290b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/libyaml_checker_spec.rb @@ -0,0 +1,69 @@ +require "spec_helper" + +describe SafeYAML::LibyamlChecker do + describe "check_libyaml_version" do + REAL_YAML_ENGINE = SafeYAML::YAML_ENGINE + REAL_LIBYAML_VERSION = SafeYAML::LibyamlChecker::LIBYAML_VERSION + + let(:libyaml_patched) { false } + + before :each do + allow(SafeYAML::LibyamlChecker).to receive(:libyaml_patched?).and_return(libyaml_patched) + end + + after :each do + silence_warnings do + SafeYAML::YAML_ENGINE = REAL_YAML_ENGINE + SafeYAML::LibyamlChecker::LIBYAML_VERSION = REAL_LIBYAML_VERSION + end + end + + def test_libyaml_version_ok(expected_result, yaml_engine, libyaml_version=nil) + silence_warnings do + SafeYAML.const_set("YAML_ENGINE", yaml_engine) + SafeYAML::LibyamlChecker.const_set("LIBYAML_VERSION", libyaml_version) + expect(SafeYAML::LibyamlChecker.libyaml_version_ok?).to eq(expected_result) + end + end + + unless defined?(JRUBY_VERSION) + it "issues no warnings when 'Syck' is the YAML engine" do + test_libyaml_version_ok(true, "syck") + end + + it "issues a warning if Psych::LIBYAML_VERSION is not defined" do + test_libyaml_version_ok(false, "psych") + end + + it "issues a warning if Psych::LIBYAML_VERSION is < 0.1.6" do + test_libyaml_version_ok(false, "psych", "0.1.5") + end + + it "issues no warning if Psych::LIBYAML_VERSION is == 0.1.6" do + test_libyaml_version_ok(true, "psych", "0.1.6") + end + + it "issues no warning if Psych::LIBYAML_VERSION is > 0.1.6" do + test_libyaml_version_ok(true, "psych", "1.0.0") + end + + it "does a proper version comparison (not just a string comparison)" do + test_libyaml_version_ok(true, "psych", "0.1.10") + end + + context "when the system has a known patched libyaml version" do + let(:libyaml_patched) { true } + + it "issues no warning, even when Psych::LIBYAML_VERSION < 0.1.6" do + test_libyaml_version_ok(true, "psych", "0.1.4") + end + end + end + + if defined?(JRUBY_VERSION) + it "issues no warning, as JRuby doesn't use libyaml" do + test_libyaml_version_ok(true, "psych", "0.1.4") + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/psych_resolver_spec.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/psych_resolver_spec.rb new file mode 100644 index 0000000..a9e76b5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/psych_resolver_spec.rb @@ -0,0 +1,10 @@ +require "spec_helper" + +if SafeYAML::YAML_ENGINE == "psych" + require "safe_yaml/psych_resolver" + + describe SafeYAML::PsychResolver do + include ResolverSpecs + let(:resolver) { SafeYAML::PsychResolver.new } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/resolver_specs.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/resolver_specs.rb new file mode 100644 index 0000000..1b981e5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/resolver_specs.rb @@ -0,0 +1,278 @@ +module ResolverSpecs + def self.included(base) + base.module_eval do + let(:resolver) { nil } + let(:result) { @result } + + before :each do + # See the comment in the first before :each block in safe_yaml_spec.rb. + require "safe_yaml" + end + + def parse(yaml) + tree = YAML.parse(yaml.unindent) + @result = resolver.resolve_node(tree) + end + + # Isn't this how I should've been doing it all along? + def parse_and_test(yaml) + safe_result = parse(yaml) + + exception_thrown = nil + + unsafe_result = begin + YAML.unsafe_load(yaml) + rescue Exception => e + exception_thrown = e + end + + if exception_thrown + # If the underlying YAML parser (e.g. Psych) threw an exception, I'm + # honestly not sure what the right thing to do is. For now I'll just + # print a warning. Should SafeYAML fail when Psych fails? + Kernel.warn "\n" + Kernel.warn "Discrepancy between SafeYAML and #{SafeYAML::YAML_ENGINE} on input:\n" + Kernel.warn "#{yaml.unindent}\n" + Kernel.warn "SafeYAML result:" + Kernel.warn "#{safe_result.inspect}\n" + Kernel.warn "#{SafeYAML::YAML_ENGINE} result:" + Kernel.warn "#{exception_thrown.inspect}\n" + + else + expect(safe_result).to eq(unsafe_result) + end + end + + context "by default" do + it "translates maps to hashes" do + parse <<-YAML + potayto: potahto + tomayto: tomahto + YAML + + expect(result).to eq({ + "potayto" => "potahto", + "tomayto" => "tomahto" + }) + end + + it "translates sequences to arrays" do + parse <<-YAML + - foo + - bar + - baz + YAML + + expect(result).to eq(["foo", "bar", "baz"]) + end + + it "translates most values to strings" do + parse "string: value" + expect(result).to eq({ "string" => "value" }) + end + + it "does not deserialize symbols" do + parse ":symbol: value" + expect(result).to eq({ ":symbol" => "value" }) + end + + it "translates valid integral numbers to integers" do + parse "integer: 1" + expect(result).to eq({ "integer" => 1 }) + end + + it "translates valid decimal numbers to floats" do + parse "float: 3.14" + expect(result).to eq({ "float" => 3.14 }) + end + + it "translates valid dates" do + parse "date: 2013-01-24" + expect(result).to eq({ "date" => Date.parse("2013-01-24") }) + end + + it "translates valid true/false values to booleans" do + parse <<-YAML + - yes + - true + - no + - false + YAML + + expect(result).to eq([true, true, false, false]) + end + + it "translates valid nulls to nil" do + parse <<-YAML + - + - ~ + - null + YAML + + expect(result).to eq([nil] * 3) + end + + it "matches the behavior of the underlying YAML engine w/ respect to capitalization of boolean values" do + parse_and_test <<-YAML + - true + - True + - TRUE + - tRue + - TRue + - False + - FALSE + - fAlse + - FALse + YAML + + # using Syck: [true, true, true, "tRue", "TRue", false, false, "fAlse", "FALse"] + # using Psych: all booleans + end + + it "matches the behavior of the underlying YAML engine w/ respect to capitalization of nil values" do + parse_and_test <<-YAML + - Null + - NULL + - nUll + - NUll + YAML + + # using Syck: [nil, nil, "nUll", "NUll"] + # using Psych: all nils + end + + it "translates quoted empty strings to strings (not nil)" do + parse "foo: ''" + expect(result).to eq({ "foo" => "" }) + end + + it "correctly reverse-translates strings encoded via #to_yaml" do + parse "5.10".to_yaml + expect(result).to eq("5.10") + end + + it "does not specially parse any double-quoted strings" do + parse <<-YAML + - "1" + - "3.14" + - "true" + - "false" + - "2013-02-03" + - "2013-02-03 16:27:00 -0600" + YAML + + expect(result).to eq(["1", "3.14", "true", "false", "2013-02-03", "2013-02-03 16:27:00 -0600"]) + end + + it "does not specially parse any single-quoted strings" do + parse <<-YAML + - '1' + - '3.14' + - 'true' + - 'false' + - '2013-02-03' + - '2013-02-03 16:27:00 -0600' + YAML + + expect(result).to eq(["1", "3.14", "true", "false", "2013-02-03", "2013-02-03 16:27:00 -0600"]) + end + + it "deals just fine with nested maps" do + parse <<-YAML + foo: + bar: + marco: polo + YAML + + expect(result).to eq({ "foo" => { "bar" => { "marco" => "polo" } } }) + end + + it "deals just fine with nested sequences" do + parse <<-YAML + - foo + - + - bar1 + - bar2 + - + - baz1 + - baz2 + YAML + + expect(result).to eq(["foo", ["bar1", "bar2", ["baz1", "baz2"]]]) + end + + it "applies the same transformations to keys as to values" do + parse <<-YAML + foo: string + :bar: symbol + 1: integer + 3.14: float + 2013-01-24: date + YAML + + expect(result).to eq({ + "foo" => "string", + ":bar" => "symbol", + 1 => "integer", + 3.14 => "float", + Date.parse("2013-01-24") => "date", + }) + end + + it "applies the same transformations to elements in sequences as to all values" do + parse <<-YAML + - foo + - :bar + - 1 + - 3.14 + - 2013-01-24 + YAML + + expect(result).to eq(["foo", ":bar", 1, 3.14, Date.parse("2013-01-24")]) + end + end + + context "for Ruby version #{RUBY_VERSION}" do + it "translates valid time values" do + parse "time: 2013-01-29 05:58:00 -0800" + expect(result).to eq({ "time" => Time.utc(2013, 1, 29, 13, 58, 0) }) + end + + it "applies the same transformation to elements in sequences" do + parse "- 2013-01-29 05:58:00 -0800" + expect(result).to eq([Time.utc(2013, 1, 29, 13, 58, 0)]) + end + + it "applies the same transformation to keys" do + parse "2013-01-29 05:58:00 -0800: time" + expect(result).to eq({ Time.utc(2013, 1, 29, 13, 58, 0) => "time" }) + end + end + + context "with symbol deserialization enabled" do + before :each do + SafeYAML::OPTIONS[:deserialize_symbols] = true + end + + after :each do + SafeYAML.restore_defaults! + end + + it "translates values starting with ':' to symbols" do + parse "symbol: :value" + expect(result).to eq({ "symbol" => :value }) + end + + it "applies the same transformation to keys" do + parse ":bar: symbol" + expect(result).to eq({ :bar => "symbol" }) + end + + it "applies the same transformation to elements in sequences" do + parse "- :bar" + expect(result).to eq([:bar]) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/safe_yaml_spec.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/safe_yaml_spec.rb new file mode 100644 index 0000000..aa701a4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/safe_yaml_spec.rb @@ -0,0 +1,731 @@ +require "spec_helper" + +describe YAML do + def safe_load_round_trip(object, options={}) + yaml = object.to_yaml + if SafeYAML::YAML_ENGINE == "psych" + YAML.safe_load(yaml, nil, options) + else + YAML.safe_load(yaml, options) + end + end + + before :each do + # Need to require this here (as opposed to somewhere up higher in the file) + # to ensure that safe_yaml isn't loaded and therefore YAML isn't monkey- + # patched, for tests that require only safe_yaml/load. + require "safe_yaml" + require "exploitable_back_door" + + SafeYAML.restore_defaults! + end + + after :each do + SafeYAML.restore_defaults! + end + + describe "unsafe_load" do + if SafeYAML::YAML_ENGINE == "psych" && RUBY_VERSION >= "1.9.3" + it "allows exploits through objects defined in YAML w/ !ruby/hash via custom :[]= methods" do + backdoor = YAML.unsafe_load("--- !ruby/hash:ExploitableBackDoor\nfoo: bar\n") + expect(backdoor).to be_exploited_through_setter + end + + it "allows exploits through objects defined in YAML w/ !ruby/object via the :init_with method" do + backdoor = YAML.unsafe_load("--- !ruby/object:ExploitableBackDoor\nfoo: bar\n") + expect(backdoor).to be_exploited_through_init_with + end + end + + it "allows exploits through objects w/ sensitive instance variables defined in YAML w/ !ruby/object" do + backdoor = YAML.unsafe_load("--- !ruby/object:ExploitableBackDoor\nfoo: bar\n") + expect(backdoor).to be_exploited_through_ivars + end + + context "with special whitelisted tags defined" do + before :each do + SafeYAML::whitelist!(OpenStruct) + end + + it "effectively ignores the whitelist (since everything is whitelisted)" do + result = YAML.unsafe_load <<-YAML.unindent + --- !ruby/object:OpenStruct + table: + :backdoor: !ruby/object:ExploitableBackDoor + foo: bar + YAML + + expect(result).to be_a(OpenStruct) + expect(result.backdoor).to be_exploited_through_ivars + end + end + end + + describe "safe_load" do + it "does NOT allow exploits through objects defined in YAML w/ !ruby/hash" do + object = YAML.safe_load("--- !ruby/hash:ExploitableBackDoor\nfoo: bar\n") + expect(object).not_to be_a(ExploitableBackDoor) + end + + it "does NOT allow exploits through objects defined in YAML w/ !ruby/object" do + object = YAML.safe_load("--- !ruby/object:ExploitableBackDoor\nfoo: bar\n") + expect(object).not_to be_a(ExploitableBackDoor) + end + + context "for YAML engine #{SafeYAML::YAML_ENGINE}" do + if SafeYAML::YAML_ENGINE == "psych" + let(:options) { nil } + let(:arguments) { ["foo: bar", nil, options] } + + context "when no tags are whitelisted" do + it "constructs a SafeYAML::PsychHandler to resolve nodes as they're parsed, for optimal performance" do + expect(Psych::Parser).to receive(:new).with an_instance_of(SafeYAML::PsychHandler) + # This won't work now; we just want to ensure Psych::Parser#parse was in fact called. + YAML.safe_load(*arguments) rescue nil + end + end + + context "when whitelisted tags are specified" do + let(:options) { + { :whitelisted_tags => ["foo"] } + } + + it "instead uses Psych to construct a full tree before examining the nodes" do + expect(Psych).to receive(:parse) + # This won't work now; we just want to ensure Psych::Parser#parse was in fact called. + YAML.safe_load(*arguments) rescue nil + end + end + end + + if SafeYAML::YAML_ENGINE == "syck" + it "uses Syck internally to parse YAML" do + expect(YAML).to receive(:parse).with("foo: bar") + # This won't work now; we just want to ensure YAML::parse was in fact called. + YAML.safe_load("foo: bar") rescue nil + end + end + end + + it "loads a plain ol' YAML document just fine" do + result = YAML.safe_load <<-YAML.unindent + foo: + number: 1 + boolean: true + nil: ~ + string: Hello, there! + symbol: :blah + sequence: + - hi + - bye + YAML + + expect(result).to eq({ + "foo" => { + "number" => 1, + "boolean" => true, + "nil" => nil, + "string" => "Hello, there!", + "symbol" => ":blah", + "sequence" => ["hi", "bye"] + } + }) + end + + it "works for YAML documents with anchors and aliases" do + result = YAML.safe_load <<-YAML + - &id001 {} + - *id001 + - *id001 + YAML + + expect(result).to eq([{}, {}, {}]) + end + + it "works for YAML documents with binary tagged keys" do + result = YAML.safe_load <<-YAML + ? !!binary > + Zm9v + : "bar" + ? !!binary > + YmFy + : "baz" + YAML + + expect(result).to eq({"foo" => "bar", "bar" => "baz"}) + end + + it "works for YAML documents with binary tagged values" do + result = YAML.safe_load <<-YAML + "foo": !!binary > + YmFy + "bar": !!binary > + YmF6 + YAML + + expect(result).to eq({"foo" => "bar", "bar" => "baz"}) + end + + it "works for YAML documents with binary tagged array values" do + result = YAML.safe_load <<-YAML + - !binary |- + Zm9v + - !binary |- + YmFy + YAML + + expect(result).to eq(["foo", "bar"]) + end + + it "works for YAML documents with sections" do + result = YAML.safe_load <<-YAML + mysql: &mysql + adapter: mysql + pool: 30 + login: &login + username: user + password: password123 + development: &development + <<: *mysql + <<: *login + host: localhost + YAML + + expect(result).to eq({ + "mysql" => { + "adapter" => "mysql", + "pool" => 30 + }, + "login" => { + "username" => "user", + "password" => "password123" + }, + "development" => { + "adapter" => "mysql", + "pool" => 30, + "username" => "user", + "password" => "password123", + "host" => "localhost" + } + }) + end + + it "correctly prefers explicitly defined values over default values from included sections" do + # Repeating this test 100 times to increase the likelihood of running into an issue caused by + # non-deterministic hash key enumeration. + 100.times do + result = YAML.safe_load <<-YAML + defaults: &defaults + foo: foo + bar: bar + baz: baz + custom: + <<: *defaults + bar: custom_bar + baz: custom_baz + YAML + + expect(result["custom"]).to eq({ + "foo" => "foo", + "bar" => "custom_bar", + "baz" => "custom_baz" + }) + end + end + + it "works with multi-level inheritance" do + result = YAML.safe_load <<-YAML + defaults: &defaults + foo: foo + bar: bar + baz: baz + custom: &custom + <<: *defaults + bar: custom_bar + baz: custom_baz + grandcustom: &grandcustom + <<: *custom + YAML + + expect(result).to eq({ + "defaults" => { "foo" => "foo", "bar" => "bar", "baz" => "baz" }, + "custom" => { "foo" => "foo", "bar" => "custom_bar", "baz" => "custom_baz" }, + "grandcustom" => { "foo" => "foo", "bar" => "custom_bar", "baz" => "custom_baz" } + }) + end + + it "returns false when parsing an empty document" do + expect([ + YAML.safe_load(""), + YAML.safe_load(" "), + YAML.safe_load("\n") + ]).to eq([false, false, false]) + end + + it "returns nil when parsing a single value representing nil" do + expect([ + YAML.safe_load("~"), + YAML.safe_load("null") + ]).to eq([nil, nil]) + end + + context "with custom initializers defined" do + before :each do + if SafeYAML::YAML_ENGINE == "psych" + SafeYAML::OPTIONS[:custom_initializers] = { + "!set" => lambda { Set.new }, + "!hashiemash" => lambda { Hashie::Mash.new } + } + else + SafeYAML::OPTIONS[:custom_initializers] = { + "tag:yaml.org,2002:set" => lambda { Set.new }, + "tag:yaml.org,2002:hashiemash" => lambda { Hashie::Mash.new } + } + end + end + + it "will use a custom initializer to instantiate an array-like class upon deserialization" do + result = YAML.safe_load <<-YAML.unindent + --- !set + - 1 + - 2 + - 3 + YAML + + expect(result).to be_a(Set) + expect(result.to_a).to match_array([1, 2, 3]) + end + + it "will use a custom initializer to instantiate a hash-like class upon deserialization" do + result = YAML.safe_load <<-YAML.unindent + --- !hashiemash + foo: bar + YAML + + expect(result).to be_a(Hashie::Mash) + expect(result.to_hash).to eq({ "foo" => "bar" }) + end + end + + context "with special whitelisted tags defined" do + before :each do + SafeYAML::whitelist!(OpenStruct) + + # Necessary for deserializing OpenStructs properly. + SafeYAML::OPTIONS[:deserialize_symbols] = true + end + + it "will allow objects to be deserialized for whitelisted tags" do + result = YAML.safe_load("--- !ruby/object:OpenStruct\ntable:\n foo: bar\n") + expect(result).to be_a(OpenStruct) + expect(result.instance_variable_get(:@table)).to eq({ "foo" => "bar" }) + end + + it "will not deserialize objects without whitelisted tags" do + result = YAML.safe_load("--- !ruby/hash:ExploitableBackDoor\nfoo: bar\n") + expect(result).not_to be_a(ExploitableBackDoor) + expect(result).to eq({ "foo" => "bar" }) + end + + it "will not allow non-whitelisted objects to be embedded within objects with whitelisted tags" do + result = YAML.safe_load <<-YAML.unindent + --- !ruby/object:OpenStruct + table: + :backdoor: !ruby/object:ExploitableBackDoor + foo: bar + YAML + + expect(result).to be_a(OpenStruct) + expect(result.backdoor).not_to be_a(ExploitableBackDoor) + expect(result.backdoor).to eq({ "foo" => "bar" }) + end + + context "with the :raise_on_unknown_tag option enabled" do + before :each do + SafeYAML::OPTIONS[:raise_on_unknown_tag] = true + end + + after :each do + SafeYAML.restore_defaults! + end + + it "raises an exception if a non-nil, non-whitelisted tag is encountered" do + expect { + YAML.safe_load <<-YAML.unindent + --- !ruby/object:Unknown + foo: bar + YAML + }.to raise_error + end + + it "checks all tags, even those within objects with trusted tags" do + expect { + YAML.safe_load <<-YAML.unindent + --- !ruby/object:OpenStruct + table: + :backdoor: !ruby/object:Unknown + foo: bar + YAML + }.to raise_error + end + + it "does not raise an exception as long as all tags are whitelisted" do + result = YAML.safe_load <<-YAML.unindent + --- !ruby/object:OpenStruct + table: + :backdoor: + string: foo + integer: 1 + float: 3.14 + symbol: :bar + date: 2013-02-20 + array: [] + hash: {} + YAML + + expect(result).to be_a(OpenStruct) + expect(result.backdoor).to eq({ + "string" => "foo", + "integer" => 1, + "float" => 3.14, + "symbol" => :bar, + "date" => Date.parse("2013-02-20"), + "array" => [], + "hash" => {} + }) + end + + it "does not raise an exception on the non-specific '!' tag" do + result = nil + expect { result = YAML.safe_load "--- ! 'foo'" }.to_not raise_error + expect(result).to eq("foo") + end + + context "with whitelisted custom class" do + class SomeClass + attr_accessor :foo + end + let(:instance) { SomeClass.new } + + before do + SafeYAML::whitelist!(SomeClass) + instance.foo = 'with trailing whitespace: ' + end + + it "does not raise an exception on the non-specific '!' tag" do + result = nil + expect { result = YAML.safe_load(instance.to_yaml) }.to_not raise_error + expect(result.foo).to eq('with trailing whitespace: ') + end + end + end + end + + context "when options are passed direclty to #load which differ from the defaults" do + let(:default_options) { {} } + + before :each do + SafeYAML::OPTIONS.merge!(default_options) + end + + context "(for example, when symbol deserialization is enabled by default)" do + let(:default_options) { { :deserialize_symbols => true } } + + it "goes with the default option when it is not overridden" do + silence_warnings do + expect(YAML.load(":foo: bar")).to eq({ :foo => "bar" }) + end + end + + it "allows the default option to be overridden on a per-call basis" do + silence_warnings do + expect(YAML.load(":foo: bar", :deserialize_symbols => false)).to eq({ ":foo" => "bar" }) + expect(YAML.load(":foo: bar", :deserialize_symbols => true)).to eq({ :foo => "bar" }) + end + end + end + + context "(or, for example, when certain tags are whitelisted)" do + let(:default_options) { + { + :deserialize_symbols => true, + :whitelisted_tags => SafeYAML::YAML_ENGINE == "psych" ? + ["!ruby/object:OpenStruct"] : + ["tag:ruby.yaml.org,2002:object:OpenStruct"] + } + } + + it "goes with the default option when it is not overridden" do + result = safe_load_round_trip(OpenStruct.new(:foo => "bar")) + expect(result).to be_a(OpenStruct) + expect(result.foo).to eq("bar") + end + + it "allows the default option to be overridden on a per-call basis" do + result = safe_load_round_trip(OpenStruct.new(:foo => "bar"), :whitelisted_tags => []) + expect(result).to eq({ "table" => { :foo => "bar" } }) + + result = safe_load_round_trip(OpenStruct.new(:foo => "bar"), :deserialize_symbols => false, :whitelisted_tags => []) + expect(result).to eq({ "table" => { ":foo" => "bar" } }) + end + end + end + end + + describe "unsafe_load_file" do + if SafeYAML::YAML_ENGINE == "psych" && RUBY_VERSION >= "1.9.3" + it "allows exploits through objects defined in YAML w/ !ruby/hash via custom :[]= methods" do + backdoor = YAML.unsafe_load_file "spec/exploit.1.9.3.yaml" + expect(backdoor).to be_exploited_through_setter + end + end + + if SafeYAML::YAML_ENGINE == "psych" && RUBY_VERSION >= "1.9.2" + it "allows exploits through objects defined in YAML w/ !ruby/object via the :init_with method" do + backdoor = YAML.unsafe_load_file "spec/exploit.1.9.2.yaml" + expect(backdoor).to be_exploited_through_init_with + end + end + + it "allows exploits through objects w/ sensitive instance variables defined in YAML w/ !ruby/object" do + backdoor = YAML.unsafe_load_file "spec/exploit.1.9.2.yaml" + expect(backdoor).to be_exploited_through_ivars + end + end + + describe "safe_load_file" do + it "does NOT allow exploits through objects defined in YAML w/ !ruby/hash" do + object = YAML.safe_load_file "spec/exploit.1.9.3.yaml" + expect(object).not_to be_a(ExploitableBackDoor) + end + + it "does NOT allow exploits through objects defined in YAML w/ !ruby/object" do + object = YAML.safe_load_file "spec/exploit.1.9.2.yaml" + expect(object).not_to be_a(ExploitableBackDoor) + end + + it "returns false when parsing an empty file" do + expect(YAML.safe_load_file("spec/issue49.yml")).to eq(false) + end + end + + describe "load" do + let(:options) { {} } + + let (:arguments) { + if SafeYAML::MULTI_ARGUMENT_YAML_LOAD + ["foo: bar", nil, options] + else + ["foo: bar", options] + end + } + + context "as long as a :default_mode has been specified" do + it "doesn't issue a warning for safe mode, since an explicit mode has been set" do + SafeYAML::OPTIONS[:default_mode] = :safe + expect(Kernel).not_to receive(:warn) + YAML.load(*arguments) + end + + it "doesn't issue a warning for unsafe mode, since an explicit mode has been set" do + SafeYAML::OPTIONS[:default_mode] = :unsafe + expect(Kernel).not_to receive(:warn) + YAML.load(*arguments) + end + end + + context "when the :safe options is specified" do + let(:safe_mode) { true } + let(:options) { { :safe => safe_mode } } + + it "doesn't issue a warning" do + expect(Kernel).not_to receive(:warn) + YAML.load(*arguments) + end + + it "calls #safe_load if the :safe option is set to true" do + expect(YAML).to receive(:safe_load) + YAML.load(*arguments) + end + + context "when the :safe option is set to false" do + let(:safe_mode) { false } + + it "calls #unsafe_load if the :safe option is set to false" do + expect(YAML).to receive(:unsafe_load) + YAML.load(*arguments) + end + end + end + + it "issues a warning when the :safe option is omitted" do + silence_warnings do + expect(Kernel).to receive(:warn) + YAML.load(*arguments) + end + end + + it "only issues a warning once (to avoid spamming an app's output)" do + silence_warnings do + expect(Kernel).to receive(:warn).once + 2.times { YAML.load(*arguments) } + end + end + + it "defaults to safe mode if the :safe option is omitted" do + silence_warnings do + expect(YAML).to receive(:safe_load) + YAML.load(*arguments) + end + end + + context "with the default mode set to :unsafe" do + before :each do + SafeYAML::OPTIONS[:default_mode] = :unsafe + end + + it "defaults to unsafe mode if the :safe option is omitted" do + silence_warnings do + expect(YAML).to receive(:unsafe_load) + YAML.load(*arguments) + end + end + + it "calls #safe_load if the :safe option is set to true" do + expect(YAML).to receive(:safe_load) + YAML.load(*(arguments + [{ :safe => true }])) + end + end + end + + describe "load_file" do + let(:filename) { "spec/exploit.1.9.2.yaml" } # doesn't really matter + + it "issues a warning if the :safe option is omitted" do + silence_warnings do + expect(Kernel).to receive(:warn) + YAML.load_file(filename) + end + end + + it "doesn't issue a warning as long as the :safe option is specified" do + expect(Kernel).not_to receive(:warn) + YAML.load_file(filename, :safe => true) + end + + it "defaults to safe mode if the :safe option is omitted" do + silence_warnings do + expect(YAML).to receive(:safe_load_file) + YAML.load_file(filename) + end + end + + it "calls #safe_load_file if the :safe option is set to true" do + expect(YAML).to receive(:safe_load_file) + YAML.load_file(filename, :safe => true) + end + + it "calls #unsafe_load_file if the :safe option is set to false" do + expect(YAML).to receive(:unsafe_load_file) + YAML.load_file(filename, :safe => false) + end + + context "with arbitrary object deserialization enabled by default" do + before :each do + SafeYAML::OPTIONS[:default_mode] = :unsafe + end + + it "defaults to unsafe mode if the :safe option is omitted" do + silence_warnings do + expect(YAML).to receive(:unsafe_load_file) + YAML.load_file(filename) + end + end + + it "calls #safe_load if the :safe option is set to true" do + expect(YAML).to receive(:safe_load_file) + YAML.load_file(filename, :safe => true) + end + end + + it "handles files starting with --- (see issue #48)" do + expect(YAML.load_file("spec/issue48.txt", :safe => true)).to eq({ + "title" => "Blah", + "key" => "value" + }) + end + + it "handles content starting with --- (see issue #48)" do + yaml = File.read("spec/issue48.txt") + expect(YAML.load(yaml, :safe => true)).to eq({ + "title" => "Blah", + "key" => "value" + }) + end + end + + describe "whitelist!" do + context "not a class" do + it "should raise" do + expect { SafeYAML::whitelist! :foo }.to raise_error(/not a Class/) + expect(SafeYAML::OPTIONS[:whitelisted_tags]).to be_empty + end + end + + context "anonymous class" do + it "should raise" do + expect { SafeYAML::whitelist! Class.new }.to raise_error(/cannot be anonymous/) + expect(SafeYAML::OPTIONS[:whitelisted_tags]).to be_empty + end + end + + context "with a Class as its argument" do + it "should configure correctly" do + expect { SafeYAML::whitelist! OpenStruct }.to_not raise_error + expect(SafeYAML::OPTIONS[:whitelisted_tags].grep(/OpenStruct\Z/)).not_to be_empty + end + + it "successfully deserializes the specified class" do + SafeYAML.whitelist!(OpenStruct) + + # necessary for properly assigning OpenStruct attributes + SafeYAML::OPTIONS[:deserialize_symbols] = true + + result = safe_load_round_trip(OpenStruct.new(:foo => "bar")) + expect(result).to be_a(OpenStruct) + expect(result.foo).to eq("bar") + end + + it "works for ranges" do + SafeYAML.whitelist!(Range) + expect(safe_load_round_trip(1..10)).to eq(1..10) + end + + it "works for regular expressions" do + SafeYAML.whitelist!(Regexp) + expect(safe_load_round_trip(/foo/)).to eq(/foo/) + end + + it "works for multiple classes" do + SafeYAML.whitelist!(Range, Regexp) + expect(safe_load_round_trip([(1..10), /bar/])).to eq([(1..10), /bar/]) + end + + it "works for arbitrary Exception subclasses" do + class CustomException < Exception + attr_reader :custom_message + + def initialize(custom_message) + @custom_message = custom_message + end + end + + SafeYAML.whitelist!(CustomException) + + ex = safe_load_round_trip(CustomException.new("blah")) + expect(ex).to be_a(CustomException) + expect(ex.custom_message).to eq("blah") + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/spec_helper.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/spec_helper.rb new file mode 100644 index 0000000..967b2d3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/spec_helper.rb @@ -0,0 +1,42 @@ +HERE = File.dirname(__FILE__) unless defined?(HERE) +ROOT = File.join(HERE, "..") unless defined?(ROOT) + +$LOAD_PATH << File.join(ROOT, "lib") +$LOAD_PATH << File.join(HERE, "support") + +require "yaml" +if ENV["YAMLER"] && defined?(YAML::ENGINE) + YAML::ENGINE.yamler = ENV["YAMLER"] +end + +ruby_version = defined?(JRUBY_VERSION) ? "JRuby #{JRUBY_VERSION} in #{RUBY_VERSION} mode" : "Ruby #{RUBY_VERSION}" +yaml_engine = defined?(YAML::ENGINE) ? YAML::ENGINE.yamler : "syck" +libyaml_version = yaml_engine == "psych" && Psych.const_defined?("LIBYAML_VERSION", false) ? Psych::LIBYAML_VERSION : "N/A" + +env_info = [ + ruby_version, + "YAML: #{yaml_engine} (#{YAML::VERSION}) (libyaml: #{libyaml_version})", + "Monkeypatch: #{ENV['MONKEYPATCH_YAML']}" +] + +puts env_info.join(", ") + +# Caching references to these methods before loading safe_yaml in order to test +# that they aren't touched unless you actually require safe_yaml (see yaml_spec.rb). +ORIGINAL_YAML_LOAD = YAML.method(:load) +ORIGINAL_YAML_LOAD_FILE = YAML.method(:load_file) + +require "safe_yaml/load" +require "ostruct" +require "hashie" +require "heredoc_unindent" + +# Stolen from Rails: +# https://github.com/rails/rails/blob/3-2-stable/activesupport/lib/active_support/core_ext/kernel/reporting.rb#L10-25 +def silence_warnings + $VERBOSE = nil; yield +ensure + $VERBOSE = true +end + +require File.join(HERE, "resolver_specs") diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/store_spec.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/store_spec.rb new file mode 100644 index 0000000..aafcfd4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/store_spec.rb @@ -0,0 +1,57 @@ +require 'spec_helper' + +require 'safe_yaml/store' + +describe SafeYAML::Store do + + let(:file) { 'spec/store.yaml' } + let(:content) { "--- \nfoo: 42\n:bar: \"party\"\n" } + + before do + # Rewrite file on every test, as its contents are potentially modified by + # SafeYAML::Store#transaction + File.open(file, 'w') { |f| f.write(content) } + end + + def expect_safe_load(options = {}) + load_args = [content, options] + load_args.insert(1, nil) if SafeYAML::YAML_ENGINE == 'psych' + + expect(SafeYAML).to receive(:load).with(*load_args).and_call_original + expect(YAML).not_to receive(:load) + end + + let(:init_args) { [file] } + subject { described_class.new(*init_args) } + + it 'should be a YAML::Store' do + expect(subject).to be_a(YAML::Store) + end + + it 'should be a SafeYAML::Store' do + expect(subject).to be_a(SafeYAML::Store) + end + + it 'should use SafeYAML.load instead of YAML.load' do + expect_safe_load + expect(subject.transaction { subject['foo'] }).to eq(42) + end + + it 'preserves default SafeYAML behavior' do + expect(subject.transaction { subject[:bar] }).to eq(nil) + expect(subject.transaction { subject[':bar'] }).to eq('party') + end + + + describe 'with options' do + + let(:init_args) { super().insert(2, :deserialize_symbols => true) } + + it 'should accept options for SafeYAML.load' do + expect_safe_load(:deserialize_symbols => true) + expect(subject.transaction { subject[:bar] }).to eq('party') + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/support/exploitable_back_door.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/support/exploitable_back_door.rb new file mode 100644 index 0000000..48754b4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/support/exploitable_back_door.rb @@ -0,0 +1,29 @@ +class ExploitableBackDoor + def exploited? + @exploited_through_setter || @exploited_through_init_with || @exploited_through_ivars + end + + def exploited_through_setter? + @exploited_through_setter + end + + def exploited_through_init_with? + @exploited_through_init_with + end + + def exploited_through_ivars? + self.instance_variables.any? + end + + def init_with(command) + # Note: this is how bad this COULD be. + # system("#{command}") + @exploited_through_init_with = true + end + + def []=(command, arguments) + # Note: this is how bad this COULD be. + # system("#{command} #{arguments}") + @exploited_through_setter = true + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/syck_resolver_spec.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/syck_resolver_spec.rb new file mode 100644 index 0000000..bec729b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/syck_resolver_spec.rb @@ -0,0 +1,10 @@ +require "spec_helper" + +if SafeYAML::YAML_ENGINE == "syck" + require "safe_yaml/syck_resolver" + + describe SafeYAML::SyckResolver do + include ResolverSpecs + let(:resolver) { SafeYAML::SyckResolver.new } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/transform/base64_spec.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/transform/base64_spec.rb new file mode 100644 index 0000000..f4d83d0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/transform/base64_spec.rb @@ -0,0 +1,11 @@ +require "spec_helper" + +describe SafeYAML::Transform do + it "should return the same encoding when decoding Base64" do + value = "c3VyZS4=" + decoded = SafeYAML::Transform.to_proper_type(value, false, "!binary") + + expect(decoded).to eq("sure.") + expect(decoded.encoding).to eq(value.encoding) if decoded.respond_to?(:encoding) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/transform/to_date_spec.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/transform/to_date_spec.rb new file mode 100644 index 0000000..31bdb41 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/transform/to_date_spec.rb @@ -0,0 +1,60 @@ +require "spec_helper" + +describe SafeYAML::Transform::ToDate do + it "returns true when the value matches a valid Date" do + expect(subject.transform?("2013-01-01")).to eq([true, Date.parse("2013-01-01")]) + end + + it "returns false when the value does not match a valid Date" do + expect(subject.transform?("foobar")).to be_falsey + end + + it "returns false when the value does not end with a Date" do + expect(subject.transform?("2013-01-01\nNOT A DATE")).to be_falsey + end + + it "returns false when the value does not begin with a Date" do + expect(subject.transform?("NOT A DATE\n2013-01-01")).to be_falsey + end + + it "correctly parses the remaining formats of the YAML spec" do + equivalent_values = [ + "2001-12-15T02:59:43.1Z", # canonical + "2001-12-14t21:59:43.10-05:00", # iso8601 + "2001-12-14 21:59:43.10 -5", # space separated + "2001-12-15 2:59:43.10" # no time zone (Z) + ] + + equivalent_values.each do |value| + success, result = subject.transform?(value) + expect(success).to be_truthy + expect(result).to eq(Time.utc(2001, 12, 15, 2, 59, 43, 100000)) + end + end + + it "converts times to the local timezone" do + success, result = subject.transform?("2012-12-01 10:33:45 +11:00") + expect(success).to be_truthy + expect(result).to eq(Time.utc(2012, 11, 30, 23, 33, 45)) + expect(result.gmt_offset).to eq(Time.local(2012, 11, 30).gmt_offset) + end + + it "returns strings for invalid dates" do + expect(subject.transform?("0000-00-00")).to eq([true, "0000-00-00"]) + expect(subject.transform?("2013-13-01")).to eq([true, "2013-13-01"]) + expect(subject.transform?("2014-01-32")).to eq([true, "2014-01-32"]) + end + + it "returns strings for invalid date/times" do + expect(subject.transform?("0000-00-00 00:00:00 -0000")).to eq([true, "0000-00-00 00:00:00 -0000"]) + expect(subject.transform?("2013-13-01 21:59:43 -05:00")).to eq([true, "2013-13-01 21:59:43 -05:00"]) + expect(subject.transform?("2013-01-32 21:59:43 -05:00")).to eq([true, "2013-01-32 21:59:43 -05:00"]) + expect(subject.transform?("2013-01-30 25:59:43 -05:00")).to eq([true, "2013-01-30 25:59:43 -05:00"]) + expect(subject.transform?("2013-01-30 21:69:43 -05:00")).to eq([true, "2013-01-30 21:69:43 -05:00"]) + + # Interesting. It seems that in some older Ruby versions, the below actually parses successfully + # w/ DateTime.parse; but it fails w/ YAML.load. Whom to follow??? + + # subject.transform?("2013-01-30 21:59:63 -05:00").should == [true, "2013-01-30 21:59:63 -05:00"] + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/transform/to_float_spec.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/transform/to_float_spec.rb new file mode 100644 index 0000000..d4d813f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/transform/to_float_spec.rb @@ -0,0 +1,42 @@ +require "spec_helper" + +describe SafeYAML::Transform::ToFloat do + it "returns true when the value matches a valid Float" do + expect(subject.transform?("20.00")).to eq([true, 20.0]) + end + + it "returns false when the value does not match a valid Float" do + expect(subject.transform?("foobar")).to be_falsey + end + + it "returns false when the value spans multiple lines" do + expect(subject.transform?("20.00\nNOT A FLOAT")).to be_falsey + end + + it "correctly parses all formats in the YAML spec" do + # canonical + expect(subject.transform?("6.8523015e+5")).to eq([true, 685230.15]) + + # exponentioal + expect(subject.transform?("685.230_15e+03")).to eq([true, 685230.15]) + + # fixed + expect(subject.transform?("685_230.15")).to eq([true, 685230.15]) + + # sexagesimal + expect(subject.transform?("190:20:30.15")).to eq([true, 685230.15]) + + # infinity + expect(subject.transform?("-.inf")).to eq([true, (-1.0 / 0.0)]) + + # not a number + # NOTE: can't use == here since NaN != NaN + success, result = subject.transform?(".NaN") + expect(success).to be_truthy; expect(result).to be_nan + end + + # issue 29 + it "returns false for the string '.'" do + expect(subject.transform?(".")).to be_falsey + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/transform/to_integer_spec.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/transform/to_integer_spec.rb new file mode 100644 index 0000000..6c6723b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/transform/to_integer_spec.rb @@ -0,0 +1,64 @@ +require "spec_helper" + +describe SafeYAML::Transform::ToInteger do + it "returns true when the value matches a valid Integer" do + expect(subject.transform?("10")).to eq([true, 10]) + end + + it "returns false when the value does not match a valid Integer" do + expect(subject.transform?("foobar")).to be_falsey + end + + it "returns false when the value spans multiple lines" do + expect(subject.transform?("10\nNOT AN INTEGER")).to be_falsey + end + + it "allows commas in the number" do + expect(subject.transform?("1,000")).to eq([true, 1000]) + end + + it "correctly parses numbers in octal format" do + expect(subject.transform?("010")).to eq([true, 8]) + end + + it "correctly parses numbers in hexadecimal format" do + expect(subject.transform?("0x1FF")).to eq([true, 511]) + end + + it "defaults to a string for a number that resembles octal format but is not" do + expect(subject.transform?("09")).to be_falsey + end + + it "correctly parses 0 in decimal" do + expect(subject.transform?("0")).to eq([true, 0]) + end + + it "defaults to a string for a number that resembles hexadecimal format but is not" do + expect(subject.transform?("0x1G")).to be_falsey + end + + it "correctly parses all formats in the YAML spec" do + # canonical + expect(subject.transform?("685230")).to eq([true, 685230]) + + # decimal + expect(subject.transform?("+685_230")).to eq([true, 685230]) + + # octal + expect(subject.transform?("02472256")).to eq([true, 685230]) + + # hexadecimal: + expect(subject.transform?("0x_0A_74_AE")).to eq([true, 685230]) + + # binary + expect(subject.transform?("0b1010_0111_0100_1010_1110")).to eq([true, 685230]) + + # sexagesimal + expect(subject.transform?("190:20:30")).to eq([true, 685230]) + end + + # see https://github.com/dtao/safe_yaml/pull/51 + it "strips out underscores before parsing decimal values" do + expect(subject.transform?("_850_")).to eq([true, 850]) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/transform/to_symbol_spec.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/transform/to_symbol_spec.rb new file mode 100644 index 0000000..59cd242 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/transform/to_symbol_spec.rb @@ -0,0 +1,51 @@ +require "spec_helper" + +describe SafeYAML::Transform::ToSymbol do + def with_symbol_deserialization_value(value) + symbol_deserialization_flag = SafeYAML::OPTIONS[:deserialize_symbols] + SafeYAML::OPTIONS[:deserialize_symbols] = value + + yield + + ensure + SafeYAML::OPTIONS[:deserialize_symbols] = symbol_deserialization_flag + end + + def with_symbol_deserialization(&block) + with_symbol_deserialization_value(true, &block) + end + + def without_symbol_deserialization(&block) + with_symbol_deserialization_value(false, &block) + end + + it "returns true when the value matches a valid Symbol" do + with_symbol_deserialization { expect(subject.transform?(":foo")[0]).to be_truthy } + end + + it "returns true when the value matches a valid String+Symbol" do + with_symbol_deserialization { expect(subject.transform?(':"foo"')[0]).to be_truthy } + end + + it "returns true when the value matches a valid String+Symbol with 's" do + with_symbol_deserialization { expect(subject.transform?(":'foo'")[0]).to be_truthy } + end + + it "returns true when the value has special characters and is wrapped in a String" do + with_symbol_deserialization { expect(subject.transform?(':"foo.bar"')[0]).to be_truthy } + end + + it "returns false when symbol deserialization is disabled" do + without_symbol_deserialization { expect(subject.transform?(":foo")).to be_falsey } + end + + it "returns false when the value does not match a valid Symbol" do + with_symbol_deserialization { expect(subject.transform?("foo")).to be_falsey } + end + + it "returns false when the symbol does not begin the line" do + with_symbol_deserialization do + expect(subject.transform?("NOT A SYMBOL\n:foo")).to be_falsey + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/yaml_spec.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/yaml_spec.rb new file mode 100644 index 0000000..2c2bd18 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/spec/yaml_spec.rb @@ -0,0 +1,15 @@ +# See https://github.com/dtao/safe_yaml/issues/47 + +require "spec_helper" + +describe YAML do + context "when you've only required safe_yaml/load", :libraries => true do + it "YAML.load doesn't get monkey patched" do + expect(YAML.method(:load)).to eq(ORIGINAL_YAML_LOAD) + end + + it "YAML.load_file doesn't get monkey patched" do + expect(YAML.method(:load_file)).to eq(ORIGINAL_YAML_LOAD_FILE) + end + end +end |
