Skip to content

Marshal.load corrupts repeated object reference after Set appears earlier in payload #9405

Description

@hmdne

Environment Information

JRuby:

$ jruby -v
jruby 10.1.0.0 (4.0.0) 2026-04-20 32f988b78c OpenJDK 64-Bit Server VM 26+35 on 26+35 +indy +jit [x86_64-linux]

MRI comparison:

ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [x86_64-linux]

Expected Behavior

Marshal.load(Marshal.dump(obj)) should preserve repeated object references correctly. In the script below, loaded[2] should be "good".

Repro:

require 'set'

shared = 'good'
payload = [
  Set.new,
  ['bad', shared],
  shared,
]

loaded = Marshal.load(Marshal.dump(payload))

puts RUBY_DESCRIPTION
puts "expected: good"
puts "actual:   #{loaded[2].inspect}"
puts "ok: #{loaded[2] == 'good'}"

MRI output:

ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [x86_64-linux]
expected: good
actual:   "good"
ok: true

Actual Behavior

JRuby 10.1.0.0 output:

jruby 10.1.0.0 (4.0.0) 2026-04-20 32f988b78c OpenJDK 64-Bit Server VM 26+35 on 26+35 +indy +jit [x86_64-linux]
expected: good
actual:   "bad"
ok: false

The third element of the top-level array becomes "bad" after the Marshal roundtrip. It should remain the same string object/value as shared, i.e. "good".

Some narrowing observations:

  • No threading is involved.
  • The issue reproduces with plain Marshal.dump / Marshal.load.
  • Replacing Set.new with [] or {} avoids the problem.
  • Using shared.dup for the third payload element avoids the problem.
  • The failure seems to require a Set appearing before a nested array containing a shared string object that is referenced again later.

This was found while debugging Opal's compiler cache on JRuby 10.1.0.0 (a regression since JRuby 10.0.2.0), where a cached compiler's generated JavaScript string was replaced by a source-map mappings string after a Marshal roundtrip.

Ref: opal/opal#2787

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions