Commit 5c3f1e34 authored by Richard Levitte's avatar Richard Levitte
Browse files

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: default avatarMatt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8899)
parent 67c81ec3
Loading
Loading
Loading
Loading

crypto/bsearch.c

0 → 100644
+44 −0
Original line number Original line Diff line number Diff line
/*
 * 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;
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -18,12 +18,12 @@ SOURCE[../libcrypto]=\
        ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fopen.c ctype.c \
        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 \
        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 \
        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} -}
        {- $target{cpuid_asm_src} -} {- $target{uplink_aux_src} -}


# FIPS module
# FIPS module
SOURCE[../providers/fips]=\
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
DEPEND[cversion.o]=buildinf.h
+9 −29
Original line number Original line Diff line number Diff line
@@ -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);
    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 size,
                            int (*cmp) (const void *, const void *),
                            int (*cmp) (const void *, const void *),
                            int flags)
                            int flags)
{
{
    const char *base = base_;
    const char *p = ossl_bsearch(key, base, num, size, cmp, flags);
    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;
    }
#ifdef CHARSET_EBCDIC
#ifdef CHARSET_EBCDIC
    /*
    /*
     * THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I
     * 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
     * don't have perl (yet), we revert to a *LINEAR* search when the object
     * wasn't found in the binary search.
     * 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) {
        for (i = 0; i < num; ++i) {
            p = &(base[i * size]);
            p = &(base_[i * size]);
            c = (*cmp) (key, p);
            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;
                return p;
        }
        }
    }
    }
#endif
#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;
    return p;
}
}


+4 −5
Original line number Original line Diff line number Diff line
@@ -11,7 +11,6 @@
#include "internal/cryptlib.h"
#include "internal/cryptlib.h"
#include "internal/numbers.h"
#include "internal/numbers.h"
#include <openssl/stack.h>
#include <openssl/stack.h>
#include <openssl/objects.h>
#include <errno.h>
#include <errno.h>
#include <openssl/e_os2.h>      /* For ossl_inline */
#include <openssl/e_os2.h>      /* For ossl_inline */


@@ -307,7 +306,7 @@ static int internal_find(OPENSSL_STACK *st, const void *data,
    }
    }
    if (data == NULL)
    if (data == NULL)
        return -1;
        return -1;
    r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp,
    r = ossl_bsearch(&data, st->data, st->num, sizeof(void *), st->comp,
                     ret_val_options);
                     ret_val_options);


    return r == NULL ? -1 : (int)((const void **)r - st->data);
    return r == NULL ? -1 : (int)((const void **)r - st->data);
@@ -315,12 +314,12 @@ static int internal_find(OPENSSL_STACK *st, const void *data,


int OPENSSL_sk_find(OPENSSL_STACK *st, const void *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)
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)
int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data)
+11 −0
Original line number Original line Diff line number Diff line
@@ -174,4 +174,15 @@ int crypto_get_ex_new_index_ex(OPENSSL_CTX *ctx, int class_index,
                               CRYPTO_EX_dup *dup_func,
                               CRYPTO_EX_dup *dup_func,
                               CRYPTO_EX_free *free_func);
                               CRYPTO_EX_free *free_func);
int crypto_free_ex_index_ex(OPENSSL_CTX *ctx, int class_index, int idx);
int crypto_free_ex_index_ex(OPENSSL_CTX *ctx, int class_index, int idx);

/* Function for simple binary search */

/* Flags */
# define OSSL_BSEARCH_VALUE_ON_NOMATCH            0x01
# define OSSL_BSEARCH_FIRST_VALUE_ON_MATCH        0x02

const void *ossl_bsearch(const void *key, const void *base, int num,
                         int size, int (*cmp) (const void *, const void *),
                         int flags);

#endif
#endif