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;