diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index 87e3d6f31..451e360d7 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -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);