diff options
Diffstat (limited to 'vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib')
24 files changed, 1069 insertions, 0 deletions
diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml.rb new file mode 100644 index 0000000..db1957d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml.rb @@ -0,0 +1,94 @@ +require "safe_yaml/load" + +module YAML + def self.load_with_options(yaml, *original_arguments) + filename, options = filename_and_options_from_arguments(original_arguments) + safe_mode = safe_mode_from_options("load", options) + arguments = [yaml] + + if safe_mode == :safe + arguments << filename if SafeYAML::YAML_ENGINE == "psych" + arguments << options_for_safe_load(options) + safe_load(*arguments) + else + arguments << filename if SafeYAML::MULTI_ARGUMENT_YAML_LOAD + unsafe_load(*arguments) + end + end + + def self.load_file_with_options(file, options={}) + safe_mode = safe_mode_from_options("load_file", options) + if safe_mode == :safe + safe_load_file(file, options_for_safe_load(options)) + else + unsafe_load_file(file) + end + end + + def self.safe_load(*args) + SafeYAML.load(*args) + end + + def self.safe_load_file(*args) + SafeYAML.load_file(*args) + end + + if SafeYAML::MULTI_ARGUMENT_YAML_LOAD + def self.unsafe_load_file(filename) + # https://github.com/tenderlove/psych/blob/v1.3.2/lib/psych.rb#L296-298 + File.open(filename, 'r:bom|utf-8') { |f| self.unsafe_load(f, filename) } + end + + else + def self.unsafe_load_file(filename) + # https://github.com/tenderlove/psych/blob/v1.2.2/lib/psych.rb#L231-233 + self.unsafe_load File.open(filename) + end + end + + class << self + alias_method :unsafe_load, :load + alias_method :load, :load_with_options + alias_method :load_file, :load_file_with_options + + private + def filename_and_options_from_arguments(arguments) + if arguments.count == 1 + if arguments.first.is_a?(String) + return arguments.first, {} + else + return nil, arguments.first || {} + end + + else + return arguments.first, arguments.last || {} + end + end + + def safe_mode_from_options(method, options={}) + if options[:safe].nil? + safe_mode = SafeYAML::OPTIONS[:default_mode] || :safe + + if SafeYAML::OPTIONS[:default_mode].nil? && !SafeYAML::OPTIONS[:suppress_warnings] + + Kernel.warn <<-EOWARNING.gsub(/^\s+/, '') + Called '#{method}' without the :safe option -- defaulting to #{safe_mode} mode. + You can avoid this warning in the future by setting the SafeYAML::OPTIONS[:default_mode] option (to :safe or :unsafe). + EOWARNING + + SafeYAML::OPTIONS[:suppress_warnings] = true + end + + return safe_mode + end + + options[:safe] ? :safe : :unsafe + end + + def options_for_safe_load(base_options) + options = base_options.dup + options.delete(:safe) + options + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/deep.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/deep.rb new file mode 100644 index 0000000..6a5e037 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/deep.rb @@ -0,0 +1,34 @@ +module SafeYAML + class Deep + def self.freeze(object) + object.each do |*entry| + value = entry.last + case value + when String, Regexp + value.freeze + when Enumerable + Deep.freeze(value) + end + end + + return object.freeze + end + + def self.copy(object) + duplicate = object.dup rescue object + + case object + when Array + (0...duplicate.count).each do |i| + duplicate[i] = Deep.copy(duplicate[i]) + end + when Hash + duplicate.keys.each do |key| + duplicate[key] = Deep.copy(duplicate[key]) + end + end + + duplicate + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/libyaml_checker.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/libyaml_checker.rb new file mode 100644 index 0000000..1ae2423 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/libyaml_checker.rb @@ -0,0 +1,36 @@ +require "set" + +module SafeYAML + class LibyamlChecker + LIBYAML_VERSION = Psych::LIBYAML_VERSION rescue nil + + # Do proper version comparison (e.g. so 0.1.10 is >= 0.1.6) + SAFE_LIBYAML_VERSION = Gem::Version.new("0.1.6") + + KNOWN_PATCHED_LIBYAML_VERSIONS = Set.new([ + # http://people.canonical.com/~ubuntu-security/cve/2014/CVE-2014-2525.html + "0.1.4-2ubuntu0.12.04.3", + "0.1.4-2ubuntu0.12.10.3", + "0.1.4-2ubuntu0.13.10.3", + "0.1.4-3ubuntu3", + + # https://security-tracker.debian.org/tracker/CVE-2014-2525 + "0.1.3-1+deb6u4", + "0.1.4-2+deb7u4", + "0.1.4-3.2" + ]).freeze + + def self.libyaml_version_ok? + return true if YAML_ENGINE != "psych" || defined?(JRUBY_VERSION) + return true if Gem::Version.new(LIBYAML_VERSION || "0") >= SAFE_LIBYAML_VERSION + return libyaml_patched? + end + + def self.libyaml_patched? + return false if (`which dpkg` rescue '').empty? + libyaml_version = `dpkg -s libyaml-0-2`.match(/^Version: (.*)$/) + return false if libyaml_version.nil? + KNOWN_PATCHED_LIBYAML_VERSIONS.include?(libyaml_version[1]) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/load.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/load.rb new file mode 100644 index 0000000..5ea0f60 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/load.rb @@ -0,0 +1,181 @@ +require "set" +require "yaml" + +# This needs to be defined up front in case any internal classes need to base +# their behavior off of this. +module SafeYAML + YAML_ENGINE = defined?(YAML::ENGINE) ? YAML::ENGINE.yamler : (defined?(Psych) && YAML == Psych ? "psych" : "syck") +end + +require "safe_yaml/libyaml_checker" +require "safe_yaml/deep" +require "safe_yaml/parse/hexadecimal" +require "safe_yaml/parse/sexagesimal" +require "safe_yaml/parse/date" +require "safe_yaml/transform/transformation_map" +require "safe_yaml/transform/to_boolean" +require "safe_yaml/transform/to_date" +require "safe_yaml/transform/to_float" +require "safe_yaml/transform/to_integer" +require "safe_yaml/transform/to_nil" +require "safe_yaml/transform/to_symbol" +require "safe_yaml/transform" +require "safe_yaml/resolver" +require "safe_yaml/syck_hack" if SafeYAML::YAML_ENGINE == "syck" && defined?(JRUBY_VERSION) + +module SafeYAML + MULTI_ARGUMENT_YAML_LOAD = YAML.method(:load).arity != 1 + + DEFAULT_OPTIONS = Deep.freeze({ + :default_mode => nil, + :suppress_warnings => false, + :deserialize_symbols => false, + :whitelisted_tags => [], + :custom_initializers => {}, + :raise_on_unknown_tag => false + }) + + OPTIONS = Deep.copy(DEFAULT_OPTIONS) + + PREDEFINED_TAGS = {} + + if YAML_ENGINE == "syck" + YAML.tagged_classes.each do |tag, klass| + PREDEFINED_TAGS[klass] = tag + end + + else + # Special tags appear to be hard-coded in Psych: + # https://github.com/tenderlove/psych/blob/v1.3.4/lib/psych/visitors/to_ruby.rb + # Fortunately, there aren't many that SafeYAML doesn't already support. + PREDEFINED_TAGS.merge!({ + Exception => "!ruby/exception", + Range => "!ruby/range", + Regexp => "!ruby/regexp", + }) + end + + Deep.freeze(PREDEFINED_TAGS) + + module_function + + def restore_defaults! + OPTIONS.clear.merge!(Deep.copy(DEFAULT_OPTIONS)) + end + + def tag_safety_check!(tag, options) + return if tag.nil? || tag == "!" + if options[:raise_on_unknown_tag] && !options[:whitelisted_tags].include?(tag) && !tag_is_explicitly_trusted?(tag) + raise "Unknown YAML tag '#{tag}'" + end + end + + def whitelist!(*classes) + classes.each do |klass| + whitelist_class!(klass) + end + end + + def whitelist_class!(klass) + raise "#{klass} not a Class" unless klass.is_a?(::Class) + + klass_name = klass.name + raise "#{klass} cannot be anonymous" if klass_name.nil? || klass_name.empty? + + # Whitelist any built-in YAML tags supplied by Syck or Psych. + predefined_tag = PREDEFINED_TAGS[klass] + if predefined_tag + OPTIONS[:whitelisted_tags] << predefined_tag + return + end + + # Exception is exceptional (har har). + tag_class = klass < Exception ? "exception" : "object" + + tag_prefix = case YAML_ENGINE + when "psych" then "!ruby/#{tag_class}" + when "syck" then "tag:ruby.yaml.org,2002:#{tag_class}" + else raise "unknown YAML_ENGINE #{YAML_ENGINE}" + end + OPTIONS[:whitelisted_tags] << "#{tag_prefix}:#{klass_name}" + end + + if YAML_ENGINE == "psych" + def tag_is_explicitly_trusted?(tag) + false + end + + else + TRUSTED_TAGS = Set.new([ + "tag:yaml.org,2002:binary", + "tag:yaml.org,2002:bool#no", + "tag:yaml.org,2002:bool#yes", + "tag:yaml.org,2002:float", + "tag:yaml.org,2002:float#fix", + "tag:yaml.org,2002:int", + "tag:yaml.org,2002:map", + "tag:yaml.org,2002:null", + "tag:yaml.org,2002:seq", + "tag:yaml.org,2002:str", + "tag:yaml.org,2002:timestamp", + "tag:yaml.org,2002:timestamp#ymd" + ]).freeze + + def tag_is_explicitly_trusted?(tag) + TRUSTED_TAGS.include?(tag) + end + end + + if SafeYAML::YAML_ENGINE == "psych" + require "safe_yaml/psych_handler" + require "safe_yaml/psych_resolver" + require "safe_yaml/safe_to_ruby_visitor" + + def self.load(yaml, filename=nil, options={}) + # If the user hasn't whitelisted any tags, we can go with this implementation which is + # significantly faster. + if (options && options[:whitelisted_tags] || SafeYAML::OPTIONS[:whitelisted_tags]).empty? + safe_handler = SafeYAML::PsychHandler.new(options) do |result| + return result + end + arguments_for_parse = [yaml] + arguments_for_parse << filename if SafeYAML::MULTI_ARGUMENT_YAML_LOAD + Psych::Parser.new(safe_handler).parse(*arguments_for_parse) + return safe_handler.result + + else + safe_resolver = SafeYAML::PsychResolver.new(options) + tree = SafeYAML::MULTI_ARGUMENT_YAML_LOAD ? + Psych.parse(yaml, filename) : + Psych.parse(yaml) + return safe_resolver.resolve_node(tree) + end + end + + def self.load_file(filename, options={}) + if SafeYAML::MULTI_ARGUMENT_YAML_LOAD + File.open(filename, 'r:bom|utf-8') { |f| self.load(f, filename, options) } + + else + # Ruby pukes on 1.9.2 if we try to open an empty file w/ 'r:bom|utf-8'; + # so we'll not specify those flags here. This mirrors the behavior for + # unsafe_load_file so it's probably preferable anyway. + self.load File.open(filename), nil, options + end + end + + else + require "safe_yaml/syck_resolver" + require "safe_yaml/syck_node_monkeypatch" + + def self.load(yaml, options={}) + resolver = SafeYAML::SyckResolver.new(SafeYAML::OPTIONS.merge(options || {})) + tree = YAML.parse(yaml) + return resolver.resolve_node(tree) + end + + def self.load_file(filename, options={}) + File.open(filename) { |f| self.load(f, options) } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/parse/date.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/parse/date.rb new file mode 100644 index 0000000..3a30a8b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/parse/date.rb @@ -0,0 +1,37 @@ +require 'time' + +module SafeYAML + class Parse + class Date + # This one's easy enough :) + DATE_MATCHER = /\A(\d{4})-(\d{2})-(\d{2})\Z/.freeze + + # This unbelievable little gem is taken basically straight from the YAML spec, but made + # slightly more readable (to my poor eyes at least) to me: + # http://yaml.org/type/timestamp.html + TIME_MATCHER = /\A\d{4}-\d{1,2}-\d{1,2}(?:[Tt]|\s+)\d{1,2}:\d{2}:\d{2}(?:\.\d*)?\s*(?:Z|[-+]\d{1,2}(?::?\d{2})?)?\Z/.freeze + + SECONDS_PER_DAY = 60 * 60 * 24 + MICROSECONDS_PER_SECOND = 1000000 + + # So this is weird. In Ruby 1.8.7, the DateTime#sec_fraction method returned fractional + # seconds in units of DAYS for some reason. In 1.9.2, they changed the units -- much more + # reasonably -- to seconds. + SEC_FRACTION_MULTIPLIER = RUBY_VERSION == "1.8.7" ? (SECONDS_PER_DAY * MICROSECONDS_PER_SECOND) : MICROSECONDS_PER_SECOND + + # The DateTime class has a #to_time method in Ruby 1.9+; + # Before that we'll just need to convert DateTime to Time ourselves. + TO_TIME_AVAILABLE = DateTime.instance_methods.include?(:to_time) + + def self.value(value) + d = DateTime.parse(value) + + return d.to_time if TO_TIME_AVAILABLE + + usec = d.sec_fraction * SEC_FRACTION_MULTIPLIER + time = Time.utc(d.year, d.month, d.day, d.hour, d.min, d.sec, usec) - (d.offset * SECONDS_PER_DAY) + time.getlocal + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/parse/hexadecimal.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/parse/hexadecimal.rb new file mode 100644 index 0000000..8da3624 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/parse/hexadecimal.rb @@ -0,0 +1,12 @@ +module SafeYAML + class Parse + class Hexadecimal + MATCHER = /\A[-+]?0x[0-9a-fA-F_]+\Z/.freeze + + def self.value(value) + # This is safe to do since we already validated the value. + return Integer(value.gsub(/_/, "")) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/parse/sexagesimal.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/parse/sexagesimal.rb new file mode 100644 index 0000000..3fff5bb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/parse/sexagesimal.rb @@ -0,0 +1,26 @@ +module SafeYAML + class Parse + class Sexagesimal + INTEGER_MATCHER = /\A[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\Z/.freeze + FLOAT_MATCHER = /\A[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\.[0-9_]*\Z/.freeze + + def self.value(value) + before_decimal, after_decimal = value.split(".") + + whole_part = 0 + multiplier = 1 + + before_decimal = before_decimal.split(":") + until before_decimal.empty? + whole_part += (Float(before_decimal.pop) * multiplier) + multiplier *= 60 + end + + result = whole_part + result += Float("." + after_decimal) unless after_decimal.nil? + result *= -1 if value[0] == "-" + result + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/psych_handler.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/psych_handler.rb new file mode 100644 index 0000000..cf016a3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/psych_handler.rb @@ -0,0 +1,99 @@ +require "psych" +require "base64" + +module SafeYAML + class PsychHandler < Psych::Handler + def initialize(options, &block) + @options = SafeYAML::OPTIONS.merge(options || {}) + @block = block + @initializers = @options[:custom_initializers] || {} + @anchors = {} + @stack = [] + @current_key = nil + @result = nil + @begun = false + end + + def result + @begun ? @result : false + end + + def add_to_current_structure(value, anchor=nil, quoted=nil, tag=nil) + value = Transform.to_proper_type(value, quoted, tag, @options) + + @anchors[anchor] = value if anchor + + if !@begun + @begun = true + @result = value + @current_structure = @result + return + end + + if @current_structure.respond_to?(:<<) + @current_structure << value + + elsif @current_structure.respond_to?(:[]=) + if @current_key.nil? + @current_key = value + + else + if @current_key == "<<" + @current_structure.merge!(value) + else + @current_structure[@current_key] = value + end + + @current_key = nil + end + + else + raise "Don't know how to add to a #{@current_structure.class}!" + end + end + + def end_current_structure + @stack.pop + @current_structure = @stack.last + end + + def streaming? + true + end + + # event handlers + def alias(anchor) + add_to_current_structure(@anchors[anchor]) + end + + def scalar(value, anchor, tag, plain, quoted, style) + add_to_current_structure(value, anchor, quoted, tag) + end + + def end_document(implicit) + @block.call(@result) + end + + def start_mapping(anchor, tag, implicit, style) + map = @initializers.include?(tag) ? @initializers[tag].call : {} + self.add_to_current_structure(map, anchor) + @current_structure = map + @stack.push(map) + end + + def end_mapping + self.end_current_structure() + end + + def start_sequence(anchor, tag, implicit, style) + seq = @initializers.include?(tag) ? @initializers[tag].call : [] + self.add_to_current_structure(seq, anchor) + @current_structure = seq + @stack.push(seq) + end + + def end_sequence + self.end_current_structure() + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/psych_resolver.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/psych_resolver.rb new file mode 100644 index 0000000..851989b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/psych_resolver.rb @@ -0,0 +1,52 @@ +module SafeYAML + class PsychResolver < Resolver + NODE_TYPES = { + Psych::Nodes::Document => :root, + Psych::Nodes::Mapping => :map, + Psych::Nodes::Sequence => :seq, + Psych::Nodes::Scalar => :scalar, + Psych::Nodes::Alias => :alias + }.freeze + + def initialize(options={}) + super + @aliased_nodes = {} + end + + def resolve_root(root) + resolve_seq(root).first + end + + def resolve_alias(node) + resolve_node(@aliased_nodes[node.anchor]) + end + + def native_resolve(node) + @visitor ||= SafeYAML::SafeToRubyVisitor.new(self) + @visitor.accept(node) + end + + def get_node_type(node) + NODE_TYPES[node.class] + end + + def get_node_tag(node) + node.tag + end + + def get_node_value(node) + @aliased_nodes[node.anchor] = node if node.respond_to?(:anchor) && node.anchor + + case get_node_type(node) + when :root, :map, :seq + node.children + when :scalar + node.value + end + end + + def value_is_quoted?(node) + node.quoted + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/resolver.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/resolver.rb new file mode 100644 index 0000000..e4de157 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/resolver.rb @@ -0,0 +1,94 @@ +module SafeYAML + class Resolver + def initialize(options) + @options = SafeYAML::OPTIONS.merge(options || {}) + @whitelist = @options[:whitelisted_tags] || [] + @initializers = @options[:custom_initializers] || {} + @raise_on_unknown_tag = @options[:raise_on_unknown_tag] + end + + def resolve_node(node) + return node if !node + return self.native_resolve(node) if tag_is_whitelisted?(self.get_node_tag(node)) + + case self.get_node_type(node) + when :root + resolve_root(node) + when :map + resolve_map(node) + when :seq + resolve_seq(node) + when :scalar + resolve_scalar(node) + when :alias + resolve_alias(node) + else + raise "Don't know how to resolve this node: #{node.inspect}" + end + end + + def resolve_map(node) + tag = get_and_check_node_tag(node) + hash = @initializers.include?(tag) ? @initializers[tag].call : {} + map = normalize_map(self.get_node_value(node)) + + # Take the "<<" key nodes first, as these are meant to approximate a form of inheritance. + inheritors = map.select { |key_node, value_node| resolve_node(key_node) == "<<" } + inheritors.each do |key_node, value_node| + merge_into_hash(hash, resolve_node(value_node)) + end + + # All that's left should be normal (non-"<<") nodes. + (map - inheritors).each do |key_node, value_node| + hash[resolve_node(key_node)] = resolve_node(value_node) + end + + return hash + end + + def resolve_seq(node) + seq = self.get_node_value(node) + + tag = get_and_check_node_tag(node) + arr = @initializers.include?(tag) ? @initializers[tag].call : [] + + seq.inject(arr) { |array, n| array << resolve_node(n) } + end + + def resolve_scalar(node) + Transform.to_proper_type(self.get_node_value(node), self.value_is_quoted?(node), get_and_check_node_tag(node), @options) + end + + def get_and_check_node_tag(node) + tag = self.get_node_tag(node) + SafeYAML.tag_safety_check!(tag, @options) + tag + end + + def tag_is_whitelisted?(tag) + @whitelist.include?(tag) + end + + def options + @options + end + + private + def normalize_map(map) + # Syck creates Hashes from maps. + if map.is_a?(Hash) + map.inject([]) { |arr, key_and_value| arr << key_and_value } + + # Psych is really weird; it flattens out a Hash completely into: [key, value, key, value, ...] + else + map.each_slice(2).to_a + end + end + + def merge_into_hash(hash, array) + array.each do |key, value| + hash[key] = value + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/safe_to_ruby_visitor.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/safe_to_ruby_visitor.rb new file mode 100644 index 0000000..b980445 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/safe_to_ruby_visitor.rb @@ -0,0 +1,29 @@ +module SafeYAML + class SafeToRubyVisitor < Psych::Visitors::ToRuby + INITIALIZE_ARITY = superclass.instance_method(:initialize).arity + + def initialize(resolver) + case INITIALIZE_ARITY + when 2 + # https://github.com/tenderlove/psych/blob/v2.0.0/lib/psych/visitors/to_ruby.rb#L14-L28 + loader = Psych::ClassLoader.new + scanner = Psych::ScalarScanner.new(loader) + super(scanner, loader) + + else + super() + end + + @resolver = resolver + end + + def accept(node) + if node.tag + SafeYAML.tag_safety_check!(node.tag, @resolver.options) + return super + end + + @resolver.resolve_node(node) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/store.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/store.rb new file mode 100644 index 0000000..e02a0fc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/store.rb @@ -0,0 +1,39 @@ +require 'safe_yaml/load' +require 'yaml/store' + +module SafeYAML + + class Store < YAML::Store + + # Override YAML::Store#initialize to accept additional option + # +safe_yaml_opts+. + def initialize(file_name, yaml_opts = {}, safe_yaml_opts = {}) + @safe_yaml_opts = safe_yaml_opts + super(file_name, yaml_opts) + end + + # Override YAML::Store#load to use SafeYAML.load instead of + # YAML.load (via #safe_yaml_load). + #-- + # PStore#load is private, while YAML::Store#load is public. + #++ + def load(content) + table = safe_yaml_load(content) + table == false ? {} : table + end + + private + + if SafeYAML::YAML_ENGINE == 'psych' + def safe_yaml_load(content) + SafeYAML.load(content, nil, @safe_yaml_opts) + end + else + def safe_yaml_load(content) + SafeYAML.load(content, @safe_yaml_opts) + end + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/syck_hack.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/syck_hack.rb new file mode 100644 index 0000000..08a5e47 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/syck_hack.rb @@ -0,0 +1,36 @@ +# Hack to JRuby 1.8's YAML Parser Yecht +# +# This file is always loaded AFTER either syck or psych are already +# loaded. It then looks at what constants are available and creates +# a consistent view on all rubys. +# +# Taken from rubygems and modified. +# See https://github.com/rubygems/rubygems/blob/master/lib/rubygems/syck_hack.rb + +module YAML + # In newer 1.9.2, there is a Syck toplevel constant instead of it + # being underneith YAML. If so, reference it back under YAML as + # well. + if defined? ::Syck + # for tests that change YAML::ENGINE + # 1.8 does not support the second argument to const_defined? + remove_const :Syck rescue nil + + Syck = ::Syck + + # JRuby's "Syck" is called "Yecht" + elsif defined? YAML::Yecht + Syck = YAML::Yecht + end +end + +# Sometime in the 1.9 dev cycle, the Syck constant was moved from under YAML +# to be a toplevel constant. So gemspecs created under these versions of Syck +# will have references to Syck::DefaultKey. +# +# So we need to be sure that we reference Syck at the toplevel too so that +# we can always load these kind of gemspecs. +# +if !defined?(Syck) + Syck = YAML::Syck +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/syck_node_monkeypatch.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/syck_node_monkeypatch.rb new file mode 100644 index 0000000..c026376 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/syck_node_monkeypatch.rb @@ -0,0 +1,43 @@ +# This is, admittedly, pretty insane. Fundamentally the challenge here is this: if we want to allow +# whitelisting of tags (while still leveraging Syck's internal functionality), then we have to +# change how Syck::Node#transform works. But since we (SafeYAML) do not control instantiation of +# Syck::Node objects, we cannot, for example, subclass Syck::Node and override #tranform the "easy" +# way. So the only choice is to monkeypatch, like this. And the only way to make this work +# recursively with potentially call-specific options (that my feeble brain can think of) is to set +# pseudo-global options on the first call and unset them once the recursive stack has fully unwound. + +monkeypatch = <<-EORUBY + class Node + @@safe_transform_depth = 0 + @@safe_transform_whitelist = nil + + def safe_transform(options={}) + begin + @@safe_transform_depth += 1 + @@safe_transform_whitelist ||= options[:whitelisted_tags] + + if self.type_id + SafeYAML.tag_safety_check!(self.type_id, options) + return unsafe_transform if @@safe_transform_whitelist.include?(self.type_id) + end + + SafeYAML::SyckResolver.new.resolve_node(self) + + ensure + @@safe_transform_depth -= 1 + if @@safe_transform_depth == 0 + @@safe_transform_whitelist = nil + end + end + end + + alias_method :unsafe_transform, :transform + alias_method :transform, :safe_transform + end +EORUBY + +if defined?(YAML::Syck::Node) + YAML::Syck.module_eval monkeypatch +else + Syck.module_eval monkeypatch +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/syck_resolver.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/syck_resolver.rb new file mode 100644 index 0000000..10d55ab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/syck_resolver.rb @@ -0,0 +1,38 @@ +module SafeYAML + class SyckResolver < Resolver + QUOTE_STYLES = [ + :quote1, + :quote2 + ].freeze + + NODE_TYPES = { + Hash => :map, + Array => :seq, + String => :scalar + }.freeze + + def initialize(options={}) + super + end + + def native_resolve(node) + node.transform(self.options) + end + + def get_node_type(node) + NODE_TYPES[node.value.class] + end + + def get_node_tag(node) + node.type_id + end + + def get_node_value(node) + node.value + end + + def value_is_quoted?(node) + QUOTE_STYLES.include?(node.instance_variable_get(:@style)) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform.rb new file mode 100644 index 0000000..d61d1a9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform.rb @@ -0,0 +1,41 @@ +require 'base64' + +module SafeYAML + class Transform + TRANSFORMERS = [ + Transform::ToSymbol.new, + Transform::ToInteger.new, + Transform::ToFloat.new, + Transform::ToNil.new, + Transform::ToBoolean.new, + Transform::ToDate.new + ] + + def self.to_guessed_type(value, quoted=false, options=nil) + return value if quoted + + if value.is_a?(String) + TRANSFORMERS.each do |transformer| + success, transformed_value = transformer.method(:transform?).arity == 1 ? + transformer.transform?(value) : + transformer.transform?(value, options) + + return transformed_value if success + end + end + + value + end + + def self.to_proper_type(value, quoted=false, tag=nil, options=nil) + case tag + when "tag:yaml.org,2002:binary", "x-private:binary", "!binary" + decoded = Base64.decode64(value) + decoded = decoded.force_encoding(value.encoding) if decoded.respond_to?(:force_encoding) + decoded + else + self.to_guessed_type(value, quoted, options) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_boolean.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_boolean.rb new file mode 100644 index 0000000..99dc85e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_boolean.rb @@ -0,0 +1,21 @@ +module SafeYAML + class Transform + class ToBoolean + include TransformationMap + + set_predefined_values({ + "yes" => true, + "on" => true, + "true" => true, + "no" => false, + "off" => false, + "false" => false + }) + + def transform?(value) + return false if value.length > 5 + return PREDEFINED_VALUES.include?(value), PREDEFINED_VALUES[value] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_date.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_date.rb new file mode 100644 index 0000000..4bfe552 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_date.rb @@ -0,0 +1,13 @@ +module SafeYAML + class Transform + class ToDate + def transform?(value) + return true, Date.parse(value) if Parse::Date::DATE_MATCHER.match(value) + return true, Parse::Date.value(value) if Parse::Date::TIME_MATCHER.match(value) + false + rescue ArgumentError + return true, value + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_float.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_float.rb new file mode 100644 index 0000000..4ee3f5f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_float.rb @@ -0,0 +1,33 @@ +module SafeYAML + class Transform + class ToFloat + Infinity = 1.0 / 0.0 + NaN = 0.0 / 0.0 + + PREDEFINED_VALUES = { + ".inf" => Infinity, + ".Inf" => Infinity, + ".INF" => Infinity, + "-.inf" => -Infinity, + "-.Inf" => -Infinity, + "-.INF" => -Infinity, + ".nan" => NaN, + ".NaN" => NaN, + ".NAN" => NaN, + }.freeze + + MATCHER = /\A[-+]?(?:\d[\d_]*)?\.[\d_]+(?:[eE][-+][\d]+)?\Z/.freeze + + def transform?(value) + return true, Float(value) if MATCHER.match(value) + try_edge_cases?(value) + end + + def try_edge_cases?(value) + return true, PREDEFINED_VALUES[value] if PREDEFINED_VALUES.include?(value) + return true, Parse::Sexagesimal.value(value) if Parse::Sexagesimal::FLOAT_MATCHER.match(value) + return false + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_integer.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_integer.rb new file mode 100644 index 0000000..9a5f563 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_integer.rb @@ -0,0 +1,26 @@ +module SafeYAML + class Transform + class ToInteger + MATCHERS = Deep.freeze([ + /\A[-+]?(0|([1-9][0-9_,]*))\Z/, # decimal + /\A0[0-7]+\Z/, # octal + /\A0x[0-9a-f]+\Z/i, # hexadecimal + /\A0b[01_]+\Z/ # binary + ]) + + def transform?(value) + MATCHERS.each_with_index do |matcher, idx| + value = value.gsub(/[_,]/, "") if idx == 0 + return true, Integer(value) if matcher.match(value) + end + try_edge_cases?(value) + end + + def try_edge_cases?(value) + return true, Parse::Hexadecimal.value(value) if Parse::Hexadecimal::MATCHER.match(value) + return true, Parse::Sexagesimal.value(value) if Parse::Sexagesimal::INTEGER_MATCHER.match(value) + return false + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_nil.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_nil.rb new file mode 100644 index 0000000..1f61756 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_nil.rb @@ -0,0 +1,18 @@ +module SafeYAML + class Transform + class ToNil + include TransformationMap + + set_predefined_values({ + "" => nil, + "~" => nil, + "null" => nil + }) + + def transform?(value) + return false if value.length > 4 + return PREDEFINED_VALUES.include?(value), PREDEFINED_VALUES[value] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_symbol.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_symbol.rb new file mode 100644 index 0000000..36a72bb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_symbol.rb @@ -0,0 +1,17 @@ +module SafeYAML + class Transform + class ToSymbol + def transform?(value, options=SafeYAML::OPTIONS) + if options[:deserialize_symbols] && value =~ /\A:./ + if value =~ /\A:(["'])(.*)\1\Z/ + return true, $2.sub(/^:/, "").to_sym + else + return true, value.sub(/^:/, "").to_sym + end + end + + return false + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/transformation_map.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/transformation_map.rb new file mode 100644 index 0000000..d4e45ec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/transformation_map.rb @@ -0,0 +1,47 @@ +module SafeYAML + class Transform + module TransformationMap + def self.included(base) + base.extend(ClassMethods) + end + + class CaseAgnosticMap < Hash + def initialize(*args) + super + end + + def include?(key) + super(key.downcase) + end + + def [](key) + super(key.downcase) + end + + # OK, I actually don't think it's all that important that this map be + # frozen. + def freeze + self + end + end + + module ClassMethods + def set_predefined_values(predefined_values) + if SafeYAML::YAML_ENGINE == "syck" + expanded_map = predefined_values.inject({}) do |hash, (key, value)| + hash[key] = value + hash[key.capitalize] = value + hash[key.upcase] = value + hash + end + else + expanded_map = CaseAgnosticMap.new + expanded_map.merge!(predefined_values) + end + + self.const_set(:PREDEFINED_VALUES, expanded_map.freeze) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/version.rb b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/version.rb new file mode 100644 index 0000000..89ff3b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/safe_yaml-1.0.5/lib/safe_yaml/version.rb @@ -0,0 +1,3 @@ +module SafeYAML + VERSION = "1.0.5" +end |
