]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
property: improve ossl_property_find_property() function
authorPauli <pauli@openssl.org>
Fri, 4 Jun 2021 04:25:14 +0000 (14:25 +1000)
committerPauli <pauli@openssl.org>
Sat, 5 Jun 2021 10:39:39 +0000 (20:39 +1000)
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 <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15614)

crypto/property/property_parse.c
crypto/property/property_query.c

index abfbbdfb6e33a81fccb3c056171814d1ea27e03d..28822ec42cdc9d1236cf3c29f8f7f905ab088a7c 100644 (file)
@@ -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)));
 }
 
 /*
index 6f870d36958e517481fd87f6fc6eb613d7cdb02e..c4c6b1a22fda8f09585af5032550b981e85a5367 100644 (file)
 #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;
 }
+