Incorrect deserialization of some instances serialized by version 0.2.0
Nobody has claimed this yet.
- Dominant language
- Ruby
- Stars
- 175
- Forks
- 35
- Avg merge
- 16h 14m
- Merged PRs (30d)
- 1
Description
In the ruby 2 version of OpenStruct, serialized objects can have two root keys: table and modifiable. The second key only seems to appear after an attribute is assigned post-initialization:
irb(main):012:0> OpenStruct::VERSION
=> "0.2.0"
irb(main):013:0> RUBY_VERSION
=> "2.7.5"
irb(main):014:0> s = OpenStruct.new(foo: 1, bar: 'baz')
=> #<OpenStruct foo=1, bar="baz">
irb(main):015:0> Psych.dump s
=> "--- !ruby/object:OpenStruct\ntable:\n :foo: 1\n :bar: baz\n"
irb(main):017:0> s.bar = 'baz'
=> "baz"
irb(main):019:0> Psych.dump s
=> "--- !ruby/object:OpenStruct\ntable:\n :foo: 1\n :bar: baz\nmodifiable: true\n"
On newer versions of OpenStruct, serialized objects with that key are not deserialized as expected:
irb(main):010:0> OpenStruct::VERSION
=> "0.3.1"
irb(main):011:0> RUBY_VERSION
=> "3.0.5"
irb(main):012:0> s = Psych.load "--- !ruby/object:OpenStruct\ntable:\n :foo: 1\n :bar: baz\nmodifiable: true\n"
=> #<OpenStruct table={:foo=>1, :bar=>"baz"}, modifiable=true>
irb(main):013:0> s.foo
=> nil
The deserialization hook provided by OpenStruct attempts to be backwards compatible, but incorrectly assumes that legacy documents have exactly one root-level key table:
https://github.com/ruby/ostruct/blob/master/lib/ostruct.rb#L449-L454
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in lib/ostruct.rb around lines 449-454, where the deserialization hook handles legacy documents. Reproduce the issue with the provided Psych.load data and inspect how both root-level keys are interpreted. Done means the serialized object restores foo and bar as attributes without exposing table or modifiable as attributes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ruby
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100