mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
error.c: avoid infinite recursion at inspecting the frozen object
This commit is contained in:
parent
b2fe7484e7
commit
1624d77f3e
2 changed files with 35 additions and 7 deletions
27
error.c
27
error.c
|
@ -2887,24 +2887,37 @@ rb_frozen_error_raise(VALUE frozen_obj, const char *fmt, ...)
|
|||
rb_exc_raise(exc);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
inspect_frozen_obj(VALUE obj, VALUE mesg, int recur)
|
||||
{
|
||||
if (recur) {
|
||||
rb_str_cat_cstr(mesg, " ...");
|
||||
}
|
||||
else {
|
||||
rb_str_append(mesg, rb_inspect(obj));
|
||||
}
|
||||
return mesg;
|
||||
}
|
||||
|
||||
void
|
||||
rb_error_frozen_object(VALUE frozen_obj)
|
||||
{
|
||||
VALUE debug_info;
|
||||
const ID created_info = id_debug_created_info;
|
||||
VALUE mesg = rb_sprintf("can't modify frozen %"PRIsVALUE": ",
|
||||
CLASS_OF(frozen_obj));
|
||||
VALUE exc = rb_exc_new_str(rb_eFrozenError, mesg);
|
||||
|
||||
rb_ivar_set(exc, id_recv, frozen_obj);
|
||||
rb_exec_recursive(inspect_frozen_obj, frozen_obj, mesg);
|
||||
|
||||
if (!NIL_P(debug_info = rb_attr_get(frozen_obj, created_info))) {
|
||||
VALUE path = rb_ary_entry(debug_info, 0);
|
||||
VALUE line = rb_ary_entry(debug_info, 1);
|
||||
|
||||
rb_frozen_error_raise(frozen_obj,
|
||||
"can't modify frozen %"PRIsVALUE": %"PRIsVALUE", created at %"PRIsVALUE":%"PRIsVALUE,
|
||||
CLASS_OF(frozen_obj), rb_inspect(frozen_obj), path, line);
|
||||
}
|
||||
else {
|
||||
rb_frozen_error_raise(frozen_obj, "can't modify frozen %"PRIsVALUE": %"PRIsVALUE,
|
||||
CLASS_OF(frozen_obj), rb_inspect(frozen_obj));
|
||||
rb_str_catf(mesg, ", created at %"PRIsVALUE":%"PRIsVALUE, path, line);
|
||||
}
|
||||
rb_exc_raise(exc);
|
||||
}
|
||||
|
||||
#undef rb_check_frozen
|
||||
|
|
|
@ -886,6 +886,21 @@ end.join
|
|||
obj.instance_variable_set(:@test, true)
|
||||
}
|
||||
assert_include(e.message, obj.inspect)
|
||||
|
||||
klass = Class.new do
|
||||
def init
|
||||
@x = true
|
||||
end
|
||||
def inspect
|
||||
init
|
||||
super
|
||||
end
|
||||
end
|
||||
obj = klass.new.freeze
|
||||
e = assert_raise_with_message(FrozenError, /can't modify frozen #{obj.class}/) {
|
||||
obj.init
|
||||
}
|
||||
assert_include(e.message, klass.inspect)
|
||||
end
|
||||
|
||||
def test_name_error_new_default
|
||||
|
|
Loading…
Add table
Reference in a new issue