Commit a7540121b5 for openssl.org

commit a7540121b5ff0d42333d563bb16ee74bf466bb75
Author: Bob Beck <beck@openssl.org>
Date:   Fri Sep 12 12:08:02 2025 -0600

    Don't clear is_sorted unconditionally on OPENSSL_sk_insert()

    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)

diff --git a/crypto/stack/stack.c b/crypto/stack/stack.c
index 2efc0768e0..ecfaac9d6e 100644
--- a/crypto/stack/stack.c
+++ b/crypto/stack/stack.c
@@ -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;
 }

diff --git a/test/stack_test.c b/test/stack_test.c
index 5a75d142be..1d7be299aa 100644
--- a/test/stack_test.c
+++ b/test/stack_test.c
@@ -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;