From 2993302b8a0531086a153bcd7b4bd8c7626f4383 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 18 Nov 2025 21:50:34 +0900 Subject: [PATCH] mruby-pack: fix buffer overflow in pack_uu encoding fix buffer size calculation for UU-encoding to account for per-line padding. each line encodes separately, causing additional padding when line length is not divisible by 3. the previous calculation treated all input as one block, underestimating the required buffer size when using small count values. Co-authored-by: Claude --- mrbgems/mruby-pack/src/pack.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/mrbgems/mruby-pack/src/pack.c b/mrbgems/mruby-pack/src/pack.c index f3fbcc3d1..09f5084d6 100644 --- a/mrbgems/mruby-pack/src/pack.c +++ b/mrbgems/mruby-pack/src/pack.c @@ -1478,7 +1478,23 @@ pack_uu(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count) if (count <= 1) count = 45; /* default line length for UU-encoding */ - str_len_ensure(mrb, dst, didx + ((slen * 4 + 2) / 3) + (slen / count + 1) * 2); + /* Calculate buffer size by accounting for per-line encoding + * Each line encodes separately, so padding happens per line, not globally + */ + mrb_int num_lines = (slen + count - 1) / count; /* Number of lines */ + mrb_int total_encoded = 0; + mrb_int temp_slen = slen; + + /* Calculate actual encoded size line by line */ + while (temp_slen > 0) { + mrb_int line_len = (temp_slen > count) ? count : temp_slen; + total_encoded += ((line_len + 2) / 3) * 4; /* Each line's encoded size */ + temp_slen -= line_len; + } + + /* Total buffer = encoded data + (length char + newline) per line + terminating line */ + mrb_int buffer_size = total_encoded + num_lines * 2 + 2; + str_len_ensure(mrb, dst, didx + buffer_size); char *dptr = RSTRING_PTR(dst) + didx; while (slen > 0) {