]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Optimize ossl_namemap_name2num_n to avoid strndup
authorAndrew Dinh <andrewd@openssl.org>
Fri, 21 Feb 2025 16:55:58 +0000 (23:55 +0700)
committerNeil Horman <nhorman@openssl.org>
Wed, 26 Feb 2025 18:32:59 +0000 (13:32 -0500)
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26870)

crypto/core_namemap.c
include/internal/hashtable.h

index 1083b14d79b479315103c103a6dcff8442327ead..de6bdfa573f501da857de88a5ef29f09a74a3863 100644 (file)
@@ -163,19 +163,31 @@ int ossl_namemap_name2num(const OSSL_NAMEMAP *namemap, const char *name)
     return number;
 }
 
-/* TODO: Optimize to avoid strndup() */
 int ossl_namemap_name2num_n(const OSSL_NAMEMAP *namemap,
                             const char *name, size_t name_len)
 {
-    char *tmp;
-    int ret;
+    int number = 0;
+    HT_VALUE *val;
+    NAMENUM_KEY key;
 
-    if (name == NULL || (tmp = OPENSSL_strndup(name, name_len)) == NULL)
+#ifndef FIPS_MODULE
+    if (namemap == NULL)
+        namemap = ossl_namemap_stored(NULL);
+#endif
+
+    if (namemap == NULL)
         return 0;
 
-    ret = ossl_namemap_name2num(namemap, tmp);
-    OPENSSL_free(tmp);
-    return ret;
+    HT_INIT_KEY(&key);
+    HT_SET_KEY_STRING_CASE_N(&key, name, name, name_len);
+
+    val = ossl_ht_get(namemap->namenum_ht, TO_HT_KEY(&key));
+
+    if (val != NULL)
+        /* We store a (small) int directly instead of a pointer to it. */
+        number = (int)(intptr_t)val->value;
+
+    return number;
 }
 
 const char *ossl_namemap_num2name(const OSSL_NAMEMAP *namemap, int number,
index 5ca1efbe22276180a3b1ee944626b6e5e1bd6d5d..1f7479d9d7b8a52a8509b33efe125a02d973b845 100644 (file)
@@ -139,6 +139,26 @@ memset((key), 0, sizeof(*(key))); \
    ossl_ht_strcase((key)->keyfields.member, value, sizeof((key)->keyfields.member) -1); \
 } while(0)
 
+/*
+ * Same as HT_SET_KEY_STRING but also takes length of the string.
+ */
+#define HT_SET_KEY_STRING_N(key, member, value, len) do { \
+    if ((value) != NULL) { \
+        if (len < sizeof((key)->keyfields.member)) \
+            strncpy((key)->keyfields.member, value, len); \
+        else \
+            strncpy((key)->keyfields.member, value, sizeof((key)->keyfields.member) - 1); \
+    } \
+} while(0)
+
+/* Same as HT_SET_KEY_STRING_CASE but also takes length of the string. */
+#define HT_SET_KEY_STRING_CASE_N(key, member, value, len) do { \
+    if (len < sizeof((key)->keyfields.member)) \
+        ossl_ht_strcase((key)->keyfields.member, value, len); \
+    else \
+        ossl_ht_strcase((key)->keyfields.member, value, sizeof((key)->keyfields.member) - 1); \
+} while(0)
+
 /*
  * Sets a uint8_t (blob) field in a hash table key
  */