GitHub

@@ -455,6 +455,12 @@ ary_subtract_internal(mrb_state *mrb, mrb_value self, mrb_int argc, const mrb_va

455455

mrb_value result = mrb_ary_new(mrb);

456456457457

if (total_len > SET_OP_HASH_THRESHOLD) {

458+

/* Create shared copies to protect elements during khash operations */

459+

mrb_value *argv_copies = (mrb_value *)mrb_alloca(mrb, sizeof(mrb_value) * argc);

460+

for (mrb_int i = 0; i < argc; i++) {

461+

argv_copies[i] = mrb_ary_make_shared_copy(mrb, argv[i]);

462+

}

463+458464

ary_set_t set_struct;

459465

ary_set_t *set = &set_struct;

460466

ary_init_temp_set(mrb, set, total_len);

@@ -465,7 +471,7 @@ ary_subtract_internal(mrb_state *mrb, mrb_value self, mrb_int argc, const mrb_va

465471

MRB_TRY(&c_jmp) {

466472

mrb->jmp = &c_jmp;

467473

for (mrb_int i = 0; i < argc; i++) {

468-

ary_populate_temp_set(mrb, set, argv[i]);

474+

ary_populate_temp_set(mrb, set, argv_copies[i]);

469475

}

470476471477

for (mrb_int i = 0; i < RARRAY_LEN(self); i++) {

@@ -568,6 +574,13 @@ ary_union_internal(mrb_state *mrb, mrb_value self, mrb_int argc, const mrb_value

568574

mrb_value result = mrb_ary_new(mrb);

569575570576

if (total_len > SET_OP_HASH_THRESHOLD) {

577+

/* Create shared copies to protect elements during khash operations */

578+

mrb_value self_copy = mrb_ary_make_shared_copy(mrb, self);

579+

mrb_value *argv_copies = (mrb_value *)mrb_alloca(mrb, sizeof(mrb_value) * argc);

580+

for (mrb_int i = 0; i < argc; i++) {

581+

argv_copies[i] = mrb_ary_make_shared_copy(mrb, argv[i]);

582+

}

583+571584

ary_set_t set_struct;

572585

ary_set_t *set = &set_struct;

573586

ary_init_temp_set(mrb, set, total_len);

@@ -578,8 +591,8 @@ ary_union_internal(mrb_state *mrb, mrb_value self, mrb_int argc, const mrb_value

578591

MRB_TRY(&c_jmp) {

579592

mrb->jmp = &c_jmp;

580593

/* Add unique elements from self */

581-

for (mrb_int i = 0; i < RARRAY_LEN(self); i++) {

582-

mrb_value elem = RARRAY_PTR(self)[i];

594+

for (mrb_int i = 0; i < RARRAY_LEN(self_copy); i++) {

595+

mrb_value elem = RARRAY_PTR(self_copy)[i];

583596

khiter_t k = kh_get(ary_set, mrb, set, elem);

584597

if (kh_is_end(set, k)) {

585598

kh_put(ary_set, mrb, set, elem);

@@ -589,7 +602,7 @@ ary_union_internal(mrb_state *mrb, mrb_value self, mrb_int argc, const mrb_value

589602590603

/* Add unique elements from others */

591604

for (mrb_int i = 0; i < argc; i++) {

592-

mrb_value other = argv[i];

605+

mrb_value other = argv_copies[i];

593606

for (mrb_int j = 0; j < RARRAY_LEN(other); j++) {

594607

mrb_value elem = RARRAY_PTR(other)[j];

595608

khiter_t k = kh_get(ary_set, mrb, set, elem);

@@ -681,6 +694,12 @@ ary_intersection_internal(mrb_state *mrb, mrb_value self, mrb_int argc, const mr

681694

mrb_value result = mrb_ary_new(mrb);

682695683696

if (total_len > SET_OP_HASH_THRESHOLD) {

697+

/* Create shared copies to protect elements during khash operations */

698+

mrb_value *argv_copies = (mrb_value *)mrb_alloca(mrb, sizeof(mrb_value) * argc);

699+

for (mrb_int i = 0; i < argc; i++) {

700+

argv_copies[i] = mrb_ary_make_shared_copy(mrb, argv[i]);

701+

}

702+684703

ary_set_t set_struct;

685704

ary_set_t *set = &set_struct;

686705

ary_init_temp_set(mrb, set, total_len);

@@ -691,7 +710,7 @@ ary_intersection_internal(mrb_state *mrb, mrb_value self, mrb_int argc, const mr

691710

MRB_TRY(&c_jmp) {

692711

mrb->jmp = &c_jmp;

693712

for (mrb_int i = 0; i < argc; i++) {

694-

ary_populate_temp_set(mrb, set, argv[i]);

713+

ary_populate_temp_set(mrb, set, argv_copies[i]);

695714

}

696715697716

for (mrb_int i = 0; i < RARRAY_LEN(self); i++) {

@@ -824,17 +843,19 @@ ary_intersect_p(mrb_state *mrb, mrb_value self)

824843

}

825844826845

if (RARRAY_LEN(shorter_ary) > SET_OP_HASH_THRESHOLD) {

846+

mrb_value shorter_ary_copy = mrb_ary_make_shared_copy(mrb, shorter_ary);

847+827848

ary_set_t set_struct;

828849

ary_set_t *set = &set_struct;

829-

ary_init_temp_set(mrb, set, RARRAY_LEN(shorter_ary));

850+

ary_init_temp_set(mrb, set, RARRAY_LEN(shorter_ary_copy));

830851831852

struct mrb_jmpbuf *prev_jmp = mrb->jmp;

832853

struct mrb_jmpbuf c_jmp;

833854

mrb_bool found = FALSE;

834855835856

MRB_TRY(&c_jmp) {

836857

mrb->jmp = &c_jmp;

837-

ary_populate_temp_set(mrb, set, shorter_ary);

858+

ary_populate_temp_set(mrb, set, shorter_ary_copy);

838859839860

for (mrb_int i = 0; i < RARRAY_LEN(longer_ary); i++) {

840861

khiter_t k = kh_get(ary_set, mrb, set, RARRAY_PTR(longer_ary)[i]);

@@ -1019,6 +1040,9 @@ ary_uniq_bang(mrb_state *mrb, mrb_value self)

10191040

mrb_int write_pos = 0;

1020104110211042

if (len > SET_OP_HASH_THRESHOLD) {

1043+

/* Create shared copy to protect elements during khash operations */

1044+

mrb_value self_copy = mrb_ary_make_shared_copy(mrb, self);

1045+10221046

ary_set_t set_struct;

10231047

ary_set_t *set = &set_struct;

10241048

ary_init_temp_set(mrb, set, len);

@@ -1028,7 +1052,7 @@ ary_uniq_bang(mrb_state *mrb, mrb_value self)

1028105210291053

MRB_TRY(&c_jmp) {

10301054

mrb->jmp = &c_jmp;

1031-

ary_populate_temp_set(mrb, set, self);

1055+

ary_populate_temp_set(mrb, set, self_copy);

1032105610331057

for (mrb_int read_pos = 0; read_pos < len; read_pos++) {

10341058

mrb_value elem = RARRAY_PTR(self)[read_pos];

Read the original on github.com ↗