Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ jobs:
- name: Run test
id: test
run: rake
continue-on-error: ${{ matrix.ruby == 'jruby-head' }}
- name: Install gem
run: rake install
if: ${{ steps.test.outcome == 'success' }}
Expand Down
7 changes: 0 additions & 7 deletions ext/psych/psych_to_ruby.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,6 @@ static VALUE path2class(VALUE self, VALUE path)
return rb_path_to_class(path);
}

static VALUE init_data(VALUE self, VALUE data, VALUE values)
{
rb_struct_initialize(data, values);
return data;
}

void Init_psych_to_ruby(void)
{
VALUE psych = rb_define_module("Psych");
Expand All @@ -43,7 +37,6 @@ void Init_psych_to_ruby(void)
VALUE visitor = rb_define_class_under(visitors, "Visitor", rb_cObject);
cPsychVisitorsToRuby = rb_define_class_under(visitors, "ToRuby", visitor);

rb_define_private_method(cPsychVisitorsToRuby, "init_data", init_data, 2);
rb_define_private_method(cPsychVisitorsToRuby, "build_exception", build_exception, 2);
rb_define_private_method(class_loader, "path2class", path2class, 1);
}
7 changes: 5 additions & 2 deletions lib/psych/visitors/to_ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ module Visitors
###
# This class walks a YAML AST, converting each node to Ruby
class ToRuby < Psych::Visitors::Visitor
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, parse_symbols: parse_symbols
Expand Down Expand Up @@ -219,8 +223,7 @@ def visit_Psych_Nodes_Mapping o
revive_data_members(members, o)
end
data ||= allocate_anon_data(o, members)
values = data.members.map { |m| members[m] }
init_data(data, values)
DATA_INITIALIZE.bind_call(data, **members)
data.freeze
data

Expand Down
25 changes: 25 additions & 0 deletions test/psych/test_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,31 @@ def test_load
assert_equal "hello", obj.bar
assert_equal "bar", obj.foo
end

def test_members_must_be_identical
TestData.const_set :D, Data.define(:a, :b)
d = Psych.dump(TestData::D.new(1, 2))

# more members
TestData.send :remove_const, :D
TestData.const_set :D, Data.define(:a, :b, :c)
e = assert_raise(ArgumentError) { Psych.unsafe_load d }
assert_equal 'missing keyword: :c', e.message

# less members
TestData.send :remove_const, :D
TestData.const_set :D, Data.define(:a)
e = assert_raise(ArgumentError) { Psych.unsafe_load d }
assert_equal 'unknown keyword: :b', e.message

# completely different members
TestData.send :remove_const, :D
TestData.const_set :D, Data.define(:foo, :bar)
e = assert_raise(ArgumentError) { Psych.unsafe_load d }
assert_equal 'unknown keywords: :a, :b', e.message
ensure
TestData.send :remove_const, :D
end
end
end