[ruby-core:114412] [Ruby master Bug#19841] Marshal.dump stack overflow with recursive Time
From:
"byroot (Jean Boussier) via ruby-core" <ruby-core@...>
Date:
2023-08-19 08:21:17 UTC
List:
ruby-core #114412
Issue #19841 has been updated by byroot (Jean Boussier).
Hum, this is tricky.
`Time` implements `_dump`, so we enter this branch:
```c
if (rb_obj_respond_to(obj, s_dump, TRUE)) {
VALUE ivobj2 = Qundef;
st_index_t hasiv2;
VALUE encname2;
v = INT2NUM(limit);
v = dump_funcall(arg, obj, s_dump, 1, &v);
if (!RB_TYPE_P(v, T_STRING)) {
rb_raise(rb_eTypeError, "_dump() must return string");
}
hasiv = has_ivars(obj, (encname = encoding_name(obj, arg)), &ivobj);
hasiv2 = has_ivars(v, (encname2 = encoding_name(v, arg)), &ivobj2);
if (hasiv2) {
hasiv = hasiv2;
ivobj = ivobj2;
encname = encname2;
}
if (hasiv) w_byte(TYPE_IVAR, arg);
w_class(TYPE_USERDEF, obj, arg, FALSE);
w_bytes(RSTRING_PTR(v), RSTRING_LEN(v), arg);
if (hasiv) {
w_ivar(hasiv, ivobj, encname, &c_arg);
}
w_remember(obj, arg);
return;
}
```
`w_remember` is what takes care of circular references, and it's explicitly called at the end, contrary to other types where it's called as early as possible.
Calling it sooner fixes this specific issue, but cause the format to change and some other tests to fail. I'll dig more, but I fear we may not be able to fix it without breaking the format.
----------------------------------------
Bug #19841: Marshal.dump stack overflow with recursive Time
https://bugs.ruby-lang.org/issues/19841#change-104161
* Author: segiddins (Samuel Giddins)
* Status: Open
* Priority: Normal
* ruby -v: 3.2.2
* Backport: 3.0: WONTFIX, 3.1: REQUIRED, 3.2: REQUIRED
----------------------------------------
``` ruby
#!/usr/bin/env ruby
puts RUBY_VERSION
t = Time.at(0, 1, :nanosecond)
t.instance_variable_set :@itself, t
Marshal.dump(t)
```
Yields a stack overflow error from the `Marshal.dump` call, even though Marshal is explicitly able to handle cyclical references
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- [email protected]
To unsubscribe send an email to [email protected]
ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/