From: Bob Beck Date: Fri, 12 Sep 2025 18:08:02 +0000 (-0600) Subject: Don't clear is_sorted unconditionally on OPENSSL_sk_insert() X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a7540121b5ff0d42333d563bb16ee74bf466bb75;p=thirdparty%2Fopenssl.git 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 Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/28533) --- diff --git a/crypto/stack/stack.c b/crypto/stack/stack.c index 2efc0768e09..ecfaac9d6e6 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 5a75d142be9..1d7be299aa0 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;