hash.c: add recursion detection to prevent SystemStackError; fix #5531

Add generalized recursion detection system and integrate it into Hash#==
and Hash#eql? to prevent infinite recursion with mutually recursive hash
structures. Uses call stack inspection for minimal memory overhead.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-07-07 13:23:00 +09:00
parent 96355f33b2
commit 419c8ebfb2
3 changed files with 47 additions and 0 deletions
+12
View File
@@ -1303,6 +1303,18 @@ MRB_API mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
/* mrb_cmp(mrb, obj1, obj2): 1:0:-1; -2 for error */
MRB_API mrb_int mrb_cmp(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
/* recursion detection */
MRB_API mrb_bool mrb_recursive_method_p(mrb_state *mrb, mrb_sym mid, mrb_value obj1, mrb_value obj2);
#define MRB_RECURSIVE_P(mrb, mid, obj1, obj2) \
mrb_recursive_method_p(mrb, mid, obj1, obj2)
#define MRB_RECURSIVE_UNARY_P(mrb, mid, obj) \
mrb_recursive_method_p(mrb, mid, obj, mrb_nil_value())
#define MRB_RECURSIVE_BINARY_P(mrb, mid, obj1, obj2) \
mrb_recursive_method_p(mrb, mid, obj1, obj2)
#define mrb_gc_arena_save(mrb) ((mrb)->gc.arena_idx)
#define mrb_gc_arena_restore(mrb, idx) ((mrb)->gc.arena_idx = (idx))