Merge pull request #6876 from dkgkdfg65/backport/7dfd560d-stable

[stable] backport: cap IO#puts recursion depth on cyclic arrays (mruby-io)
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-05-31 08:18:35 +09:00
committed by GitHub
+13 -3
View File
@@ -992,10 +992,20 @@ io_puts_str(mrb_state *mrb, int fd, mrb_value str)
}
}
/* Maximum nesting depth for puts with arrays; guards against cyclic and
pathologically deep arrays causing C stack overflow. */
#define IO_PUTS_MAX_DEPTH 16
/* Recursive helper for puts with arrays */
static void
io_puts_ary(mrb_state *mrb, int fd, mrb_value ary)
io_puts_ary(mrb_state *mrb, int fd, mrb_value ary, int depth)
{
if (depth >= IO_PUTS_MAX_DEPTH) {
mrb_value mark = mrb_str_new_lit(mrb, "[...]\n");
fd_write(mrb, fd, mark);
return;
}
mrb_int len = RARRAY_LEN(ary);
if (len == 0) {
@@ -1008,7 +1018,7 @@ io_puts_ary(mrb_state *mrb, int fd, mrb_value ary)
for (mrb_int i = 0; i < len; i++) {
mrb_value elem = RARRAY_PTR(ary)[i];
if (mrb_array_p(elem)) {
io_puts_ary(mrb, fd, elem); /* Recursive call for nested arrays */
io_puts_ary(mrb, fd, elem, depth + 1);
}
else {
io_puts_str(mrb, fd, elem);
@@ -1040,7 +1050,7 @@ io_puts(mrb_state *mrb, mrb_value io)
for (mrb_int i = 0; i < argc; i++) {
mrb_value arg = argv[i];
if (mrb_array_p(arg)) {
io_puts_ary(mrb, fd, arg);
io_puts_ary(mrb, fd, arg, 0);
}
else {
io_puts_str(mrb, fd, arg);