[Bug #19242] Prohibit circular causes to be loaded
This commit is contained in:
parent
18ba89093a
commit
2e7e153a2a
Notes:
git
2022-12-20 05:13:10 +00:00
4
error.c
4
error.c
@ -2959,6 +2959,8 @@ ivar_copy_i(st_data_t key, st_data_t val, st_data_t exc)
|
|||||||
return ST_CONTINUE;
|
return ST_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rb_exc_check_circular_cause(VALUE exc);
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
exception_loader(VALUE exc, VALUE obj)
|
exception_loader(VALUE exc, VALUE obj)
|
||||||
{
|
{
|
||||||
@ -2973,6 +2975,8 @@ exception_loader(VALUE exc, VALUE obj)
|
|||||||
|
|
||||||
rb_ivar_foreach(obj, ivar_copy_i, exc);
|
rb_ivar_foreach(obj, ivar_copy_i, exc);
|
||||||
|
|
||||||
|
rb_exc_check_circular_cause(exc);
|
||||||
|
|
||||||
if (rb_attr_get(exc, id_bt) == rb_attr_get(exc, id_bt_locations)) {
|
if (rb_attr_get(exc, id_bt) == rb_attr_get(exc, id_bt_locations)) {
|
||||||
rb_ivar_set(exc, id_bt_locations, Qnil);
|
rb_ivar_set(exc, id_bt_locations, Qnil);
|
||||||
}
|
}
|
||||||
|
4
eval.c
4
eval.c
@ -537,12 +537,16 @@ exc_setup_message(const rb_execution_context_t *ec, VALUE mesg, VALUE *cause)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!nocircular && !NIL_P(*cause) && !UNDEF_P(*cause) && *cause != mesg) {
|
if (!nocircular && !NIL_P(*cause) && !UNDEF_P(*cause) && *cause != mesg) {
|
||||||
|
#if 0 /* maybe critical for some cases */
|
||||||
|
rb_exc_check_circular_cause(*cause);
|
||||||
|
#else
|
||||||
VALUE c = *cause;
|
VALUE c = *cause;
|
||||||
while (!NIL_P(c = rb_attr_get(c, id_cause))) {
|
while (!NIL_P(c = rb_attr_get(c, id_cause))) {
|
||||||
if (c == mesg) {
|
if (c == mesg) {
|
||||||
rb_raise(rb_eArgError, "circular causes");
|
rb_raise(rb_eArgError, "circular causes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return mesg;
|
return mesg;
|
||||||
}
|
}
|
||||||
|
11
eval_error.c
11
eval_error.c
@ -290,6 +290,17 @@ show_cause(VALUE errinfo, VALUE str, VALUE opt, VALUE highlight, VALUE reverse,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_exc_check_circular_cause(VALUE exc)
|
||||||
|
{
|
||||||
|
VALUE cause = exc, shown_causes = 0;
|
||||||
|
do {
|
||||||
|
if (shown_cause_p(cause, &shown_causes)) {
|
||||||
|
rb_raise(rb_eArgError, "circular causes");
|
||||||
|
}
|
||||||
|
} while (!NIL_P(cause = rb_attr_get(cause, id_cause)));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_error_write(VALUE errinfo, VALUE emesg, VALUE errat, VALUE str, VALUE opt, VALUE highlight, VALUE reverse)
|
rb_error_write(VALUE errinfo, VALUE emesg, VALUE errat, VALUE str, VALUE opt, VALUE highlight, VALUE reverse)
|
||||||
{
|
{
|
||||||
|
@ -1412,6 +1412,18 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
|
|||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_marshal_circular_cause
|
||||||
|
begin
|
||||||
|
raise RuntimeError, "err", [], cause: Exception.new
|
||||||
|
rescue => e
|
||||||
|
end
|
||||||
|
dump = Marshal.dump(e).sub(/o:\x0EException\x08;.0;.0;.0/, "@\x05")
|
||||||
|
assert_raise_with_message(ArgumentError, /circular cause/, ->{dump.inspect}) do
|
||||||
|
e = Marshal.load(dump)
|
||||||
|
assert_same(e, e.cause)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_super_in_method_missing
|
def test_super_in_method_missing
|
||||||
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
|
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
|
||||||
begin;
|
begin;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user