summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2019-05-08 10:40:20 +0200
committerRichard Levitte <levitte@openssl.org>2019-05-08 16:17:16 +0200
commit5c3f1e34b559c9b4372bf48aab63b61a6cd5edbb (patch)
tree3c6d91959d546794e32517dd5adecc8f1bbc0333 /crypto
parent67c81ec311d696464bdbf4c6d6f8a887a3ddf9f8 (diff)
ossl_bsearch(): New generic internal binary search utility function
OBJ_bsearch_ and OBJ_bsearch_ex_ are generic functions that don't really belong with the OBJ API, but should rather be generic utility functions. The ending underscore indicates that they are considered internal, even though they are declared publicly. Since crypto/stack/stack.c uses OBJ_bsearch_ex_, the stack API ends up depending on the OBJ API, which is unnecessary, and carries along other dependencies. Therefor, a generic internal function is created, ossl_bsearch(). This removes the unecessary dependencies. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/8899)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/bsearch.c44
-rw-r--r--crypto/build.info4
-rw-r--r--crypto/objects/obj_dat.c38
-rw-r--r--crypto/stack/stack.c9
4 files changed, 59 insertions, 36 deletions
diff --git a/crypto/bsearch.c b/crypto/bsearch.c
new file mode 100644
index 0000000000..f812c4f8ef
--- /dev/null
+++ b/crypto/bsearch.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stddef.h>
+#include "internal/cryptlib.h"
+
+const void *ossl_bsearch(const void *key, const void *base, int num,
+ int size, int (*cmp) (const void *, const void *),
+ int flags)
+{
+ const char *base_ = base;
+ int l, h, i = 0, c = 0;
+ const char *p = NULL;
+
+ if (num == 0)
+ return NULL;
+ l = 0;
+ h = num;
+ while (l < h) {
+ i = (l + h) / 2;
+ p = &(base_[i * size]);
+ c = (*cmp) (key, p);
+ if (c < 0)
+ h = i;
+ else if (c > 0)
+ l = i + 1;
+ else
+ break;
+ }
+ if (c != 0 && !(flags & OSSL_BSEARCH_VALUE_ON_NOMATCH))
+ p = NULL;
+ else if (c == 0 && (flags & OSSL_BSEARCH_FIRST_VALUE_ON_MATCH)) {
+ while (i > 0 && (*cmp) (key, &(base_[(i - 1) * size])) == 0)
+ i--;
+ p = &(base_[i * size]);
+ }
+ return p;
+}
diff --git a/crypto/build.info b/crypto/build.info
index 30dcf8c91e..fa99d61bd6 100644
--- a/crypto/build.info
+++ b/crypto/build.info
@@ -18,12 +18,12 @@ SOURCE[../libcrypto]=\
ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fopen.c ctype.c \
threads_pthread.c threads_win.c threads_none.c getenv.c \
o_init.c o_fips.c mem_sec.c init.c context.c sparse_array.c \
- trace.c provider.c params.c \
+ trace.c provider.c params.c bsearch.c \
{- $target{cpuid_asm_src} -} {- $target{uplink_aux_src} -}
# FIPS module
SOURCE[../providers/fips]=\
- cryptlib.c mem.c mem_clr.c params.c
+ cryptlib.c mem.c mem_clr.c params.c bsearch.c
DEPEND[cversion.o]=buildinf.h
diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c
index f374d19fc7..ec9e131337 100644
--- a/crypto/objects/obj_dat.c
+++ b/crypto/objects/obj_dat.c
@@ -585,52 +585,32 @@ const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
return OBJ_bsearch_ex_(key, base, num, size, cmp, 0);
}
-const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num,
+const void *OBJ_bsearch_ex_(const void *key, const void *base, int num,
int size,
int (*cmp) (const void *, const void *),
int flags)
{
- const char *base = base_;
- int l, h, i = 0, c = 0;
- const char *p = NULL;
+ const char *p = ossl_bsearch(key, base, num, size, cmp, flags);
- if (num == 0)
- return NULL;
- l = 0;
- h = num;
- while (l < h) {
- i = (l + h) / 2;
- p = &(base[i * size]);
- c = (*cmp) (key, p);
- if (c < 0)
- h = i;
- else if (c > 0)
- l = i + 1;
- else
- break;
- }
#ifdef CHARSET_EBCDIC
/*
* THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I
* don't have perl (yet), we revert to a *LINEAR* search when the object
* wasn't found in the binary search.
*/
- if (c != 0) {
+ if (p == NULL) {
+ const char *base_ = base;
+ int l, h, i = 0, c = 0;
+
for (i = 0; i < num; ++i) {
- p = &(base[i * size]);
+ p = &(base_[i * size]);
c = (*cmp) (key, p);
- if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
+ if (c == 0
+ || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
return p;
}
}
#endif
- if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))
- p = NULL;
- else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) {
- while (i > 0 && (*cmp) (key, &(base[(i - 1) * size])) == 0)
- i--;
- p = &(base[i * size]);
- }
return p;
}
diff --git a/crypto/stack/stack.c b/crypto/stack/stack.c
index 2f0ed64232..450a4e1a0e 100644
--- a/crypto/stack/stack.c
+++ b/crypto/stack/stack.c
@@ -11,7 +11,6 @@
#include "internal/cryptlib.h"
#include "internal/numbers.h"
#include <openssl/stack.h>
-#include <openssl/objects.h>
#include <errno.h>
#include <openssl/e_os2.h> /* For ossl_inline */
@@ -307,20 +306,20 @@ static int internal_find(OPENSSL_STACK *st, const void *data,
}
if (data == NULL)
return -1;
- r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp,
- ret_val_options);
+ r = ossl_bsearch(&data, st->data, st->num, sizeof(void *), st->comp,
+ ret_val_options);
return r == NULL ? -1 : (int)((const void **)r - st->data);
}
int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data)
{
- return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH);
+ return internal_find(st, data, OSSL_BSEARCH_FIRST_VALUE_ON_MATCH);
}
int OPENSSL_sk_find_ex(OPENSSL_STACK *st, const void *data)
{
- return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH);
+ return internal_find(st, data, OSSL_BSEARCH_VALUE_ON_NOMATCH);
}
int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data)