[squid-dev] [PATCH] Deletors for std::unique_ptr WAS: Re: Broken trunk after r14735

Amos Jeffries squid3 at treenet.co.nz
Fri Jul 29 15:27:54 UTC 2016


On 26/07/2016 2:10 a.m., Alex Rousskov wrote:
> On 07/24/2016 01:04 AM, Amos Jeffries wrote:
> 
>>   does replacing "BIO_free" with "BIO_vfree" in the ssl/gadgets.h
>> definition of BIO_POinter fix this one?
> 
> Same startup exception (quoted below) after patching trunk revision
> 14756 with
> 
>> -typedef std::unique_ptr<BIO, std::function<decltype(BIO_free)>> BIO_Pointer;
>> +typedef std::unique_ptr<BIO, std::function<decltype(BIO_vfree)>> BIO_Pointer;
> 
> 
> Thank you,
> 
> Alex.
> 

I got this config parsing crash replicated here and tried a dozen or so
combinations. It does seem to keep coming back to my earlier approach of
using per-type Functors as the most reliable solution.

Attached patch seem to work for me. It implements a macro to simplify
Functor creation.

We could also wrap the std::unique_ptr definition parts inside the macro
for much smaller visible code. But that would prevent re-use of the
macro for other plain Functor definitions (not that anything else is
using it).

Amos

-------------- next part --------------
=== modified file 'src/security/LockingPointer.h'
--- src/security/LockingPointer.h	2016-07-13 12:39:22 +0000
+++ src/security/LockingPointer.h	2016-07-29 13:30:35 +0000
@@ -31,6 +31,14 @@
             function(a); \
         }
 
+// Macro to be used to define the C++ wrapper functor of the OpenSSL *_free
+// and GnuTLS *_deinit family of functions. The C++ functor is suffixed with
+// the _Deleter extension and intended for use by std::unique_ptr
+#define CtoDeleter(argument_type, function) \
+        struct argument_type ## _Deleter { \
+            void operator()(argument_type *a) { function(a); } \
+        }
+
 namespace Security
 {
 

=== modified file 'src/security/cert_generators/file/certificate_db.cc'
--- src/security/cert_generators/file/certificate_db.cc	2016-07-05 23:37:12 +0000
+++ src/security/cert_generators/file/certificate_db.cc	2016-07-29 15:17:30 +0000
@@ -287,12 +287,18 @@
     load();
     if (!db || !cert || !pkey)
         return false;
+
+    // Functor to wrap xfree() for std::unique_ptr
+    struct CharDeleter {
+        void operator()(char *a) {xfree(a);}
+    };
+
     Row row;
     ASN1_INTEGER * ai = X509_get_serialNumber(cert.get());
     std::string serial_string;
     Ssl::BIGNUM_Pointer serial(ASN1_INTEGER_to_BN(ai, NULL));
     {
-        std::unique_ptr<char, std::function<decltype(xfree)>> hex_bn(BN_bn2hex(serial.get()));
+        std::unique_ptr<char, CharDeleter> hex_bn(BN_bn2hex(serial.get()));
         serial_string = std::string(hex_bn.get());
     }
     row.setValue(cnlSerial, serial_string.c_str());
@@ -305,7 +311,7 @@
     }
 
     {
-        std::unique_ptr<char, std::function<decltype(xfree)>> subject(X509_NAME_oneline(X509_get_subject_name(cert.get()), nullptr, 0));
+        std::unique_ptr<char, CharDeleter> subject(X509_NAME_oneline(X509_get_subject_name(cert.get()), nullptr, 0));
         Security::CertPointer findCert;
         Ssl::EVP_PKEY_Pointer findPkey;
         if (pure_find(useName.empty() ? subject.get() : useName, findCert, findPkey)) {
@@ -348,7 +354,7 @@
     if (!useName.empty())
         row.setValue(cnlName, useName.c_str());
     else {
-        std::unique_ptr<char, std::function<decltype(xfree)>> subject(X509_NAME_oneline(X509_get_subject_name(cert.get()), nullptr, 0));
+        std::unique_ptr<char, CharDeleter> subject(X509_NAME_oneline(X509_get_subject_name(cert.get()), nullptr, 0));
         row.setValue(cnlName, subject.get());
     }
 

=== modified file 'src/ssl/gadgets.h'
--- src/ssl/gadgets.h	2016-06-29 10:44:40 +0000
+++ src/ssl/gadgets.h	2016-07-29 15:01:44 +0000
@@ -47,33 +47,44 @@
 CtoCpp1(EVP_PKEY_free, EVP_PKEY *)
 typedef Security::LockingPointer<EVP_PKEY, EVP_PKEY_free_cpp, CRYPTO_LOCK_EVP_PKEY> EVP_PKEY_Pointer;
 
-typedef std::unique_ptr<BIGNUM, std::function<decltype(BN_free)>> BIGNUM_Pointer;
-
-typedef std::unique_ptr<BIO, std::function<decltype(BIO_free)>> BIO_Pointer;
-
-typedef std::unique_ptr<ASN1_INTEGER, std::function<decltype(ASN1_INTEGER_free)>> ASN1_INT_Pointer;
-
-typedef std::unique_ptr<ASN1_OCTET_STRING, std::function<decltype(ASN1_OCTET_STRING_free)>> ASN1_OCTET_STRING_Pointer;
-
-typedef std::unique_ptr<TXT_DB, std::function<decltype(TXT_DB_free)>> TXT_DB_Pointer;
-
-typedef std::unique_ptr<X509_NAME, std::function<decltype(X509_NAME_free)>> X509_NAME_Pointer;
-
-typedef std::unique_ptr<RSA, std::function<decltype(RSA_free)>> RSA_Pointer;
-
-typedef std::unique_ptr<X509_REQ, std::function<decltype(X509_REQ_free)>> X509_REQ_Pointer;
+CtoDeleter(BIGNUM, BN_free);
+typedef std::unique_ptr<BIGNUM, BIGNUM_Deleter> BIGNUM_Pointer;
+
+CtoDeleter(BIO, BIO_vfree);
+typedef std::unique_ptr<BIO, BIO_Deleter> BIO_Pointer;
+
+CtoDeleter(ASN1_INTEGER, ASN1_INTEGER_free);
+typedef std::unique_ptr<ASN1_INTEGER, ASN1_INTEGER_Deleter> ASN1_INT_Pointer;
+
+CtoDeleter(ASN1_OCTET_STRING, ASN1_OCTET_STRING_free);
+typedef std::unique_ptr<ASN1_OCTET_STRING, ASN1_OCTET_STRING_Deleter> ASN1_OCTET_STRING_Pointer;
+
+CtoDeleter(TXT_DB, TXT_DB_free);
+typedef std::unique_ptr<TXT_DB, TXT_DB_Deleter> TXT_DB_Pointer;
+
+CtoDeleter(X509_NAME, X509_NAME_free);
+typedef std::unique_ptr<X509_NAME, X509_NAME_Deleter> X509_NAME_Pointer;
+
+CtoDeleter(RSA, RSA_free);
+typedef std::unique_ptr<RSA, RSA_Deleter> RSA_Pointer;
+
+CtoDeleter(X509_REQ, X509_REQ_free);
+typedef std::unique_ptr<X509_REQ, X509_REQ_Deleter> X509_REQ_Pointer;
 
 sk_dtor_wrapper(sk_X509_NAME, STACK_OF(X509_NAME) *, X509_NAME_free);
 typedef std::unique_ptr<STACK_OF(X509_NAME), sk_X509_NAME_free_wrapper> X509_NAME_STACK_Pointer;
 
-typedef std::unique_ptr<AUTHORITY_KEYID, std::function<decltype(AUTHORITY_KEYID_free)>> AUTHORITY_KEYID_Pointer;
+CtoDeleter(AUTHORITY_KEYID, AUTHORITY_KEYID_free);
+typedef std::unique_ptr<AUTHORITY_KEYID, AUTHORITY_KEYID_Deleter> AUTHORITY_KEYID_Pointer;
 
 sk_dtor_wrapper(sk_GENERAL_NAME, STACK_OF(GENERAL_NAME) *, GENERAL_NAME_free);
 typedef std::unique_ptr<STACK_OF(GENERAL_NAME), sk_GENERAL_NAME_free_wrapper> GENERAL_NAME_STACK_Pointer;
 
-typedef std::unique_ptr<GENERAL_NAME, std::function<decltype(GENERAL_NAME_free)>> GENERAL_NAME_Pointer;
+CtoDeleter(GENERAL_NAME, GENERAL_NAME_free);
+typedef std::unique_ptr<GENERAL_NAME, GENERAL_NAME_Deleter> GENERAL_NAME_Pointer;
 
-typedef std::unique_ptr<X509_EXTENSION, std::function<decltype(X509_EXTENSION_free)>> X509_EXTENSION_Pointer;
+CtoDeleter(X509_EXTENSION, X509_EXTENSION_free);
+typedef std::unique_ptr<X509_EXTENSION, X509_EXTENSION_Deleter> X509_EXTENSION_Pointer;
 
 /**
  \ingroup SslCrtdSslAPI



More information about the squid-dev mailing list