From 5eca2fae1ee5be31e5978bf357e15f17d523980c Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 30 Dec 2025 14:28:44 +0900 Subject: [PATCH] rational.c: fix undefined behavior from large shift exponents In rational_new_f(), the code performed ((mrb_int)1)<= MRB_INT_BIT. Shifting by a value >= bit width is undefined behavior in C. Also fixed the negative exponent case which incorrectly used deno >>= exp (right-shift by negative is UB). The correct logic is deno <<= -exp to multiply denominator by 2^(-exp). Both cases now check for overflow before shifting and fall back to bigint operations when necessary. Discovered via ClusterFuzz with input "92r**11". Co-authored-by: Claude --- mrbgems/mruby-rational/src/rational.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/mrbgems/mruby-rational/src/rational.c b/mrbgems/mruby-rational/src/rational.c index 9f4475749..fff29b876 100644 --- a/mrbgems/mruby-rational/src/rational.c +++ b/mrbgems/mruby-rational/src/rational.c @@ -342,7 +342,8 @@ rational_new_f(mrb_state *mrb, mrb_float f) if (exp > 0) { mrb_int temp; - if (mrb_int_mul_overflow(nume, ((mrb_int)1)<= MRB_INT_BIT || mrb_int_mul_overflow(nume, ((mrb_int)1)<>= exp; + else if (exp < 0) { + /* exp is negative, so we need to multiply denominator by 2^(-exp) */ + int neg_exp = -exp; + if (neg_exp >= MRB_INT_BIT || mrb_int_mul_overflow(deno, ((mrb_int)1)<