From: Andrew Dinh Date: Fri, 21 Feb 2025 16:55:58 +0000 (+0700) Subject: Optimize ossl_namemap_name2num_n to avoid strndup X-Git-Tag: openssl-3.5.0-alpha1~54 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=054f6c0fc15e9c11ec4a94b08a9528844005b449;p=thirdparty%2Fopenssl.git Optimize ossl_namemap_name2num_n to avoid strndup Reviewed-by: Neil Horman Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/26870) --- diff --git a/crypto/core_namemap.c b/crypto/core_namemap.c index 1083b14d79b..de6bdfa573f 100644 --- a/crypto/core_namemap.c +++ b/crypto/core_namemap.c @@ -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, diff --git a/include/internal/hashtable.h b/include/internal/hashtable.h index 5ca1efbe222..1f7479d9d7b 100644 --- a/include/internal/hashtable.h +++ b/include/internal/hashtable.h @@ -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 */