property: reduce memory consumption when OPENSSL_SMALL_FOOTPRINT is defined.
[openssl.git] / crypto / property / property_string.c
index 6c61bfbbb27d1c97786759a7abcefe321f60881c..9191453d5a96b8246f77050a5a6d709e1d04387d 100644 (file)
@@ -40,8 +40,10 @@ typedef struct {
     PROP_TABLE *prop_values;
     OSSL_PROPERTY_IDX prop_name_idx;
     OSSL_PROPERTY_IDX prop_value_idx;
+#ifndef OPENSSL_SMALL_FOOTPRINT
     STACK_OF(OPENSSL_CSTRING) *prop_namelist;
     STACK_OF(OPENSSL_CSTRING) *prop_valuelist;
+#endif
 } PROPERTY_STRING_DATA;
 
 static unsigned long property_hash(const PROPERTY_STRING *a)
@@ -80,9 +82,11 @@ static void property_string_data_free(void *vpropdata)
     CRYPTO_THREAD_lock_free(propdata->lock);
     property_table_free(&propdata->prop_names);
     property_table_free(&propdata->prop_values);
+#ifndef OPENSSL_SMALL_FOOTPRINT
     sk_OPENSSL_CSTRING_free(propdata->prop_namelist);
     sk_OPENSSL_CSTRING_free(propdata->prop_valuelist);
     propdata->prop_namelist = propdata->prop_valuelist = NULL;
+#endif
     propdata->prop_name_idx = propdata->prop_value_idx = 0;
 
     OPENSSL_free(propdata);
@@ -99,13 +103,17 @@ static void *property_string_data_new(OSSL_LIB_CTX *ctx) {
                                                   &property_cmp);
     propdata->prop_values = lh_PROPERTY_STRING_new(&property_hash,
                                                    &property_cmp);
+#ifndef OPENSSL_SMALL_FOOTPRINT
     propdata->prop_namelist = sk_OPENSSL_CSTRING_new_null();
     propdata->prop_valuelist = sk_OPENSSL_CSTRING_new_null();
+#endif
     if (propdata->lock == NULL
-            || propdata->prop_names == NULL
-            || propdata->prop_values == NULL
+#ifndef OPENSSL_SMALL_FOOTPRINT
             || propdata->prop_namelist == NULL
-            || propdata->prop_valuelist == NULL) {
+            || propdata->prop_valuelist == NULL
+#endif
+            || propdata->prop_names == NULL
+            || propdata->prop_values == NULL) {
         property_string_data_free(propdata);
         return NULL;
     }
@@ -141,7 +149,6 @@ static OSSL_PROPERTY_IDX ossl_property_string(OSSL_LIB_CTX *ctx, int name,
 {
     PROPERTY_STRING p, *ps, *ps_new;
     PROP_TABLE *t;
-    STACK_OF(OPENSSL_CSTRING) *slist;
     OSSL_PROPERTY_IDX *pidx;
     PROPERTY_STRING_DATA *propdata
         = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_PROPERTY_STRING_INDEX,
@@ -166,19 +173,25 @@ static OSSL_PROPERTY_IDX ossl_property_string(OSSL_LIB_CTX *ctx, int name,
         pidx = name ? &propdata->prop_name_idx : &propdata->prop_value_idx;
         ps = lh_PROPERTY_STRING_retrieve(t, &p);
         if (ps == NULL && (ps_new = new_property_string(s, pidx)) != NULL) {
+#ifndef OPENSSL_SMALL_FOOTPRINT
+            STACK_OF(OPENSSL_CSTRING) *slist;
+
             slist = name ? propdata->prop_namelist : propdata->prop_valuelist;
             if (sk_OPENSSL_CSTRING_push(slist, ps_new->s) <= 0) {
                 property_free(ps_new);
                 CRYPTO_THREAD_unlock(propdata->lock);
                 return 0;
             }
+#endif
             lh_PROPERTY_STRING_insert(t, ps_new);
             if (lh_PROPERTY_STRING_error(t)) {
                 /*-
                  * Undo the previous push which means also decrementing the
                  * index and freeing the allocated storage.
                  */
+#ifndef OPENSSL_SMALL_FOOTPRINT
                 sk_OPENSSL_CSTRING_pop(slist);
+#endif
                 property_free(ps_new);
                 --*pidx;
                 CRYPTO_THREAD_unlock(propdata->lock);
@@ -191,6 +204,21 @@ static OSSL_PROPERTY_IDX ossl_property_string(OSSL_LIB_CTX *ctx, int name,
     return ps != NULL ? ps->idx : 0;
 }
 
+#ifdef OPENSSL_SMALL_FOOTPRINT
+struct find_str_st {
+    const char *str;
+    OSSL_PROPERTY_IDX idx;
+};
+
+static void find_str_fn(PROPERTY_STRING *prop, void *vfindstr)
+{
+    struct find_str_st *findstr = vfindstr;
+
+    if (prop->idx == findstr->idx)
+        findstr->str = prop->s;
+}
+#endif
+
 static const char *ossl_property_str(int name, OSSL_LIB_CTX *ctx,
                                      OSSL_PROPERTY_IDX idx)
 {
@@ -206,8 +234,22 @@ static const char *ossl_property_str(int name, OSSL_LIB_CTX *ctx,
         ERR_raise(ERR_LIB_CRYPTO, ERR_R_UNABLE_TO_GET_READ_LOCK);
         return NULL;
     }
+#ifdef OPENSSL_SMALL_FOOTPRINT
+    {
+        struct find_str_st findstr;
+
+        findstr.str = NULL;
+        findstr.idx = idx;
+
+        lh_PROPERTY_STRING_doall_arg(name ? propdata->prop_names
+                                          : propdata->prop_values,
+                                     find_str_fn, &findstr);
+        r = findstr.str;
+    }
+#else
     r = sk_OPENSSL_CSTRING_value(name ? propdata->prop_namelist
                                       : propdata->prop_valuelist, idx - 1);
+#endif
     CRYPTO_THREAD_unlock(propdata->lock);
 
     return r;