mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-set: use kh_is_end() for safe iteration; ref #6664
kh_is_end() safely checks if an iterator is at the end position, preventing issues when the hash table is modified during iteration. replaced direct kset_end() comparisons with kset_is_end() calls throughout set operations. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
+22
-21
@@ -55,6 +55,7 @@ typedef khint_t kset_iter_t;
|
||||
#define kset_key(s, k) kh_key(set_val, s, k)
|
||||
#define kset_size(s) kh_size(s)
|
||||
#define kset_end(s) kh_end(s)
|
||||
#define kset_is_end(s, k) kh_is_end(s, k)
|
||||
|
||||
#define KSET_FOREACH(s, k) KHASH_FOREACH(set_val, s, k)
|
||||
|
||||
@@ -279,7 +280,7 @@ set_include_p(mrb_state *mrb, mrb_value self)
|
||||
kset_t *set = set_get_kset(mrb, self);
|
||||
if (kset_is_empty(set)) return mrb_false_value();
|
||||
|
||||
return mrb_bool_value(kset_get(mrb, set, obj) != kset_end(set));
|
||||
return mrb_bool_value(!kset_is_end(set, kset_get(mrb, set, obj)));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -333,7 +334,7 @@ set_delete(mrb_state *mrb, mrb_value self)
|
||||
if (kset_is_empty(set)) return self;
|
||||
|
||||
kset_iter_t k = kset_get(mrb, set, obj);
|
||||
if (k != kset_end(set)) {
|
||||
if (!kset_is_end(set, k)) {
|
||||
kset_del(mrb, set, k);
|
||||
}
|
||||
return self;
|
||||
@@ -354,7 +355,7 @@ set_delete_p(mrb_state *mrb, mrb_value self)
|
||||
if (kset_is_empty(set)) return mrb_nil_value();
|
||||
|
||||
kset_iter_t k = kset_get(mrb, set, obj);
|
||||
if (k != kset_end(set)) {
|
||||
if (!kset_is_end(set, k)) {
|
||||
kset_del(mrb, set, k);
|
||||
return self;
|
||||
}
|
||||
@@ -410,7 +411,7 @@ set_core_subtract(mrb_state *mrb, mrb_value self)
|
||||
KSET_FOREACH(other_set, k) {
|
||||
mrb_value key = kset_key(other_set, k);
|
||||
kset_iter_t self_k = kset_get(mrb, self_set, key);
|
||||
if (self_k != kset_end(self_set)) {
|
||||
if (!kset_is_end(self_set, self_k)) {
|
||||
kset_del(mrb, self_set, self_k);
|
||||
}
|
||||
}
|
||||
@@ -475,7 +476,7 @@ set_core_difference(mrb_state *mrb, mrb_value self)
|
||||
KSET_FOREACH(other_set, k) {
|
||||
mrb_value key = kset_key(other_set, k);
|
||||
kset_iter_t result_k = kset_get(mrb, result_set, key);
|
||||
if (result_k != kset_end(result_set)) {
|
||||
if (!kset_is_end(result_set, result_k)) {
|
||||
kset_del(mrb, result_set, result_k);
|
||||
}
|
||||
}
|
||||
@@ -513,7 +514,7 @@ set_core_intersection(mrb_state *mrb, mrb_value self)
|
||||
kset_iter_t self_k = kset_get(mrb, self_set, key);
|
||||
|
||||
/* If key exists in self, add it to result */
|
||||
if (self_k != kset_end(self_set)) {
|
||||
if (!kset_is_end(self_set, self_k)) {
|
||||
kset_put(mrb, result_set, key);
|
||||
}
|
||||
}
|
||||
@@ -561,7 +562,7 @@ set_core_xor(mrb_state *mrb, mrb_value self)
|
||||
kset_iter_t other_k = kset_get(mrb, other_set, key);
|
||||
|
||||
/* Add to result if not in other */
|
||||
if (other_k == kset_end(other_set)) {
|
||||
if (kset_is_end(other_set, other_k)) {
|
||||
kset_put(mrb, result_set, key);
|
||||
}
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
@@ -573,7 +574,7 @@ set_core_xor(mrb_state *mrb, mrb_value self)
|
||||
kset_iter_t self_k = kset_get(mrb, self_set, key);
|
||||
|
||||
/* Add to result if not in self */
|
||||
if (self_k == kset_end(self_set)) {
|
||||
if (kset_is_end(self_set, self_k)) {
|
||||
kset_put(mrb, result_set, key);
|
||||
}
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
@@ -626,7 +627,7 @@ set_equal(mrb_state *mrb, mrb_value self)
|
||||
int ai = mrb_gc_arena_save(mrb);
|
||||
KSET_FOREACH(self_set, k) {
|
||||
kset_iter_t k2 = kset_get(mrb, other_set, kset_key(self_set, k));
|
||||
if (k2 == kset_end(other_set)) {
|
||||
if (kset_is_end(other_set, k2)) {
|
||||
return mrb_false_value(); /* Element in self not found in other */
|
||||
}
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
@@ -710,7 +711,7 @@ set_superset_p(mrb_state *mrb, mrb_value self)
|
||||
int ai = mrb_gc_arena_save(mrb);
|
||||
KSET_FOREACH(other_set, k) {
|
||||
kset_iter_t self_k = kset_get(mrb, self_set, kset_key(other_set, k));
|
||||
if (self_k == kset_end(self_set)) {
|
||||
if (kset_is_end(self_set, self_k)) {
|
||||
return mrb_false_value(); /* Element in other not found in self */
|
||||
}
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
@@ -756,7 +757,7 @@ set_proper_superset_p(mrb_state *mrb, mrb_value self)
|
||||
int ai = mrb_gc_arena_save(mrb);
|
||||
KSET_FOREACH(other_set, k) {
|
||||
kset_iter_t self_k = kset_get(mrb, self_set, kset_key(other_set, k));
|
||||
if (self_k == kset_end(self_set)) {
|
||||
if (kset_is_end(self_set, self_k)) {
|
||||
return mrb_false_value(); /* Element in other not found in self */
|
||||
}
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
@@ -801,7 +802,7 @@ set_subset_p(mrb_state *mrb, mrb_value self)
|
||||
int ai = mrb_gc_arena_save(mrb);
|
||||
KSET_FOREACH(self_set, k) {
|
||||
kset_iter_t other_k = kset_get(mrb, other_set, kset_key(self_set, k));
|
||||
if (other_k == kset_end(other_set)) {
|
||||
if (kset_is_end(other_set, other_k)) {
|
||||
return mrb_false_value(); /* Element in self not found in other */
|
||||
}
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
@@ -847,7 +848,7 @@ set_proper_subset_p(mrb_state *mrb, mrb_value self)
|
||||
int ai = mrb_gc_arena_save(mrb);
|
||||
KSET_FOREACH(self_set, k) {
|
||||
kset_iter_t other_k = kset_get(mrb, other_set, kset_key(self_set, k));
|
||||
if (other_k == kset_end(other_set)) {
|
||||
if (kset_is_end(other_set, other_k)) {
|
||||
return mrb_false_value(); /* Element in self not found in other */
|
||||
}
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
@@ -883,7 +884,7 @@ set_intersect_p(mrb_state *mrb, mrb_value self)
|
||||
if (kset_size(self_set) < kset_size(other_set)) {
|
||||
KSET_FOREACH(self_set, k) {
|
||||
kset_iter_t other_k = kset_get(mrb, other_set, kset_key(self_set, k));
|
||||
if (other_k != kset_end(other_set)) {
|
||||
if (!kset_is_end(other_set, other_k)) {
|
||||
return mrb_true_value(); /* Found a common element */
|
||||
}
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
@@ -892,7 +893,7 @@ set_intersect_p(mrb_state *mrb, mrb_value self)
|
||||
else {
|
||||
KSET_FOREACH(other_set, k) {
|
||||
kset_iter_t self_k = kset_get(mrb, self_set, kset_key(other_set, k));
|
||||
if (self_k != kset_end(self_set)) {
|
||||
if (!kset_is_end(self_set, self_k)) {
|
||||
return mrb_true_value(); /* Found a common element */
|
||||
}
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
@@ -957,7 +958,7 @@ set_cmp(mrb_state *mrb, mrb_value self)
|
||||
int ai = mrb_gc_arena_save(mrb);
|
||||
KSET_FOREACH(self_set, k) {
|
||||
kset_iter_t other_k = kset_get(mrb, other_set, kset_key(self_set, k));
|
||||
if (other_k == kset_end(other_set)) {
|
||||
if (kset_is_end(other_set, other_k)) {
|
||||
/* Not a subset */
|
||||
return mrb_nil_value(); /* Not comparable */
|
||||
}
|
||||
@@ -972,7 +973,7 @@ set_cmp(mrb_state *mrb, mrb_value self)
|
||||
int ai = mrb_gc_arena_save(mrb);
|
||||
KSET_FOREACH(other_set, k) {
|
||||
kset_iter_t self_k = kset_get(mrb, self_set, kset_key(other_set, k));
|
||||
if (self_k == kset_end(self_set)) {
|
||||
if (kset_is_end(self_set, self_k)) {
|
||||
/* Not a superset */
|
||||
return mrb_nil_value(); /* Not comparable */
|
||||
}
|
||||
@@ -989,7 +990,7 @@ set_cmp(mrb_state *mrb, mrb_value self)
|
||||
int ai3 = mrb_gc_arena_save(mrb);
|
||||
KSET_FOREACH(self_set, k) {
|
||||
kset_iter_t other_k = kset_get(mrb, other_set, kset_key(self_set, k));
|
||||
if (other_k == kset_end(other_set)) {
|
||||
if (kset_is_end(other_set, other_k)) {
|
||||
is_equal = FALSE;
|
||||
break;
|
||||
}
|
||||
@@ -1332,7 +1333,7 @@ set_delete_all(mrb_state *mrb, mrb_value self)
|
||||
int ai = mrb_gc_arena_save(mrb);
|
||||
for (mrb_int i = 0; i < argc; i++) {
|
||||
kset_iter_t k = kset_get(mrb, ks, argv[i]);
|
||||
if (k != kset_end(ks)) {
|
||||
if (!kset_is_end(ks, k)) {
|
||||
kset_del(mrb, ks, k);
|
||||
}
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
@@ -1359,7 +1360,7 @@ set_include_all_p(mrb_state *mrb, mrb_value self)
|
||||
|
||||
for (mrb_int i = 0; i < argc; i++) {
|
||||
kset_iter_t k = kset_get(mrb, ks, argv[i]);
|
||||
if (k == kset_end(ks)) {
|
||||
if (kset_is_end(ks, k)) {
|
||||
return mrb_false_value();
|
||||
}
|
||||
}
|
||||
@@ -1385,7 +1386,7 @@ set_include_any_p(mrb_state *mrb, mrb_value self)
|
||||
|
||||
for (mrb_int i = 0; i < argc; i++) {
|
||||
kset_iter_t k = kset_get(mrb, ks, argv[i]);
|
||||
if (k != kset_end(ks)) {
|
||||
if (!kset_is_end(ks, k)) {
|
||||
return mrb_true_value();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user