apr_crypto: Don't cache the driver if initialisation fails. This
stops the second and subsequent attempt to use the API from failing
claiming the library is not initialised.


git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1751806 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/CHANGES b/CHANGES
index 80b970d..5d65a65 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
                                                      -*- coding: utf-8 -*-
 Changes for APR 2.0.0
 
+  *) apr_crypto: Don't cache the driver if initialisation fails. This
+     stops the second and subsequent attempt to use the API from failing
+     claiming the library is not initialised. [Graham Leggett]
+
   *) apr_xml_to_text: Add style APR_XML_X2T_PARSED to maintain a
      consistent namespace prefix. [Jari Urpalainen
      <jari.urpalainen nokia.com>]
diff --git a/crypto/apr_crypto.c b/crypto/apr_crypto.c
index 52930c1..d10e6de 100644
--- a/crypto/apr_crypto.c
+++ b/crypto/apr_crypto.c
@@ -182,12 +182,15 @@
     apr_snprintf(symname, sizeof(symname), "apr_crypto_%s_driver", name);
     rv = apu_dso_load(&dso, &symbol, modname, symname, pool);
     if (rv == APR_SUCCESS || rv == APR_EINIT) { /* previously loaded?!? */
-        *driver = symbol;
-        name = apr_pstrdup(pool, name);
-        apr_hash_set(drivers, name, APR_HASH_KEY_STRING, *driver);
+        apr_crypto_driver_t *d = symbol;
         rv = APR_SUCCESS;
-        if ((*driver)->init) {
-            rv = (*driver)->init(pool, params, result);
+        if (d->init) {
+            rv = d->init(pool, params, result);
+        }
+        if (APR_SUCCESS == rv) {
+            *driver = symbol;
+            name = apr_pstrdup(pool, name);
+            apr_hash_set(drivers, name, APR_HASH_KEY_STRING, *driver);
         }
     }
     apu_dso_mutex_unlock();
diff --git a/crypto/apr_crypto_nss.c b/crypto/apr_crypto_nss.c
index f65f60a..1a92c85 100644
--- a/crypto/apr_crypto_nss.c
+++ b/crypto/apr_crypto_nss.c
@@ -198,9 +198,6 @@
         return APR_EREINIT;
     }
 
-    apr_pool_cleanup_register(pool, pool, crypto_shutdown_helper,
-            apr_pool_cleanup_null);
-
     if (keyPrefix || certPrefix || secmod) {
         s = NSS_Initialize(dir, certPrefix, keyPrefix, secmod, flags);
     }
@@ -212,15 +209,19 @@
     }
     if (s != SECSuccess) {
         if (result) {
+            /* Note: all memory must be owned by the caller, in case we're unloaded */
             apu_err_t *err = apr_pcalloc(pool, sizeof(apu_err_t));
             err->rc = PR_GetError();
-            err->msg = PR_ErrorToName(s);
-            err->reason = "Error during 'nss' initialisation";
+            err->msg = apr_pstrdup(pool, PR_ErrorToName(s));
+            err->reason = apr_pstrdup(pool, "Error during 'nss' initialisation");
             *result = err;
         }
         return APR_ECRYPT;
     }
 
+    apr_pool_cleanup_register(pool, pool, crypto_shutdown_helper,
+            apr_pool_cleanup_null);
+
     return APR_SUCCESS;
 
 }