]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Don't clear is_sorted unconditionally on OPENSSL_sk_insert()
authorBob Beck <beck@openssl.org>
Fri, 12 Sep 2025 18:08:02 +0000 (12:08 -0600)
committerPauli <paul.dale@oracle.com>
Wed, 17 Sep 2025 21:30:23 +0000 (07:30 +1000)
If we have a comparison function, and the array was sorted,
check to see if we are inserting in the correct location.
if so do not clear is_sorted.

This allows for element locations found with OPENSSL_sk_find_ex
to be used to insert elements in the correct location and preserve
the sorting order without the need to sort the stack again.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/28533)

crypto/stack/stack.c
test/stack_test.c

index 2efc0768e0964228d3d0d20eab6fdcea3dc2edfd..ecfaac9d6e675a175c089bb97e2e5403473c085f 100644 (file)
@@ -257,14 +257,25 @@ int OPENSSL_sk_insert(OPENSSL_STACK *st, const void *data, int loc)
         return 0;
 
     if ((loc >= st->num) || (loc < 0)) {
-        st->data[st->num] = data;
+        loc = st->num;
+        st->data[loc] = data;
     } else {
         memmove(&st->data[loc + 1], &st->data[loc],
                 sizeof(st->data[0]) * (st->num - loc));
         st->data[loc] = data;
     }
     st->num++;
-    st->sorted = st->num <= 1;
+    if (st->sorted && st->num > 1) {
+        if (st->comp != NULL) {
+            if (loc > 0 && (st->comp(&st->data[loc - 1], &st->data[loc]) > 0))
+                st->sorted = 0;
+            if (loc < st->num - 1
+                && (st->comp(&st->data[loc + 1], &st->data[loc]) < 0))
+                st->sorted = 0;
+        } else {
+            st->sorted = 0;
+        }
+    }
     return st->num;
 }
 
index 5a75d142be963ced8c9e619e744d221a668951ff..1d7be299aa0eff605562daef4322cc4159e51f49 100644 (file)
@@ -179,6 +179,30 @@ static int test_int_stack(int reserve)
             goto end;
         }
 
+    if (!TEST_true(sk_sint_is_sorted(s)))
+        goto end;
+
+    for (i = 0; i < n_exfinds; i++) {
+        int loc = sk_sint_find_ex(s, &exfinds[i].value);
+        int value = *sk_sint_value(s, loc);
+
+        /* inserting in the correct location should preserve is_sorted */
+        if (value < exfinds[i].value)
+            loc++;
+        sk_sint_insert(s, &exfinds[i].value, loc);
+        if (!TEST_true(sk_sint_is_sorted(s)))
+            goto end;
+    }
+
+    if (!TEST_true(sk_sint_is_sorted(s)))
+        goto end;
+
+    /* inserting out of order should make the array unsorted again */
+    sk_sint_insert(s, v + 6, 0);
+
+    if (!TEST_false(sk_sint_is_sorted(s)))
+        goto end;
+
     /* shift */
     if (!TEST_ptr_eq(sk_sint_shift(s), v + 6))
         goto end;