From f35000f2a9681a1ada75165e6ad9b92064e9cd0d Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 23 Aug 2024 22:29:45 +0900 Subject: [PATCH] array.c (sort_cmp): comparing objects may be freed by GC; #6326 If comparing function (block or `<=>`) modifies the sorting array and GC happens after the modification, objects passed to comparison may be freed by GC. --- src/array.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/array.c b/src/array.c index 42f06987d..b59a077e7 100644 --- a/src/array.c +++ b/src/array.c @@ -1586,15 +1586,14 @@ static mrb_bool sort_cmp(mrb_state *mrb, mrb_value ary, mrb_value *p, mrb_int a, mrb_int b, mrb_value blk) { mrb_int cmp; - mrb_value va = p[a], vb = p[b]; if (mrb_nil_p(blk)) { - cmp = mrb_cmp(mrb, va, vb); + cmp = mrb_cmp(mrb, p[a], p[b]); } else { - mrb_value c = mrb_funcall_id(mrb, blk, MRB_SYM(call), 2, va, vb); + mrb_value c = mrb_funcall_id(mrb, blk, MRB_SYM(call), 2, p[a], p[b]); if (mrb_nil_p(c) || !mrb_fixnum_p(c)) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "comparison of %!v and %!v failed", va, vb); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "comparison failed (element %d and %d)", a, b); } cmp = mrb_fixnum(c); }