diff options
Diffstat (limited to 'ext/psych')
| -rw-r--r-- | ext/psych/depend | 5 | ||||
| -rw-r--r-- | ext/psych/extconf.rb | 7 | ||||
| -rw-r--r-- | ext/psych/lib/psych.rb | 51 | ||||
| -rw-r--r-- | ext/psych/lib/psych/class_loader.rb | 1 | ||||
| -rw-r--r-- | ext/psych/lib/psych/core_ext.rb | 21 | ||||
| -rw-r--r-- | ext/psych/lib/psych/nodes/node.rb | 7 | ||||
| -rw-r--r-- | ext/psych/lib/psych/scalar_scanner.rb | 7 | ||||
| -rw-r--r-- | ext/psych/lib/psych/versions.rb | 4 | ||||
| -rw-r--r-- | ext/psych/lib/psych/visitors/to_ruby.rb | 57 | ||||
| -rw-r--r-- | ext/psych/lib/psych/visitors/yaml_tree.rb | 53 | ||||
| -rw-r--r-- | ext/psych/psych.c | 1 | ||||
| -rw-r--r-- | ext/psych/psych.gemspec | 2 | ||||
| -rw-r--r-- | ext/psych/psych_emitter.c | 4 | ||||
| -rw-r--r-- | ext/psych/psych_parser.c | 18 | ||||
| -rw-r--r-- | ext/psych/psych_to_ruby.c | 5 | ||||
| -rw-r--r-- | ext/psych/psych_yaml_tree.c | 1 |
16 files changed, 201 insertions, 43 deletions
diff --git a/ext/psych/depend b/ext/psych/depend index a4d9ca9a6a..95175841a2 100644 --- a/ext/psych/depend +++ b/ext/psych/depend @@ -152,6 +152,7 @@ psych.o: $(hdrdir)/ruby/internal/intern/re.h psych.o: $(hdrdir)/ruby/internal/intern/ruby.h psych.o: $(hdrdir)/ruby/internal/intern/select.h psych.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +psych.o: $(hdrdir)/ruby/internal/intern/set.h psych.o: $(hdrdir)/ruby/internal/intern/signal.h psych.o: $(hdrdir)/ruby/internal/intern/sprintf.h psych.o: $(hdrdir)/ruby/internal/intern/string.h @@ -329,6 +330,7 @@ psych_emitter.o: $(hdrdir)/ruby/internal/intern/re.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/ruby.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/select.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +psych_emitter.o: $(hdrdir)/ruby/internal/intern/set.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/signal.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/sprintf.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/string.h @@ -506,6 +508,7 @@ psych_parser.o: $(hdrdir)/ruby/internal/intern/re.h psych_parser.o: $(hdrdir)/ruby/internal/intern/ruby.h psych_parser.o: $(hdrdir)/ruby/internal/intern/select.h psych_parser.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +psych_parser.o: $(hdrdir)/ruby/internal/intern/set.h psych_parser.o: $(hdrdir)/ruby/internal/intern/signal.h psych_parser.o: $(hdrdir)/ruby/internal/intern/sprintf.h psych_parser.o: $(hdrdir)/ruby/internal/intern/string.h @@ -683,6 +686,7 @@ psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/re.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/ruby.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/select.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/set.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/signal.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/sprintf.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/string.h @@ -860,6 +864,7 @@ psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/re.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/ruby.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/select.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/set.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/signal.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/sprintf.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/string.h diff --git a/ext/psych/extconf.rb b/ext/psych/extconf.rb index e7dd0bb60a..589e201c1c 100644 --- a/ext/psych/extconf.rb +++ b/ext/psych/extconf.rb @@ -36,8 +36,11 @@ if yaml_source libyaml = "libyaml.#$LIBEXT" $cleanfiles << libyaml $LOCAL_LIBS.prepend("$(LIBYAML) ") -else # default to pre-installed libyaml - pkg_config('yaml-0.1') + + # default to pre-installed libyaml +elsif pkg_config('yaml-0.1') + # found with pkg-config +else dir_config('libyaml') find_header('yaml.h') or abort "yaml.h not found" find_library('yaml', 'yaml_get_version') or abort "libyaml not found" diff --git a/ext/psych/lib/psych.rb b/ext/psych/lib/psych.rb index d227b1f225..850a6d1937 100644 --- a/ext/psych/lib/psych.rb +++ b/ext/psych/lib/psych.rb @@ -1,4 +1,6 @@ # frozen_string_literal: true +require 'date' + require_relative 'psych/versions' case RUBY_ENGINE when 'jruby' @@ -21,7 +23,6 @@ require_relative 'psych/parser' require_relative 'psych/omap' require_relative 'psych/set' require_relative 'psych/coder' -require_relative 'psych/core_ext' require_relative 'psych/stream' require_relative 'psych/json/tree_builder' require_relative 'psych/json/stream' @@ -84,7 +85,7 @@ require_relative 'psych/class_loader' # Psych.safe_load_file("data.yml", permitted_classes: [Date]) # Psych.load_file("trusted_database.yml") # -# ==== Exception handling +# ==== \Exception handling # # begin # # The second argument changes only the exception contents @@ -148,7 +149,7 @@ require_relative 'psych/class_loader' # # Returns Psych::Nodes::Document # Psych.parse_file('database.yml') # -# ==== Exception handling +# ==== \Exception handling # # begin # # The second argument changes only the exception contents @@ -268,10 +269,10 @@ module Psych # YAML documents that are supplied via user input. Instead, please use the # load method or the safe_load method. # - def self.unsafe_load yaml, filename: nil, fallback: false, symbolize_names: false, freeze: false, strict_integer: false + def self.unsafe_load yaml, filename: nil, fallback: false, symbolize_names: false, freeze: false, strict_integer: false, parse_symbols: true result = parse(yaml, filename: filename) return fallback unless result - result.to_ruby(symbolize_names: symbolize_names, freeze: freeze, strict_integer: strict_integer) + result.to_ruby(symbolize_names: symbolize_names, freeze: freeze, strict_integer: strict_integer, parse_symbols: parse_symbols) end ### @@ -319,13 +320,13 @@ module Psych # Psych.safe_load("---\n foo: bar") # => {"foo"=>"bar"} # Psych.safe_load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"} # - def self.safe_load yaml, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false + def self.safe_load yaml, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false, parse_symbols: true result = parse(yaml, filename: filename) return fallback unless result class_loader = ClassLoader::Restricted.new(permitted_classes.map(&:to_s), permitted_symbols.map(&:to_s)) - scanner = ScalarScanner.new class_loader, strict_integer: strict_integer + scanner = ScalarScanner.new class_loader, strict_integer: strict_integer, parse_symbols: parse_symbols visitor = if aliases Visitors::ToRuby.new scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze else @@ -365,7 +366,7 @@ module Psych # Raises a TypeError when `yaml` parameter is NilClass. This method is # similar to `safe_load` except that `Symbol` objects are allowed by default. # - def self.load yaml, permitted_classes: [Symbol], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false + def self.load yaml, permitted_classes: [Symbol], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false, parse_symbols: true safe_load yaml, permitted_classes: permitted_classes, permitted_symbols: permitted_symbols, aliases: aliases, @@ -373,7 +374,8 @@ module Psych fallback: fallback, symbolize_names: symbolize_names, freeze: freeze, - strict_integer: strict_integer + strict_integer: strict_integer, + parse_symbols: parse_symbols end ### @@ -653,6 +655,35 @@ module Psych end ### + # Load multiple documents given in +yaml+. Returns the parsed documents + # as a list. + # + # Example: + # + # Psych.safe_load_stream("--- foo\n...\n--- bar\n...") # => ['foo', 'bar'] + # + # list = [] + # Psych.safe_load_stream("--- foo\n...\n--- bar\n...") do |ruby| + # list << ruby + # end + # list # => ['foo', 'bar'] + # + def self.safe_load_stream yaml, filename: nil, permitted_classes: [], aliases: false + documents = parse_stream(yaml, filename: filename).children.map do |child| + stream = Psych::Nodes::Stream.new + stream.children << child + safe_load(stream.to_yaml, permitted_classes: permitted_classes, aliases: aliases) + end + + if block_given? + documents.each { |doc| yield doc } + nil + else + documents + end + end + + ### # Load the document contained in +filename+. Returns the yaml contained in # +filename+ as a Ruby object, or if the file is empty, it returns # the specified +fallback+ return value, which defaults to +false+. @@ -759,3 +790,5 @@ module Psych self.domain_types = {} # :startdoc: end + +require_relative 'psych/core_ext' diff --git a/ext/psych/lib/psych/class_loader.rb b/ext/psych/lib/psych/class_loader.rb index 50efc35ee2..c8f509720a 100644 --- a/ext/psych/lib/psych/class_loader.rb +++ b/ext/psych/lib/psych/class_loader.rb @@ -6,6 +6,7 @@ module Psych class ClassLoader # :nodoc: BIG_DECIMAL = 'BigDecimal' COMPLEX = 'Complex' + DATA = 'Data' unless RUBY_VERSION < "3.2" DATE = 'Date' DATE_TIME = 'DateTime' EXCEPTION = 'Exception' diff --git a/ext/psych/lib/psych/core_ext.rb b/ext/psych/lib/psych/core_ext.rb index 0721a133c3..6dfd0f1696 100644 --- a/ext/psych/lib/psych/core_ext.rb +++ b/ext/psych/lib/psych/core_ext.rb @@ -14,6 +14,23 @@ class Object end end -if defined?(::IRB) - require_relative 'y' +# Up to Ruby 3.4, Set was a regular object and was dumped as such +# by Pysch. +# Starting from Ruby 4.0 it's a core class written in C, so we have to implement +# #encode_with / #init_with to preserve backward compatibility. +if defined?(::Set) && Set.new.instance_variables.empty? + class Set + def encode_with(coder) + hash = {} + each do |m| + hash[m] = true + end + coder["hash"] = hash + coder + end + + def init_with(coder) + replace(coder["hash"].keys) + end + end end diff --git a/ext/psych/lib/psych/nodes/node.rb b/ext/psych/lib/psych/nodes/node.rb index 1a4ea5531f..fc27448f2e 100644 --- a/ext/psych/lib/psych/nodes/node.rb +++ b/ext/psych/lib/psych/nodes/node.rb @@ -45,8 +45,8 @@ module Psych # Convert this node to Ruby. # # See also Psych::Visitors::ToRuby - 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) + def to_ruby(symbolize_names: false, freeze: false, strict_integer: false, parse_symbols: true) + Visitors::ToRuby.create(symbolize_names: symbolize_names, freeze: freeze, strict_integer: strict_integer, parse_symbols: parse_symbols).accept(self) end alias :transform :to_ruby @@ -55,7 +55,8 @@ module Psych # # See also Psych::Visitors::Emitter def yaml io = nil, options = {} - require "stringio" + require "stringio" unless defined?(StringIO) + real_io = io || StringIO.new(''.encode('utf-8')) Visitors::Emitter.new(real_io, options).accept self diff --git a/ext/psych/lib/psych/scalar_scanner.rb b/ext/psych/lib/psych/scalar_scanner.rb index de21442344..6a556fb3b8 100644 --- a/ext/psych/lib/psych/scalar_scanner.rb +++ b/ext/psych/lib/psych/scalar_scanner.rb @@ -4,8 +4,6 @@ module Psych ### # Scan scalars for built in types class ScalarScanner - autoload :Date, "date" - # Taken from http://yaml.org/type/timestamp.html TIME = /^-?\d{4}-\d{1,2}-\d{1,2}(?:[Tt]|\s+)\d{1,2}:\d\d:\d\d(?:\.\d*)?(?:\s*(?:Z|[-+]\d{1,2}:?(?:\d\d)?))?$/ @@ -29,10 +27,11 @@ module Psych attr_reader :class_loader # Create a new scanner - def initialize class_loader, strict_integer: false + def initialize class_loader, strict_integer: false, parse_symbols: true @symbol_cache = {} @class_loader = class_loader @strict_integer = strict_integer + @parse_symbols = parse_symbols end # Tokenize +string+ returning the Ruby object @@ -74,7 +73,7 @@ module Psych -Float::INFINITY elsif string.match?(/^\.nan$/i) Float::NAN - elsif string.match?(/^:./) + elsif @parse_symbols && string.match?(/^:./) if string =~ /^:(["'])(.*)\1/ @symbol_cache[string] = class_loader.symbolize($2.sub(/^:/, '')) else diff --git a/ext/psych/lib/psych/versions.rb b/ext/psych/lib/psych/versions.rb index 3d69bf38a1..6c1679bf65 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 = '5.2.0.beta1' + VERSION = '5.4.0' if RUBY_ENGINE == 'jruby' - DEFAULT_SNAKEYAML_VERSION = '2.7'.freeze + DEFAULT_SNAKEYAML_VERSION = '2.10'.freeze end end diff --git a/ext/psych/lib/psych/visitors/to_ruby.rb b/ext/psych/lib/psych/visitors/to_ruby.rb index f0fda9bdbc..475444e589 100644 --- a/ext/psych/lib/psych/visitors/to_ruby.rb +++ b/ext/psych/lib/psych/visitors/to_ruby.rb @@ -12,9 +12,13 @@ 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, strict_integer: false) + unless RUBY_VERSION < "3.2" + DATA_INITIALIZE = Data.instance_method(:initialize) + end + + def self.create(symbolize_names: false, freeze: false, strict_integer: false, parse_symbols: true) class_loader = ClassLoader.new - scanner = ScalarScanner.new class_loader, strict_integer: strict_integer + scanner = ScalarScanner.new class_loader, strict_integer: strict_integer, parse_symbols: parse_symbols new(scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze) end @@ -36,7 +40,7 @@ module Psych unless @domain_types.empty? || !target.tag key = target.tag.sub(/^[!\/]*/, '').sub(/(,\d+)\//, '\1:') - key = "tag:#{key}" unless key =~ /^(?:tag:|x-private)/ + key = "tag:#{key}" unless key.match?(/^(?:tag:|x-private)/) if @domain_types.key? key value, block = @domain_types[key] @@ -79,7 +83,6 @@ module Psych class_loader.big_decimal._load o.value when "!ruby/object:DateTime" class_loader.date_time - require 'date' unless defined? DateTime t = @ss.parse_time(o.value) DateTime.civil(*t.to_a[0, 6].reverse, Rational(t.utc_offset, 86400)) + (t.subsec/86400) @@ -97,11 +100,11 @@ module Psych Float(@ss.tokenize(o.value)) when "!ruby/regexp" klass = class_loader.regexp - o.value =~ /^\/(.*)\/([mixn]*)$/m - source = $1 + matches = /^\/(?<string>.*)\/(?<options>[mixn]*)$/m.match(o.value) + source = matches[:string].gsub('\/', '/') options = 0 lang = nil - $2&.each_char do |option| + matches[:options].each_char do |option| case option when 'x' then options |= Regexp::EXTENDED when 'i' then options |= Regexp::IGNORECASE @@ -198,6 +201,32 @@ module Psych s end + when /^!ruby\/data(-with-ivars)?(?::(.*))?$/ + data = register(o, resolve_class($2).allocate) if $2 + members = {} + + if $1 # data-with-ivars + ivars = {} + o.children.each_slice(2) do |type, vars| + case accept(type) + when 'members' + revive_data_members(members, vars) + data ||= allocate_anon_data(o, members) + when 'ivars' + revive_hash(ivars, vars) + end + end + ivars.each do |ivar, v| + data.instance_variable_set ivar, v + end + else + revive_data_members(members, o) + end + data ||= allocate_anon_data(o, members) + DATA_INITIALIZE.bind_call(data, **members) + data.freeze + data + when /^!ruby\/object:?(.*)?$/ name = $1 || 'Object' @@ -341,6 +370,20 @@ module Psych list end + def allocate_anon_data node, members + klass = class_loader.data.define(*members.keys) + register(node, klass.allocate) + end + + def revive_data_members hash, o + o.children.each_slice(2) do |k,v| + name = accept(k) + value = accept(v) + hash[class_loader.symbolize(name)] = value + end + hash + end + def revive_hash hash, o, tagged= false o.children.each_slice(2) { |k,v| key = accept(k) diff --git a/ext/psych/lib/psych/visitors/yaml_tree.rb b/ext/psych/lib/psych/visitors/yaml_tree.rb index a2ebc4d781..b6c86f4c94 100644 --- a/ext/psych/lib/psych/visitors/yaml_tree.rb +++ b/ext/psych/lib/psych/visitors/yaml_tree.rb @@ -73,7 +73,7 @@ module Psych method = respond_to?(method) ? method : h[klass.superclass] - raise(TypeError, "Can't dump #{target.class}") unless method + raise(TypeError, "can't dump #{klass.name}") unless method h[klass] = method end.compare_by_identity @@ -162,6 +162,44 @@ module Psych alias :visit_Delegator :visit_Object + def visit_Data o + ivars = o.instance_variables + if ivars.empty? + tag = ['!ruby/data', o.class.name].compact.join(':') + register o, @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK) + o.members.each do |member| + @emitter.scalar member.to_s, nil, nil, true, false, Nodes::Scalar::ANY + accept o.send member + end + @emitter.end_mapping + + else + tag = ['!ruby/data-with-ivars', o.class.name].compact.join(':') + node = @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK) + register(o, node) + + # Dump the members + accept 'members' + @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK + o.members.each do |member| + @emitter.scalar member.to_s, nil, nil, true, false, Nodes::Scalar::ANY + accept o.send member + end + @emitter.end_mapping + + # Dump the ivars + accept 'ivars' + @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK + ivars.each do |ivar| + accept ivar.to_s + accept o.instance_variable_get ivar + end + @emitter.end_mapping + + @emitter.end_mapping + end + end unless RUBY_VERSION < "3.2" + def visit_Struct o tag = ['!ruby/struct', o.class.name].compact.join(':') @@ -189,7 +227,8 @@ module Psych end def visit_Date o - register o, visit_Integer(o.gregorian) + formatted = format_date o + register o, @emitter.scalar(formatted, nil, nil, true, false, Nodes::Scalar::ANY) end def visit_DateTime o @@ -261,7 +300,7 @@ module Psych style = Nodes::Scalar::LITERAL plain = false quote = false - elsif o =~ /\n(?!\Z)/ # match \n except blank line at the end of string + elsif o.match?(/\n(?!\Z)/) # match \n except blank line at the end of string style = Nodes::Scalar::LITERAL elsif o == '<<' style = Nodes::Scalar::SINGLE_QUOTED @@ -272,9 +311,9 @@ module Psych style = Nodes::Scalar::DOUBLE_QUOTED elsif @line_width && o.length > @line_width style = Nodes::Scalar::FOLDED - elsif o =~ /^[^[:word:]][^"]*$/ + elsif o.match?(/^[^[:word:]][^"]*$/) style = Nodes::Scalar::DOUBLE_QUOTED - elsif not String === @ss.tokenize(o) or /\A0[0-7]*[89]/ =~ o + elsif not String === @ss.tokenize(o) or /\A0[0-7]*[89]/.match?(o) style = Nodes::Scalar::SINGLE_QUOTED end @@ -486,6 +525,10 @@ module Psych end end + def format_date date + date.strftime("%Y-%m-%d") + end + def register target, yaml_obj @st.register target, yaml_obj yaml_obj diff --git a/ext/psych/psych.c b/ext/psych/psych.c index 3a701b677e..afbd7a3571 100644 --- a/ext/psych/psych.c +++ b/ext/psych/psych.c @@ -34,4 +34,3 @@ void Init_psych(void) Init_psych_to_ruby(); Init_psych_yaml_tree(); } -/* vim: set noet sws=4 sw=4: */ diff --git a/ext/psych/psych.gemspec b/ext/psych/psych.gemspec index a3fc53a8b9..a32f79bc16 100644 --- a/ext/psych/psych.gemspec +++ b/ext/psych/psych.gemspec @@ -75,6 +75,8 @@ DESCRIPTION s.add_dependency 'stringio' end + s.add_dependency 'date' + s.metadata['msys2_mingw_dependencies'] = 'libyaml' s.metadata['changelog_uri'] = s.homepage + '/releases' end diff --git a/ext/psych/psych_emitter.c b/ext/psych/psych_emitter.c index 0c5875f343..624ab7c528 100644 --- a/ext/psych/psych_emitter.c +++ b/ext/psych/psych_emitter.c @@ -304,11 +304,12 @@ static VALUE scalar( tag = rb_str_export_to_enc(tag, encoding); } + const char *value_ptr = StringValuePtr(value); yaml_scalar_event_initialize( &event, (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)), (yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)), - (yaml_char_t*)StringValuePtr(value), + (yaml_char_t*)value_ptr, (int)RSTRING_LEN(value), plain ? 1 : 0, quoted ? 1 : 0, @@ -586,4 +587,3 @@ void Init_psych_emitter(void) id_indentation = rb_intern("indentation"); id_canonical = rb_intern("canonical"); } -/* vim: set noet sws=4 sw=4: */ diff --git a/ext/psych/psych_parser.c b/ext/psych/psych_parser.c index 26e2d41e06..00a2207b58 100644 --- a/ext/psych/psych_parser.c +++ b/ext/psych/psych_parser.c @@ -32,9 +32,20 @@ static int io_reader(void * data, unsigned char *buf, size_t size, size_t *read) *read = 0; if(! NIL_P(string)) { - void * str = (void *)StringValuePtr(string); - *read = (size_t)RSTRING_LEN(string); - memcpy(buf, str, *read); + char * str = StringValuePtr(string); + size_t len = (size_t)RSTRING_LEN(string); + + /* IO#read(size) is documented to return at most `size` bytes, but a + * misbehaving IO-like object may return more. Clamp the copy to the + * buffer libyaml gave us to avoid writing past its end, rounding down + * to a character boundary so a multibyte character is never split. */ + if(len > size) { + rb_encoding * enc = rb_enc_get(string); + len = (size_t)(rb_enc_left_char_head(str, str + size, str + len, enc) - str); + } + + *read = len; + memcpy(buf, str, len); } return 1; @@ -562,4 +573,3 @@ void Init_psych_parser(void) id_end_mapping = rb_intern("end_mapping"); id_event_location = rb_intern("event_location"); } -/* vim: set noet sws=4 sw=4: */ diff --git a/ext/psych/psych_to_ruby.c b/ext/psych/psych_to_ruby.c index b388ff7754..3ab0138b52 100644 --- a/ext/psych/psych_to_ruby.c +++ b/ext/psych/psych_to_ruby.c @@ -10,7 +10,11 @@ static VALUE build_exception(VALUE self, VALUE klass, VALUE mesg) { VALUE e = rb_obj_alloc(klass); +#ifdef TRUFFLERUBY + rb_exc_set_message(e, mesg); +#else rb_iv_set(e, "mesg", mesg); +#endif return e; } @@ -36,4 +40,3 @@ void Init_psych_to_ruby(void) rb_define_private_method(cPsychVisitorsToRuby, "build_exception", build_exception, 2); rb_define_private_method(class_loader, "path2class", path2class, 1); } -/* vim: set noet sws=4 sw=4: */ diff --git a/ext/psych/psych_yaml_tree.c b/ext/psych/psych_yaml_tree.c index 225655d127..bbd93f874d 100644 --- a/ext/psych/psych_yaml_tree.c +++ b/ext/psych/psych_yaml_tree.c @@ -9,4 +9,3 @@ void Init_psych_yaml_tree(void) VALUE visitor = rb_define_class_under(visitors, "Visitor", rb_cObject); cPsychVisitorsYamlTree = rb_define_class_under(visitors, "YAMLTree", visitor); } -/* vim: set noet sws=4 sw=4: */ |
