From 26a1064d99c854033b7cd06cca43b28fb71c063c Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 12 Jan 2026 17:57:22 +0900 Subject: [PATCH] mruby-bigint: fix memory leak in mpz_mul_all_ones Add MRB_TRY/MRB_CATCH to ensure local mpz_t variables are freed when an exception (e.g., RangeError from shift overflow) occurs during the all-ones multiplication optimization. Co-authored-by: Claude --- mrbgems/mruby-bigint/core/bigint.c | 79 +++++++++++++++++------------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/mrbgems/mruby-bigint/core/bigint.c b/mrbgems/mruby-bigint/core/bigint.c index 526de9e20..b9236ebc1 100644 --- a/mrbgems/mruby-bigint/core/bigint.c +++ b/mrbgems/mruby-bigint/core/bigint.c @@ -1460,50 +1460,63 @@ mpz_mul_sparse(mpz_ctx_t *ctx, mpz_t *w, mpz_t *sparse, mpz_t *dense) static void mpz_mul_all_ones(mpz_ctx_t *ctx, mpz_t *w, size_t n, size_t m) { - mpz_t a; + struct mrb_jmpbuf *prev_jmp = ctx->mrb->jmp; + struct mrb_jmpbuf c_jmp; + mpz_t a = {0, 0, 0}; + mpz_t b = {0, 0, 0}; - if (n == m) { - /* Squaring: (2^n - 1)^2 = 2^(2n) - 2^(n+1) + 1 */ - /* Start with 2^(2n) */ - mpz_init(ctx, &a); - mpz_set_int(ctx, &a, 1); - mpz_mul_2exp(ctx, w, &a, 2*n); + MRB_TRY(&c_jmp) { + ctx->mrb->jmp = &c_jmp; - /* Subtract 2^(n+1) */ - mpz_set_int(ctx, &a, 1); - mpz_mul_2exp(ctx, &a, &a, n+1); - mpz_sub(ctx, w, w, &a); + if (n == m) { + /* Squaring: (2^n - 1)^2 = 2^(2n) - 2^(n+1) + 1 */ + /* Start with 2^(2n) */ + mpz_init(ctx, &a); + mpz_set_int(ctx, &a, 1); + mpz_mul_2exp(ctx, w, &a, 2*n); - /* Add 1 */ - mpz_add_int(ctx, w, 1); - mpz_clear(ctx, &a); - } - else { - /* General: (2^n - 1) * (2^m - 1) = 2^(n+m) - 2^n - 2^m + 1 */ - mpz_t b; - mpz_init(ctx, &a); - mpz_init(ctx, &b); + /* Subtract 2^(n+1) */ + mpz_set_int(ctx, &a, 1); + mpz_mul_2exp(ctx, &a, &a, n+1); + mpz_sub(ctx, w, w, &a); - /* Start with 2^(n+m) */ - mpz_set_int(ctx, &a, 1); - mpz_mul_2exp(ctx, w, &a, n+m); + /* Add 1 */ + mpz_add_int(ctx, w, 1); + } + else { + /* General: (2^n - 1) * (2^m - 1) = 2^(n+m) - 2^n - 2^m + 1 */ + mpz_init(ctx, &a); + mpz_init(ctx, &b); - /* Subtract 2^n */ - mpz_set_int(ctx, &a, 1); - mpz_mul_2exp(ctx, &a, &a, n); - mpz_sub(ctx, w, w, &a); + /* Start with 2^(n+m) */ + mpz_set_int(ctx, &a, 1); + mpz_mul_2exp(ctx, w, &a, n+m); - /* Subtract 2^m */ - mpz_set_int(ctx, &b, 1); - mpz_mul_2exp(ctx, &b, &b, m); - mpz_sub(ctx, w, w, &b); + /* Subtract 2^n */ + mpz_set_int(ctx, &a, 1); + mpz_mul_2exp(ctx, &a, &a, n); + mpz_sub(ctx, w, w, &a); - /* Add 1 */ - mpz_add_int(ctx, w, 1); + /* Subtract 2^m */ + mpz_set_int(ctx, &b, 1); + mpz_mul_2exp(ctx, &b, &b, m); + mpz_sub(ctx, w, w, &b); + /* Add 1 */ + mpz_add_int(ctx, w, 1); + } + + ctx->mrb->jmp = prev_jmp; mpz_clear(ctx, &a); mpz_clear(ctx, &b); } + MRB_CATCH(&c_jmp) { + ctx->mrb->jmp = prev_jmp; + mpz_clear(ctx, &a); + mpz_clear(ctx, &b); + MRB_THROW(ctx->mrb->jmp); + } + MRB_END_EXC(&c_jmp); } /* w = u^2 (squaring - faster than general multiplication) */