From: Pauli Date: Fri, 4 Jun 2021 04:25:14 +0000 (+1000) Subject: property: improve ossl_property_find_property() function X-Git-Tag: openssl-3.0.0-beta1~185 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fce102304a340ef1a90361a03c86bd2401f0b6c3;p=thirdparty%2Fopenssl.git property: improve ossl_property_find_property() function This function searches a property list for a specific property and returns a pointer to the definition if found. The existing version was O(n) time, the improved O(log n). Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/15614) --- diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c index abfbbdfb6e3..28822ec42cd 100644 --- a/crypto/property/property_parse.c +++ b/crypto/property/property_parse.c @@ -431,30 +431,17 @@ int ossl_property_has_optional(const OSSL_PROPERTY_LIST *query) int ossl_property_is_enabled(OSSL_LIB_CTX *ctx, const char *property_name, const OSSL_PROPERTY_LIST *prop_list) { - int i; - OSSL_PROPERTY_IDX name_id; - const OSSL_PROPERTY_DEFINITION *prop = NULL; - - if (prop_list == NULL) - return 0; + const OSSL_PROPERTY_DEFINITION *prop; - if (!parse_name(ctx, &property_name, 0, &name_id)) + prop = ossl_property_find_property(prop_list, ctx, property_name); + /* Do a separate check for override as it does not set type */ + if (prop == NULL || prop->optional || prop->oper == OSSL_PROPERTY_OVERRIDE) return 0; - - prop = prop_list->properties; - for (i = 0; i < prop_list->n; ++i) { - if (prop[i].name_idx == name_id) { - /* Do a separate check for override as it does not set type */ - if (prop[i].optional || prop[i].oper == OSSL_PROPERTY_OVERRIDE) - return 0; - return (prop[i].type == OSSL_PROPERTY_TYPE_STRING - && ((prop[i].oper == OSSL_PROPERTY_OPER_EQ - && prop[i].v.str_val == ossl_property_true) - || (prop[i].oper == OSSL_PROPERTY_OPER_NE - && prop[i].v.str_val != ossl_property_true))); - } - } - return 0; + return (prop->type == OSSL_PROPERTY_TYPE_STRING + && ((prop->oper == OSSL_PROPERTY_OPER_EQ + && prop->v.str_val == ossl_property_true) + || (prop->oper == OSSL_PROPERTY_OPER_NE + && prop->v.str_val != ossl_property_true))); } /* diff --git a/crypto/property/property_query.c b/crypto/property/property_query.c index 6f870d36958..c4c6b1a22fd 100644 --- a/crypto/property/property_query.c +++ b/crypto/property/property_query.c @@ -11,21 +11,27 @@ #include "internal/property.h" #include "property_local.h" +static int property_idx_cmp(const void *keyp, const void *compare) +{ + OSSL_PROPERTY_IDX key = *(const OSSL_PROPERTY_IDX *)keyp; + const OSSL_PROPERTY_DEFINITION *defn = + (const OSSL_PROPERTY_DEFINITION *)compare; + + return key - defn->name_idx; +} + const OSSL_PROPERTY_DEFINITION * ossl_property_find_property(const OSSL_PROPERTY_LIST *list, OSSL_LIB_CTX *libctx, const char *name) { OSSL_PROPERTY_IDX name_idx; - int i; if (list == NULL || name == NULL || (name_idx = ossl_property_name(libctx, name, 0)) == 0) return NULL; - for (i = 0; i < list->num_properties; i++) - if (list->properties[i].name_idx == name_idx) - return &list->properties[i]; - return NULL; + return ossl_bsearch(&name_idx, list->properties, list->num_properties, + sizeof(*list->properties), &property_idx_cmp, 0); } OSSL_PROPERTY_TYPE ossl_property_get_type(const OSSL_PROPERTY_DEFINITION *prop) @@ -51,3 +57,4 @@ int64_t ossl_property_get_number_value(const OSSL_PROPERTY_DEFINITION *prop) value = prop->v.int_val; return value; } +