Fix infinite loop and undefined behavior in del(.[nan]) (#3490)

This commit is contained in:
itchyny authored and GitHub committed 2026-03-02 21:58:28 +09:00
1 parent 262f0b81c1
commit 0df54c888a
2 files changed
+15 -4

No files matched your search

+7 -4
View File
@@ -276,7 +276,9 @@ static jv jv_dels(jv t, jv keys) {
jv starts = jv_array(), ends = jv_array();
jv_array_foreach(keys, i, key) {
if (jv_get_kind(key) == JV_KIND_NUMBER) {
if (jv_number_value(key) < 0) {
if (jvp_number_is_nan(key)) {
jv_free(key);
} else if (jv_number_value(key) < 0) {
neg_keys = jv_array_append(neg_keys, key);
} else {
nonneg_keys = jv_array_append(nonneg_keys, key);
@@ -439,13 +441,14 @@ jv jv_getpath(jv root, jv path) {
static jv delpaths_sorted(jv object, jv paths, int start) {
jv delkeys = jv_array();
for (int i=0; i<jv_array_length(jv_copy(paths));) {
int j = i;
assert(jv_array_length(jv_array_get(jv_copy(paths), i)) > start);
int delkey = jv_array_length(jv_array_get(jv_copy(paths), i)) == start + 1;
jv key = jv_array_get(jv_array_get(jv_copy(paths), i), start);
while (j < jv_array_length(jv_copy(paths)) &&
jv_equal(jv_copy(key), jv_array_get(jv_array_get(jv_copy(paths), j), start)))
int j = i;
do
j++;
while (j < jv_array_length(jv_copy(paths)) &&
jv_equal(jv_copy(key), jv_array_get(jv_array_get(jv_copy(paths), j), start)));
// if i <= entry < j, then entry starts with key
if (delkey) {
// deleting this entire key, we don't care about any more specific deletions
+8
View File
@@ -1176,6 +1176,14 @@ del(.[1], .[-6], .[2], .[-3:9])
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 3, 5, 6, 9]
del(.[nan])
[1,2,3]
[1,2,3]
del(.[nan,nan])
[1,2,3]
[1,2,3]
# negative index
setpath([-1]; 1)
[0]