From f69fe329a90c0d1f5d5366a7da9631b8a27eda47 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 13 Oct 2025 09:19:28 +0900 Subject: [PATCH] mruby-bigint: fix mrb_bint_copy to properly clone bigints mrb_bint_copy was creating reference to destination then destroying it with mpz_init, causing copy to happen in orphaned memory. this made clone return 0 instead of copying the bigint value. fix extracts common mpz_t-to-rbigint transfer logic into bint_set helper, used by both bint_new and mrb_bint_copy. eliminates code duplication and properly copies source data to destination rbigint structure, handling both embedded and heap storage cases. Co-authored-by: Claude --- mrbgems/mruby-bigint/core/bigint.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/mrbgems/mruby-bigint/core/bigint.c b/mrbgems/mruby-bigint/core/bigint.c index abb5d901f..cf5aae732 100644 --- a/mrbgems/mruby-bigint/core/bigint.c +++ b/mrbgems/mruby-bigint/core/bigint.c @@ -2749,10 +2749,10 @@ bint_as_mpz(struct RBigint *b, mpz_t *x) x->sn = RBIGINT_SIGN(b); } -static struct RBigint* -bint_new(mpz_ctx_t *ctx, mpz_t *x) +/* Transfer mpz_t data to RBigint structure */ +static void +bint_set(mpz_ctx_t *ctx, struct RBigint *b, mpz_t *x) { - struct RBigint *b = MRB_OBJ_ALLOC(MPZ_MRB(ctx), MRB_TT_BIGINT, MPZ_MRB(ctx)->integer_class); if (x->sz <= RBIGINT_EMBED_SIZE_MAX) { RBIGINT_SET_EMBED_SIZE(b, x->sz); RBIGINT_SET_EMBED_SIGN(b, x->sn); @@ -2769,6 +2769,13 @@ bint_new(mpz_ctx_t *ctx, mpz_t *x) RBIGINT_SET_HEAP(b); mpz_move(ctx, &b->as.heap, x); } +} + +static struct RBigint* +bint_new(mpz_ctx_t *ctx, mpz_t *x) +{ + struct RBigint *b = MRB_OBJ_ALLOC(MPZ_MRB(ctx), MRB_TT_BIGINT, MPZ_MRB(ctx)->integer_class); + bint_set(ctx, b, x); return b; } @@ -3540,12 +3547,12 @@ mrb_bint_rshift(mrb_state *mrb, mrb_value x, mrb_int width) void mrb_bint_copy(mrb_state *mrb, mrb_value x, mrb_value y) { - mpz_t a, b; + mpz_t b, temp; MPZ_CTX_INIT(mrb, ctx, pool); - bint_as_mpz(RBIGINT(x), &a); bint_as_mpz(RBIGINT(y), &b); - mpz_init_set(ctx, &a, &b); + mpz_init_set(ctx, &temp, &b); + bint_set(ctx, RBIGINT(x), &temp); } size_t