diff options
Diffstat (limited to 'ext/psych/lib/psych')
-rw-r--r-- | ext/psych/lib/psych/class_loader.rb | 6 | ||||
-rw-r--r-- | ext/psych/lib/psych/core_ext.rb | 2 | ||||
-rw-r--r-- | ext/psych/lib/psych/exception.rb | 14 | ||||
-rw-r--r-- | ext/psych/lib/psych/handlers/document_stream.rb | 2 | ||||
-rw-r--r-- | ext/psych/lib/psych/handlers/recorder.rb | 2 | ||||
-rw-r--r-- | ext/psych/lib/psych/json/stream.rb | 4 | ||||
-rw-r--r-- | ext/psych/lib/psych/json/tree_builder.rb | 2 | ||||
-rw-r--r-- | ext/psych/lib/psych/nodes.rb | 14 | ||||
-rw-r--r-- | ext/psych/lib/psych/nodes/node.rb | 8 | ||||
-rw-r--r-- | ext/psych/lib/psych/parser.rb | 13 | ||||
-rw-r--r-- | ext/psych/lib/psych/scalar_scanner.rb | 29 | ||||
-rw-r--r-- | ext/psych/lib/psych/syntax_error.rb | 2 | ||||
-rw-r--r-- | ext/psych/lib/psych/tree_builder.rb | 6 | ||||
-rw-r--r-- | ext/psych/lib/psych/versions.rb | 4 | ||||
-rw-r--r-- | ext/psych/lib/psych/visitors.rb | 12 | ||||
-rw-r--r-- | ext/psych/lib/psych/visitors/json_tree.rb | 2 | ||||
-rw-r--r-- | ext/psych/lib/psych/visitors/to_ruby.rb | 20 | ||||
-rw-r--r-- | ext/psych/lib/psych/visitors/yaml_tree.rb | 50 |
18 files changed, 112 insertions, 80 deletions
diff --git a/ext/psych/lib/psych/class_loader.rb b/ext/psych/lib/psych/class_loader.rb index 088373cd66..50efc35ee2 100644 --- a/ext/psych/lib/psych/class_loader.rb +++ b/ext/psych/lib/psych/class_loader.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'psych/omap' -require 'psych/set' +require_relative 'omap' +require_relative 'set' module Psych class ClassLoader # :nodoc: @@ -35,7 +35,7 @@ module Psych constants.each do |const| konst = const_get const - class_eval <<~RUBY + class_eval <<~RUBY, __FILE__, __LINE__ + 1 def #{const.to_s.downcase} load #{konst.inspect} end diff --git a/ext/psych/lib/psych/core_ext.rb b/ext/psych/lib/psych/core_ext.rb index 81055cc501..0721a133c3 100644 --- a/ext/psych/lib/psych/core_ext.rb +++ b/ext/psych/lib/psych/core_ext.rb @@ -15,5 +15,5 @@ class Object end if defined?(::IRB) - require 'psych/y' + require_relative 'y' end diff --git a/ext/psych/lib/psych/exception.rb b/ext/psych/lib/psych/exception.rb index f473b95a3b..d7469a4b30 100644 --- a/ext/psych/lib/psych/exception.rb +++ b/ext/psych/lib/psych/exception.rb @@ -6,6 +6,20 @@ module Psych class BadAlias < Exception end + # Subclasses `BadAlias` for backwards compatibility + class AliasesNotEnabled < BadAlias + def initialize + super "Alias parsing was not enabled. To enable it, pass `aliases: true` to `Psych::load` or `Psych::safe_load`." + end + end + + # Subclasses `BadAlias` for backwards compatibility + class AnchorNotDefined < BadAlias + def initialize anchor_name + super "An alias referenced an unknown anchor: #{anchor_name}" + end + end + class DisallowedClass < Exception def initialize action, klass_name super "Tried to #{action} unspecified class: #{klass_name}" diff --git a/ext/psych/lib/psych/handlers/document_stream.rb b/ext/psych/lib/psych/handlers/document_stream.rb index 67da794093..b77115d074 100644 --- a/ext/psych/lib/psych/handlers/document_stream.rb +++ b/ext/psych/lib/psych/handlers/document_stream.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -require 'psych/tree_builder' +require_relative '../tree_builder' module Psych module Handlers diff --git a/ext/psych/lib/psych/handlers/recorder.rb b/ext/psych/lib/psych/handlers/recorder.rb index a8fc7b1144..c98724cb76 100644 --- a/ext/psych/lib/psych/handlers/recorder.rb +++ b/ext/psych/lib/psych/handlers/recorder.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -require 'psych/handler' +require_relative '../handler' module Psych module Handlers diff --git a/ext/psych/lib/psych/json/stream.rb b/ext/psych/lib/psych/json/stream.rb index 2ebd3d7a66..24dd4b9baf 100644 --- a/ext/psych/lib/psych/json/stream.rb +++ b/ext/psych/lib/psych/json/stream.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'psych/json/ruby_events' -require 'psych/json/yaml_events' +require_relative 'ruby_events' +require_relative 'yaml_events' module Psych module JSON diff --git a/ext/psych/lib/psych/json/tree_builder.rb b/ext/psych/lib/psych/json/tree_builder.rb index 5c2ee8ca25..9a45f6b94c 100644 --- a/ext/psych/lib/psych/json/tree_builder.rb +++ b/ext/psych/lib/psych/json/tree_builder.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -require 'psych/json/yaml_events' +require_relative 'yaml_events' module Psych module JSON diff --git a/ext/psych/lib/psych/nodes.rb b/ext/psych/lib/psych/nodes.rb index 5842c2e3e5..2fa52e0055 100644 --- a/ext/psych/lib/psych/nodes.rb +++ b/ext/psych/lib/psych/nodes.rb @@ -1,11 +1,11 @@ # frozen_string_literal: true -require 'psych/nodes/node' -require 'psych/nodes/stream' -require 'psych/nodes/document' -require 'psych/nodes/sequence' -require 'psych/nodes/scalar' -require 'psych/nodes/mapping' -require 'psych/nodes/alias' +require_relative 'nodes/node' +require_relative 'nodes/stream' +require_relative 'nodes/document' +require_relative 'nodes/sequence' +require_relative 'nodes/scalar' +require_relative 'nodes/mapping' +require_relative 'nodes/alias' module Psych ### diff --git a/ext/psych/lib/psych/nodes/node.rb b/ext/psych/lib/psych/nodes/node.rb index 05cb08dac0..f44fce5f05 100644 --- a/ext/psych/lib/psych/nodes/node.rb +++ b/ext/psych/lib/psych/nodes/node.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'stringio' -require 'psych/class_loader' -require 'psych/scalar_scanner' +require_relative '../class_loader' +require_relative '../scalar_scanner' module Psych module Nodes @@ -46,8 +46,8 @@ module Psych # Convert this node to Ruby. # # See also Psych::Visitors::ToRuby - def to_ruby(symbolize_names: false, freeze: false) - Visitors::ToRuby.create(symbolize_names: symbolize_names, freeze: freeze).accept(self) + def to_ruby(symbolize_names: false, freeze: false, strict_integer: false) + Visitors::ToRuby.create(symbolize_names: symbolize_names, freeze: freeze, strict_integer: strict_integer).accept(self) end alias :transform :to_ruby diff --git a/ext/psych/lib/psych/parser.rb b/ext/psych/lib/psych/parser.rb index 39bc8289be..2181c730e5 100644 --- a/ext/psych/lib/psych/parser.rb +++ b/ext/psych/lib/psych/parser.rb @@ -48,5 +48,18 @@ module Psych @handler = handler @external_encoding = ANY end + + ### + # call-seq: + # parser.parse(yaml) + # + # Parse the YAML document contained in +yaml+. Events will be called on + # the handler set on the parser instance. + # + # See Psych::Parser and Psych::Parser#handler + + def parse yaml, path = yaml.respond_to?(:path) ? yaml.path : "<unknown>" + _native_parse @handler, yaml, path + end end end diff --git a/ext/psych/lib/psych/scalar_scanner.rb b/ext/psych/lib/psych/scalar_scanner.rb index b66ff9938c..3cb4bf3c7e 100644 --- a/ext/psych/lib/psych/scalar_scanner.rb +++ b/ext/psych/lib/psych/scalar_scanner.rb @@ -1,5 +1,4 @@ # frozen_string_literal: true -require 'strscan' module Psych ### @@ -13,24 +12,32 @@ module Psych FLOAT = /^(?:[-+]?([0-9][0-9_,]*)?\.[0-9]*([eE][-+][0-9]+)?(?# base 10))$/x # Taken from http://yaml.org/type/int.html - INTEGER = /^(?:[-+]?0b[0-1_,]+ (?# base 2) - |[-+]?0[0-7_,]+ (?# base 8) - |[-+]?(?:0|[1-9](?:[0-9]|,[0-9]|_[0-9])*) (?# base 10) - |[-+]?0x[0-9a-fA-F_,]+ (?# base 16))$/x + INTEGER_STRICT = /^(?:[-+]?0b[0-1_]+ (?# base 2) + |[-+]?0[0-7_]+ (?# base 8) + |[-+]?(0|[1-9][0-9_]*) (?# base 10) + |[-+]?0x[0-9a-fA-F_]+ (?# base 16))$/x + + # Same as above, but allows commas. + # Not to YML spec, but kept for backwards compatibility + INTEGER_LEGACY = /^(?:[-+]?0b[0-1_,]+ (?# base 2) + |[-+]?0[0-7_,]+ (?# base 8) + |[-+]?(?:0|[1-9](?:[0-9]|,[0-9]|_[0-9])*) (?# base 10) + |[-+]?0x[0-9a-fA-F_,]+ (?# base 16))$/x attr_reader :class_loader # Create a new scanner - def initialize class_loader + def initialize class_loader, strict_integer: false @symbol_cache = {} @class_loader = class_loader + @strict_integer = strict_integer end # Tokenize +string+ returning the Ruby object def tokenize string return nil if string.empty? return @symbol_cache[string] if @symbol_cache.key?(string) - + integer_regex = @strict_integer ? INTEGER_STRICT : INTEGER_LEGACY # Check for a String type, being careful not to get caught by hash keys, hex values, and # special floats (e.g., -.inf). if string.match?(%r{^[^\d.:-]?[[:alpha:]_\s!@#$%\^&*(){}<>|/\\~;=]+}) || string.match?(/\n/) @@ -56,7 +63,7 @@ module Psych elsif string.match?(/^\d{4}-(?:1[012]|0\d|\d)-(?:[12]\d|3[01]|0\d|\d)$/) require 'date' begin - class_loader.date.strptime(string, '%Y-%m-%d') + class_loader.date.strptime(string, '%F', Date::GREGORIAN) rescue ArgumentError string end @@ -88,9 +95,9 @@ module Psych if string.match?(/\A[-+]?\.\Z/) string else - Float(string.gsub(/[,_]|\.([Ee]|$)/, '\1')) + Float(string.delete(',_').gsub(/\.([Ee]|$)/, '\1')) end - elsif string.match?(INTEGER) + elsif string.match?(integer_regex) parse_int string else string @@ -100,7 +107,7 @@ module Psych ### # Parse and return an int from +string+ def parse_int string - Integer(string.gsub(/[,_]/, '')) + Integer(string.delete(',_')) end ### diff --git a/ext/psych/lib/psych/syntax_error.rb b/ext/psych/lib/psych/syntax_error.rb index 1598e6ff36..a4c9c4a376 100644 --- a/ext/psych/lib/psych/syntax_error.rb +++ b/ext/psych/lib/psych/syntax_error.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -require 'psych/exception' +require_relative 'exception' module Psych class SyntaxError < Psych::Exception diff --git a/ext/psych/lib/psych/tree_builder.rb b/ext/psych/lib/psych/tree_builder.rb index 47a1695643..83115bd721 100644 --- a/ext/psych/lib/psych/tree_builder.rb +++ b/ext/psych/lib/psych/tree_builder.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -require 'psych/handler' +require_relative 'handler' module Psych ### @@ -41,7 +41,7 @@ module Psych Sequence Mapping }.each do |node| - class_eval %{ + class_eval <<~RUBY, __FILE__, __LINE__ + 1 def start_#{node.downcase}(anchor, tag, implicit, style) n = Nodes::#{node}.new(anchor, tag, implicit, style) set_start_location(n) @@ -54,7 +54,7 @@ module Psych set_end_location(n) n end - } + RUBY end ### diff --git a/ext/psych/lib/psych/versions.rb b/ext/psych/lib/psych/versions.rb index 513d010903..b9e8d9ef11 100644 --- a/ext/psych/lib/psych/versions.rb +++ b/ext/psych/lib/psych/versions.rb @@ -2,9 +2,9 @@ module Psych # The version of Psych you are using - VERSION = '4.0.1' + VERSION = '5.1.2' if RUBY_ENGINE == 'jruby' - DEFAULT_SNAKEYAML_VERSION = '1.28'.freeze + DEFAULT_SNAKEYAML_VERSION = '2.7'.freeze end end diff --git a/ext/psych/lib/psych/visitors.rb b/ext/psych/lib/psych/visitors.rb index e2b084daee..508290d862 100644 --- a/ext/psych/lib/psych/visitors.rb +++ b/ext/psych/lib/psych/visitors.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true -require 'psych/visitors/visitor' -require 'psych/visitors/to_ruby' -require 'psych/visitors/emitter' -require 'psych/visitors/yaml_tree' -require 'psych/visitors/json_tree' -require 'psych/visitors/depth_first' +require_relative 'visitors/visitor' +require_relative 'visitors/to_ruby' +require_relative 'visitors/emitter' +require_relative 'visitors/yaml_tree' +require_relative 'visitors/json_tree' +require_relative 'visitors/depth_first' diff --git a/ext/psych/lib/psych/visitors/json_tree.rb b/ext/psych/lib/psych/visitors/json_tree.rb index 9912cb1362..979fc100bd 100644 --- a/ext/psych/lib/psych/visitors/json_tree.rb +++ b/ext/psych/lib/psych/visitors/json_tree.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -require 'psych/json/ruby_events' +require_relative '../json/ruby_events' module Psych module Visitors diff --git a/ext/psych/lib/psych/visitors/to_ruby.rb b/ext/psych/lib/psych/visitors/to_ruby.rb index 4de7f80d33..f0fda9bdbc 100644 --- a/ext/psych/lib/psych/visitors/to_ruby.rb +++ b/ext/psych/lib/psych/visitors/to_ruby.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true -require 'psych/scalar_scanner' -require 'psych/class_loader' -require 'psych/exception' +require_relative '../scalar_scanner' +require_relative '../class_loader' +require_relative '../exception' unless defined?(Regexp::NOENCODING) Regexp::NOENCODING = 32 @@ -12,9 +12,9 @@ module Psych ### # This class walks a YAML AST, converting each node to Ruby class ToRuby < Psych::Visitors::Visitor - def self.create(symbolize_names: false, freeze: false) + def self.create(symbolize_names: false, freeze: false, strict_integer: false) class_loader = ClassLoader.new - scanner = ScalarScanner.new class_loader + scanner = ScalarScanner.new class_loader, strict_integer: strict_integer new(scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze) end @@ -80,7 +80,9 @@ module Psych when "!ruby/object:DateTime" class_loader.date_time require 'date' unless defined? DateTime - @ss.parse_time(o.value).to_datetime + t = @ss.parse_time(o.value) + DateTime.civil(*t.to_a[0, 6].reverse, Rational(t.utc_offset, 86400)) + + (t.subsec/86400) when '!ruby/encoding' ::Encoding.find o.value when "!ruby/object:Complex" @@ -99,7 +101,7 @@ module Psych source = $1 options = 0 lang = nil - ($2 || '').split('').each do |option| + $2&.each_char do |option| case option when 'x' then options |= Regexp::EXTENDED when 'i' then options |= Regexp::IGNORECASE @@ -323,7 +325,7 @@ module Psych end def visit_Psych_Nodes_Alias o - @st.fetch(o.anchor) { raise BadAlias, "Unknown alias: #{o.anchor}" } + @st.fetch(o.anchor) { raise AnchorNotDefined, o.anchor } end private @@ -427,7 +429,7 @@ module Psych class NoAliasRuby < ToRuby def visit_Psych_Nodes_Alias o - raise BadAlias, "Unknown alias: #{o.anchor}" + raise AliasesNotEnabled end end end diff --git a/ext/psych/lib/psych/visitors/yaml_tree.rb b/ext/psych/lib/psych/visitors/yaml_tree.rb index 2eee4d3457..a2ebc4d781 100644 --- a/ext/psych/lib/psych/visitors/yaml_tree.rb +++ b/ext/psych/lib/psych/visitors/yaml_tree.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true -require 'psych/tree_builder' -require 'psych/scalar_scanner' -require 'psych/class_loader' +require_relative '../tree_builder' +require_relative '../scalar_scanner' +require_relative '../class_loader' module Psych module Visitors @@ -15,30 +15,25 @@ module Psych class YAMLTree < Psych::Visitors::Visitor class Registrar # :nodoc: def initialize - @obj_to_id = {} - @obj_to_node = {} - @targets = [] + @obj_to_id = {}.compare_by_identity + @obj_to_node = {}.compare_by_identity @counter = 0 end def register target, node - return unless target.respond_to? :object_id - @targets << target - @obj_to_node[target.object_id] = node + @obj_to_node[target] = node end def key? target - @obj_to_node.key? target.object_id - rescue NoMethodError - false + @obj_to_node.key? target end def id_for target - @obj_to_id[target.object_id] ||= (@counter += 1) + @obj_to_id[target] ||= (@counter += 1) end def node_for target - @obj_to_node[target.object_id] + @obj_to_node[target] end end @@ -70,6 +65,7 @@ module Psych fail(ArgumentError, "Invalid line_width #{@line_width}, must be non-negative or -1 for unlimited.") end end + @stringify_names = options[:stringify_names] @coders = [] @dispatch_cache = Hash.new do |h,klass| @@ -192,12 +188,13 @@ module Psych register o, @emitter.scalar(o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY) end + def visit_Date o + register o, visit_Integer(o.gregorian) + end + def visit_DateTime o - formatted = if o.offset.zero? - o.strftime("%Y-%m-%d %H:%M:%S.%9N Z".freeze) - else - o.strftime("%Y-%m-%d %H:%M:%S.%9N %:z".freeze) - end + t = o.italy + formatted = format_time t, t.offset.zero? tag = '!ruby/object:DateTime' register o, @emitter.scalar(formatted, nil, tag, false, false, Nodes::Scalar::ANY) end @@ -235,7 +232,6 @@ module Psych end alias :visit_TrueClass :visit_Integer alias :visit_FalseClass :visit_Integer - alias :visit_Date :visit_Integer def visit_Float o if o.nan? @@ -272,7 +268,7 @@ module Psych tag = 'tag:yaml.org,2002:str' plain = false quote = false - elsif o == 'y' || o == 'n' + elsif o == 'y' || o == 'Y' || o == 'n' || o == 'N' style = Nodes::Scalar::DOUBLE_QUOTED elsif @line_width && o.length > @line_width style = Nodes::Scalar::FOLDED @@ -328,7 +324,7 @@ module Psych if o.class == ::Hash register(o, @emitter.start_mapping(nil, nil, true, Psych::Nodes::Mapping::BLOCK)) o.each do |k,v| - accept k + accept(@stringify_names && Symbol === k ? k.to_s : k) accept v end @emitter.end_mapping @@ -341,7 +337,7 @@ module Psych register(o, @emitter.start_mapping(nil, '!set', false, Psych::Nodes::Mapping::BLOCK)) o.each do |k,v| - accept k + accept(@stringify_names && Symbol === k ? k.to_s : k) accept v end @@ -482,8 +478,8 @@ module Psych @emitter.end_mapping end - def format_time time - if time.utc? + def format_time time, utc = time.utc? + if utc time.strftime("%Y-%m-%d %H:%M:%S.%9N Z") else time.strftime("%Y-%m-%d %H:%M:%S.%9N %:z") @@ -568,7 +564,7 @@ module Psych raise BadAlias, "Tried to dump an aliased object" end - unless @permitted_classes[target.class] + unless Symbol === target || @permitted_classes[target.class] raise DisallowedClass.new('dump', target.class.name || target.class.inspect) end @@ -576,7 +572,7 @@ module Psych end def visit_Symbol sym - unless @permitted_symbols[sym] + unless @permitted_classes[Symbol] || @permitted_symbols[sym] raise DisallowedClass.new('dump', "Symbol(#{sym.inspect})") end |