From b076337121bbbe5069e31e5ae3daa8373646b390 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Tue, 13 Jul 2021 10:59:41 +0200 Subject: [PATCH] import from review #1975704 --- .gitignore | 1 + libmemcached-awesome-aes.patch | 1303 ++++++++++++++++++++++++++++++ libmemcached-awesome-catch.patch | 905 +++++++++++++++++++++ libmemcached-awesome.spec | 196 +++++ sources | 1 + 5 files changed, 2406 insertions(+) create mode 100644 .gitignore create mode 100644 libmemcached-awesome-aes.patch create mode 100644 libmemcached-awesome-catch.patch create mode 100644 libmemcached-awesome.spec create mode 100644 sources diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..23f49fb --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/libmemcached-1.1.0-0ff88be.tar.gz diff --git a/libmemcached-awesome-aes.patch b/libmemcached-awesome-aes.patch new file mode 100644 index 0000000..059bbee --- /dev/null +++ b/libmemcached-awesome-aes.patch @@ -0,0 +1,1303 @@ +From 2aab18117a2b078dd0eb366f3766a1fef06da695 Mon Sep 17 00:00:00 2001 +From: Tomas Korbar +Date: Fri, 25 Jun 2021 11:55:46 +0200 +Subject: [PATCH 1/7] Add possibility to use libcrypto for encryption + +--- + include/libhashkit-1.0/hashkit.h | 4 +- + src/libhashkit/CMakeLists.txt | 9 +++ + src/libhashkit/aes.cc | 121 +++++++++++++++++++++++++++++-- + src/libhashkit/aes.h | 22 ++++++ + src/libhashkit/encrypt.cc | 42 +++++++++-- + src/libhashkit/hashkit.cc | 43 +++++++++-- + src/libhashkit/rijndael.hpp | 2 +- + src/libmemcached/is.h | 2 +- + 8 files changed, 225 insertions(+), 20 deletions(-) + +diff --git a/include/libhashkit-1.0/hashkit.h b/include/libhashkit-1.0/hashkit.h +index a05eb5f8..0f67e377 100644 +--- a/include/libhashkit-1.0/hashkit.h ++++ b/include/libhashkit-1.0/hashkit.h +@@ -49,7 +49,7 @@ struct hashkit_st { + bool is_allocated : 1; + } options; + +- void *_key; ++ void *_cryptographic_context; + }; + + #ifdef __cplusplus +@@ -75,7 +75,7 @@ HASHKIT_API + hashkit_string_st *hashkit_decrypt(hashkit_st *, const char *source, size_t source_length); + + HASHKIT_API +-bool hashkit_key(hashkit_st *, const char *key, const size_t key_length); ++bool hashkit_key(hashkit_st *kit, const char *key, const size_t key_length); + + #ifdef __cplusplus + } // extern "C" +diff --git a/src/libhashkit/CMakeLists.txt b/src/libhashkit/CMakeLists.txt +index 355afabb..d0e03d15 100644 +--- a/src/libhashkit/CMakeLists.txt ++++ b/src/libhashkit/CMakeLists.txt +@@ -39,6 +39,15 @@ target_include_directories(libhashkit PUBLIC + $ + $ + $) ++ ++find_package(OpenSSL) ++if(NOT OPENSSL_FOUND) ++ message(WARNING "crypto library not found") ++else() ++ add_compile_definitions(WITH_OPENSSL) ++ target_link_libraries(libhashkit PUBLIC OpenSSL::Crypto) ++endif() ++ + configure_file(hashkitcon.h.in hashkitcon.h @ONLY) + + install(TARGETS libhashkit EXPORT libhashkit-targets +diff --git a/src/libhashkit/aes.cc b/src/libhashkit/aes.cc +index 0b2f73d8..d4fdad5a 100644 +--- a/src/libhashkit/aes.cc ++++ b/src/libhashkit/aes.cc +@@ -15,12 +15,122 @@ + + #include "libhashkit/common.h" + +-#include "libhashkit/rijndael.hpp" +- + #include + +-#define AES_KEY_LENGTH 256 /* 128, 192, 256 */ +-#define AES_BLOCK_SIZE 16 ++#ifdef WITH_OPENSSL ++ ++#include ++ ++#define DIGEST_ROUNDS 5 ++ ++#define AES_KEY_NBYTES 32 ++#define AES_IV_NBYTES 32 ++ ++bool aes_initialize(const unsigned char *key, const size_t key_length, ++ encryption_context_t *crypto_context) { ++ unsigned char aes_key[AES_KEY_NBYTES]; ++ unsigned char aes_iv[AES_IV_NBYTES]; ++ if (aes_key == NULL || aes_iv == NULL) { ++ return false; ++ } ++ ++ int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha256(), NULL, key, key_length, DIGEST_ROUNDS, ++ aes_key, aes_iv); ++ if (i != AES_KEY_NBYTES) { ++ return false; ++ } ++ ++ EVP_CIPHER_CTX_init(crypto_context->encryption_context); ++ EVP_CIPHER_CTX_init(crypto_context->decryption_context); ++ if (EVP_EncryptInit_ex(crypto_context->encryption_context, EVP_aes_256_cbc(), NULL, key, aes_iv) ++ != 1 ++ || EVP_DecryptInit_ex(crypto_context->decryption_context, EVP_aes_256_cbc(), NULL, key, ++ aes_iv) ++ != 1) ++ { ++ return false; ++ } ++ return true; ++} ++ ++hashkit_string_st *aes_encrypt(encryption_context_t *crypto_context, const unsigned char *source, ++ size_t source_length) { ++EVP_CIPHER_CTX *encryption_context = crypto_context->encryption_context; ++int cipher_length = source_length + EVP_CIPHER_CTX_block_size(encryption_context); ++int final_length = 0; ++unsigned char *cipher_text = (unsigned char *) malloc(cipher_length); ++if (cipher_text == NULL) { ++ return NULL; ++} ++if (EVP_EncryptInit_ex(encryption_context, NULL, NULL, NULL, NULL) != 1 ++ || EVP_EncryptUpdate(encryption_context, cipher_text, &cipher_length, source, source_length) ++ != 1 ++ || EVP_EncryptFinal_ex(encryption_context, cipher_text + cipher_length, &final_length) != 1) ++{ ++ free(cipher_text); ++ return NULL; ++} ++ ++hashkit_string_st *destination = hashkit_string_create(cipher_length + final_length); ++if (destination == NULL) { ++ return NULL; ++} ++char *dest = hashkit_string_c_str_mutable(destination); ++memcpy(dest, cipher_text, cipher_length + final_length); ++hashkit_string_set_length(destination, cipher_length + final_length); ++return destination; ++} ++ ++hashkit_string_st *aes_decrypt(encryption_context_t *crypto_context, const unsigned char *source, ++ size_t source_length) { ++EVP_CIPHER_CTX *decryption_context = crypto_context->decryption_context; ++int plain_text_length = source_length; ++int final_length = 0; ++unsigned char *plain_text = (unsigned char *) malloc(plain_text_length); ++if (plain_text == NULL) { ++ return NULL; ++} ++if (EVP_DecryptInit_ex(decryption_context, NULL, NULL, NULL, NULL) != 1 ++ || EVP_DecryptUpdate(decryption_context, plain_text, &plain_text_length, source, source_length) ++ != 1 ++ || EVP_DecryptFinal_ex(decryption_context, plain_text + plain_text_length, &final_length) != 1) ++{ ++ free(plain_text); ++ return NULL; ++} ++ ++hashkit_string_st *destination = hashkit_string_create(plain_text_length + final_length); ++if (destination == NULL) { ++ return NULL; ++} ++char *dest = hashkit_string_c_str_mutable(destination); ++memcpy(dest, plain_text, plain_text_length + final_length); ++hashkit_string_set_length(destination, plain_text_length + final_length); ++return destination; ++} ++ ++encryption_context_t *aes_clone_cryptographic_context(encryption_context_t *source) { ++ encryption_context_t *new_context = (encryption_context_t *) malloc(sizeof(encryption_context_t)); ++ if (new_context == NULL) ++ return NULL; ++ ++ new_context->encryption_context = EVP_CIPHER_CTX_new(); ++ new_context->decryption_context = EVP_CIPHER_CTX_new(); ++ if (new_context->encryption_context == NULL || new_context->decryption_context == NULL) { ++ free(new_context); ++ return NULL; ++ } ++ EVP_CIPHER_CTX_copy(new_context->encryption_context, source->encryption_context); ++ EVP_CIPHER_CTX_copy(new_context->decryption_context, source->decryption_context); ++ return new_context; ++} ++ ++#else ++ ++# include "libhashkit/rijndael.hpp" ++ ++# define AES_KEY_LENGTH 256 /* 128, 192, 256 */ ++# define AES_BLOCK_SIZE 16 + + enum encrypt_t { AES_ENCRYPT, AES_DECRYPT }; + +@@ -49,7 +159,7 @@ aes_key_t *aes_create_key(const char *key, const size_t key_length) { + if (ptr == rkey_end) { + ptr = rkey; /* Just loop over tmp_key until we used all key */ + } +- *ptr ^= (uint8_t)(*sptr); ++ *ptr ^= (uint8_t) (*sptr); + } + + _aes_key->decode_key.nr = rijndaelKeySetupDec(_aes_key->decode_key.rk, rkey, AES_KEY_LENGTH); +@@ -140,3 +250,4 @@ hashkit_string_st *aes_decrypt(aes_key_t *_aes_key, const char *source, size_t s + + return destination; + } ++#endif +\ No newline at end of file +diff --git a/src/libhashkit/aes.h b/src/libhashkit/aes.h +index 43a18b35..e021c5f1 100644 +--- a/src/libhashkit/aes.h ++++ b/src/libhashkit/aes.h +@@ -15,6 +15,27 @@ + + #pragma once + ++#ifdef WITH_OPENSSL ++ ++#include ++ ++typedef struct encryption_context { ++ EVP_CIPHER_CTX *encryption_context; ++ EVP_CIPHER_CTX *decryption_context; ++} encryption_context_t; ++ ++hashkit_string_st *aes_encrypt(encryption_context_t *crypto_context, const unsigned char *source, ++ size_t source_length); ++ ++hashkit_string_st *aes_decrypt(encryption_context_t *crypto_context, const unsigned char *source, ++ size_t source_length); ++ ++bool aes_initialize(const unsigned char *key, const size_t key_length, ++ encryption_context_t *crypto_context); ++ ++encryption_context_t *aes_clone_cryptographic_context(encryption_context_t *source); ++#else ++ + struct aes_key_t; + + hashkit_string_st *aes_encrypt(aes_key_t *_aes_key, const char *source, size_t source_length); +@@ -24,3 +45,4 @@ hashkit_string_st *aes_decrypt(aes_key_t *_aes_key, const char *source, size_t s + aes_key_t *aes_create_key(const char *key, const size_t key_length); + + aes_key_t *aes_clone_key(aes_key_t *_aes_key); ++#endif +\ No newline at end of file +diff --git a/src/libhashkit/encrypt.cc b/src/libhashkit/encrypt.cc +index 6446c018..dbc051ae 100644 +--- a/src/libhashkit/encrypt.cc ++++ b/src/libhashkit/encrypt.cc +@@ -15,20 +15,50 @@ + + #include "libhashkit/common.h" + ++#ifdef WITH_OPENSSL ++# include ++#endif ++ + hashkit_string_st *hashkit_encrypt(hashkit_st *kit, const char *source, size_t source_length) { +- return aes_encrypt(static_cast(kit->_key), source, source_length); ++#ifdef WITH_OPENSSL ++ return aes_encrypt((encryption_context_t *) kit->_cryptographic_context, ++ (const unsigned char *) source, source_length); ++#else ++ return aes_encrypt((aes_key_t *) kit->_cryptographic_context, source, ++ source_length); ++#endif + } + + hashkit_string_st *hashkit_decrypt(hashkit_st *kit, const char *source, size_t source_length) { +- return aes_decrypt(static_cast(kit->_key), source, source_length); ++#ifdef WITH_OPENSSL ++ return aes_decrypt((encryption_context_t *) kit->_cryptographic_context, ++ (const unsigned char *) source, source_length); ++#else ++ return aes_decrypt((aes_key_t *)kit->_cryptographic_context, source, source_length); ++#endif + } + ++#ifdef WITH_OPENSSL ++bool hashkit_key(hashkit_st *kit, const char *key, const size_t key_length) { ++ kit->_cryptographic_context = (encryption_context_t *) malloc(sizeof(encryption_context_t)); ++ ((encryption_context_t *) kit->_cryptographic_context)->encryption_context = EVP_CIPHER_CTX_new(); ++ ((encryption_context_t *) kit->_cryptographic_context)->decryption_context = EVP_CIPHER_CTX_new(); ++ if (((encryption_context_t *) kit->_cryptographic_context)->encryption_context == NULL ++ || ((encryption_context_t *) kit->_cryptographic_context)->decryption_context == NULL) ++ { ++ return false; ++ } ++ return aes_initialize((const unsigned char *) key, key_length, ++ (encryption_context_t *) kit->_cryptographic_context); ++} ++#else + bool hashkit_key(hashkit_st *kit, const char *key, const size_t key_length) { +- if (kit->_key) { +- free(kit->_key); ++ if (kit->_cryptographic_context) { ++ free(kit->_cryptographic_context); + } + +- kit->_key = aes_create_key(key, key_length); ++ kit->_cryptographic_context = aes_create_key(key, key_length); + +- return bool(kit->_key); ++ return bool(kit->_cryptographic_context); + } ++#endif +\ No newline at end of file +diff --git a/src/libhashkit/hashkit.cc b/src/libhashkit/hashkit.cc +index 6a179573..46cf6368 100644 +--- a/src/libhashkit/hashkit.cc ++++ b/src/libhashkit/hashkit.cc +@@ -15,6 +15,10 @@ + + #include "libhashkit/common.h" + ++#ifdef WITH_OPENSSL ++# include ++#endif ++ + static inline void _hashkit_init(hashkit_st *self) { + self->base_hash.function = hashkit_one_at_a_time; + self->base_hash.context = NULL; +@@ -23,7 +27,7 @@ static inline void _hashkit_init(hashkit_st *self) { + self->distribution_hash.context = NULL; + + self->flags.is_base_same_distributed = true; +- self->_key = NULL; ++ self->_cryptographic_context = NULL; + } + + static inline hashkit_st *_hashkit_create(hashkit_st *self) { +@@ -52,11 +56,26 @@ hashkit_st *hashkit_create(hashkit_st *self) { + return self; + } + ++#ifdef WITH_OPENSSL ++static void cryptographic_context_free(encryption_context_t *context) { ++ EVP_CIPHER_CTX_free(context->encryption_context); ++ EVP_CIPHER_CTX_free(context->decryption_context); ++ free(context); ++} ++#endif ++ + void hashkit_free(hashkit_st *self) { +- if (self and self->_key) { +- free(self->_key); +- self->_key = NULL; ++#ifdef WITH_OPENSSL ++ if (self and self->_cryptographic_context) { ++ cryptographic_context_free((encryption_context_t *)self->_cryptographic_context); ++ self->_cryptographic_context = NULL; ++ } ++#else ++ if (self and self->_cryptographic_context) { ++ free(self->_cryptographic_context); ++ self->_cryptographic_context = NULL; + } ++#endif + + if (hashkit_is_allocated(self)) { + free(self); +@@ -79,7 +98,21 @@ hashkit_st *hashkit_clone(hashkit_st *destination, const hashkit_st *source) { + destination->base_hash = source->base_hash; + destination->distribution_hash = source->distribution_hash; + destination->flags = source->flags; +- destination->_key = aes_clone_key(static_cast(source->_key)); ++#ifdef WITH_OPENSSL ++ if (destination->_cryptographic_context) { ++ cryptographic_context_free((encryption_context_t *)destination->_cryptographic_context); ++ destination->_cryptographic_context = NULL; ++ } ++ if (source->_cryptographic_context) { ++ destination->_cryptographic_context = ++ aes_clone_cryptographic_context(((encryption_context_t *) source->_cryptographic_context)); ++ if (destination->_cryptographic_context) { ++ ++ } ++ } ++#else ++ destination->_cryptographic_context = aes_clone_key(static_cast(source->_cryptographic_context)); ++#endif + + return destination; + } +diff --git a/src/libhashkit/rijndael.hpp b/src/libhashkit/rijndael.hpp +index 96f48e34..96961f8c 100644 +--- a/src/libhashkit/rijndael.hpp ++++ b/src/libhashkit/rijndael.hpp +@@ -35,4 +35,4 @@ void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 p + #ifdef INTERMEDIATE_VALUE_KAT + void rijndaelEncryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds); + void rijndaelDecryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds); +-#endif /* INTERMEDIATE_VALUE_KAT */ ++#endif /* INTERMEDIATE_VALUE_KAT */ +\ No newline at end of file +diff --git a/src/libmemcached/is.h b/src/libmemcached/is.h +index d73b54e7..3987332f 100644 +--- a/src/libmemcached/is.h ++++ b/src/libmemcached/is.h +@@ -17,7 +17,7 @@ + + /* These are private */ + #define memcached_is_allocated(__object) ((__object)->options.is_allocated) +-#define memcached_is_encrypted(__object) ((__object)->hashkit._key) ++#define memcached_is_encrypted(__object) (!!(__object)->hashkit._cryptographic_context) + #define memcached_is_initialized(__object) ((__object)->options.is_initialized) + #define memcached_is_purging(__object) ((__object)->state.is_purging) + #define memcached_is_processing_input(__object) ((__object)->state.is_processing_input) +-- +2.31.1 + +From b7f446e55146456e368c3926347f4c771afcea8c Mon Sep 17 00:00:00 2001 +From: Michael Wallner +Date: Mon, 12 Jul 2021 15:08:57 +0200 +Subject: [PATCH 2/7] libhashkit/aes: make using openssl configurable + +--- + CMakeConfig.txt | 3 +++ + src/libhashkit/CMakeLists.txt | 16 ++++++++++------ + src/libhashkit/aes.cc | 4 ++-- + src/libhashkit/aes.h | 4 ++-- + src/libhashkit/encrypt.cc | 10 +++++----- + src/libhashkit/hashkit.cc | 8 ++++---- + 6 files changed, 26 insertions(+), 19 deletions(-) + +diff --git a/CMakeConfig.txt b/CMakeConfig.txt +index 973ff824..d8afcaef 100644 +--- a/CMakeConfig.txt ++++ b/CMakeConfig.txt +@@ -65,6 +65,9 @@ if(NOT DEFINED ENV{ENABLE_MEMASLAP}) + endif() + option(ENABLE_MEMASLAP "enable memaslap client" + $ENV{ENABLE_MEMASLAP}) ++option(ENABLE_OPENSSL_CRYPTO ++ "enable OpenSSL's libcrypto instead of bundled AES implementation" ++ $ENV{ENABLE_OPENSSL_CRYPTO}) + + if(BUILD_TESTING) + set(MEMCACHED_BINARY "$ENV{MEMCACHED_BINARY}" +diff --git a/src/libhashkit/CMakeLists.txt b/src/libhashkit/CMakeLists.txt +index d0e03d15..ed3f7f1d 100644 +--- a/src/libhashkit/CMakeLists.txt ++++ b/src/libhashkit/CMakeLists.txt +@@ -40,12 +40,16 @@ target_include_directories(libhashkit PUBLIC + $ + $) + +-find_package(OpenSSL) +-if(NOT OPENSSL_FOUND) +- message(WARNING "crypto library not found") +-else() +- add_compile_definitions(WITH_OPENSSL) +- target_link_libraries(libhashkit PUBLIC OpenSSL::Crypto) ++if(ENABLE_OPENSSL_CRYPTO) ++ find_package(OpenSSL) ++ if(OPENSSL_FOUND) ++ if(OPENSSL_CRYPTO_LIBRARY) ++ target_compile_definitions(libhashkit PRIVATE HAVE_OPENSSL_CRYPTO) ++ target_link_libraries(libhashkit PUBLIC OpenSSL::Crypto) ++ else() ++ message(WARNING "Could not find OpenSSL::Crypto") ++ endif() ++ endif() + endif() + + configure_file(hashkitcon.h.in hashkitcon.h @ONLY) +diff --git a/src/libhashkit/aes.cc b/src/libhashkit/aes.cc +index d4fdad5a..d65a9d91 100644 +--- a/src/libhashkit/aes.cc ++++ b/src/libhashkit/aes.cc +@@ -17,7 +17,7 @@ + + #include + +-#ifdef WITH_OPENSSL ++#ifdef HAVE_OPENSSL_CRYPTO + + #include + +@@ -250,4 +250,4 @@ hashkit_string_st *aes_decrypt(aes_key_t *_aes_key, const char *source, size_t s + + return destination; + } +-#endif +\ No newline at end of file ++#endif +diff --git a/src/libhashkit/aes.h b/src/libhashkit/aes.h +index e021c5f1..243d501f 100644 +--- a/src/libhashkit/aes.h ++++ b/src/libhashkit/aes.h +@@ -15,7 +15,7 @@ + + #pragma once + +-#ifdef WITH_OPENSSL ++#ifdef HAVE_OPENSSL_CRYPTO + + #include + +@@ -45,4 +45,4 @@ hashkit_string_st *aes_decrypt(aes_key_t *_aes_key, const char *source, size_t s + aes_key_t *aes_create_key(const char *key, const size_t key_length); + + aes_key_t *aes_clone_key(aes_key_t *_aes_key); +-#endif +\ No newline at end of file ++#endif +diff --git a/src/libhashkit/encrypt.cc b/src/libhashkit/encrypt.cc +index dbc051ae..e7898a6a 100644 +--- a/src/libhashkit/encrypt.cc ++++ b/src/libhashkit/encrypt.cc +@@ -15,12 +15,12 @@ + + #include "libhashkit/common.h" + +-#ifdef WITH_OPENSSL ++#ifdef HAVE_OPENSSL_CRYPTO + # include + #endif + + hashkit_string_st *hashkit_encrypt(hashkit_st *kit, const char *source, size_t source_length) { +-#ifdef WITH_OPENSSL ++#ifdef HAVE_OPENSSL_CRYPTO + return aes_encrypt((encryption_context_t *) kit->_cryptographic_context, + (const unsigned char *) source, source_length); + #else +@@ -30,7 +30,7 @@ hashkit_string_st *hashkit_encrypt(hashkit_st *kit, const char *source, size_t s + } + + hashkit_string_st *hashkit_decrypt(hashkit_st *kit, const char *source, size_t source_length) { +-#ifdef WITH_OPENSSL ++#ifdef HAVE_OPENSSL_CRYPTO + return aes_decrypt((encryption_context_t *) kit->_cryptographic_context, + (const unsigned char *) source, source_length); + #else +@@ -38,7 +38,7 @@ hashkit_string_st *hashkit_decrypt(hashkit_st *kit, const char *source, size_t s + #endif + } + +-#ifdef WITH_OPENSSL ++#ifdef HAVE_OPENSSL_CRYPTO + bool hashkit_key(hashkit_st *kit, const char *key, const size_t key_length) { + kit->_cryptographic_context = (encryption_context_t *) malloc(sizeof(encryption_context_t)); + ((encryption_context_t *) kit->_cryptographic_context)->encryption_context = EVP_CIPHER_CTX_new(); +@@ -61,4 +61,4 @@ bool hashkit_key(hashkit_st *kit, const char *key, const size_t key_length) { + + return bool(kit->_cryptographic_context); + } +-#endif +\ No newline at end of file ++#endif +diff --git a/src/libhashkit/hashkit.cc b/src/libhashkit/hashkit.cc +index 46cf6368..d15d7372 100644 +--- a/src/libhashkit/hashkit.cc ++++ b/src/libhashkit/hashkit.cc +@@ -15,7 +15,7 @@ + + #include "libhashkit/common.h" + +-#ifdef WITH_OPENSSL ++#ifdef HAVE_OPENSSL_CRYPTO + # include + #endif + +@@ -56,7 +56,7 @@ hashkit_st *hashkit_create(hashkit_st *self) { + return self; + } + +-#ifdef WITH_OPENSSL ++#ifdef HAVE_OPENSSL_CRYPTO + static void cryptographic_context_free(encryption_context_t *context) { + EVP_CIPHER_CTX_free(context->encryption_context); + EVP_CIPHER_CTX_free(context->decryption_context); +@@ -65,7 +65,7 @@ static void cryptographic_context_free(encryption_context_t *context) { + #endif + + void hashkit_free(hashkit_st *self) { +-#ifdef WITH_OPENSSL ++#ifdef HAVE_OPENSSL_CRYPTO + if (self and self->_cryptographic_context) { + cryptographic_context_free((encryption_context_t *)self->_cryptographic_context); + self->_cryptographic_context = NULL; +@@ -98,7 +98,7 @@ hashkit_st *hashkit_clone(hashkit_st *destination, const hashkit_st *source) { + destination->base_hash = source->base_hash; + destination->distribution_hash = source->distribution_hash; + destination->flags = source->flags; +-#ifdef WITH_OPENSSL ++#ifdef HAVE_OPENSSL_CRYPTO + if (destination->_cryptographic_context) { + cryptographic_context_free((encryption_context_t *)destination->_cryptographic_context); + destination->_cryptographic_context = NULL; +-- +2.31.1 + +From 0d7a3e0e040ddf840d656b61f41419c252debcde Mon Sep 17 00:00:00 2001 +From: Michael Wallner +Date: Mon, 12 Jul 2021 15:57:32 +0200 +Subject: [PATCH 3/7] libhashkit/aes: keep API compatible + +--- + include/libhashkit-1.0/hashkit.h | 2 +- + src/libhashkit/encrypt.cc | 28 ++++++++++++++-------------- + src/libhashkit/hashkit.cc | 30 +++++++++++++++--------------- + src/libmemcached/is.h | 2 +- + 4 files changed, 31 insertions(+), 31 deletions(-) + +diff --git a/include/libhashkit-1.0/hashkit.h b/include/libhashkit-1.0/hashkit.h +index 0f67e377..09b7edeb 100644 +--- a/include/libhashkit-1.0/hashkit.h ++++ b/include/libhashkit-1.0/hashkit.h +@@ -49,7 +49,7 @@ struct hashkit_st { + bool is_allocated : 1; + } options; + +- void *_cryptographic_context; ++ void *_key; + }; + + #ifdef __cplusplus +diff --git a/src/libhashkit/encrypt.cc b/src/libhashkit/encrypt.cc +index e7898a6a..effa299f 100644 +--- a/src/libhashkit/encrypt.cc ++++ b/src/libhashkit/encrypt.cc +@@ -21,44 +21,44 @@ + + hashkit_string_st *hashkit_encrypt(hashkit_st *kit, const char *source, size_t source_length) { + #ifdef HAVE_OPENSSL_CRYPTO +- return aes_encrypt((encryption_context_t *) kit->_cryptographic_context, ++ return aes_encrypt((encryption_context_t *) kit->_key, + (const unsigned char *) source, source_length); + #else +- return aes_encrypt((aes_key_t *) kit->_cryptographic_context, source, ++ return aes_encrypt((aes_key_t *) kit->_key, source, + source_length); + #endif + } + + hashkit_string_st *hashkit_decrypt(hashkit_st *kit, const char *source, size_t source_length) { + #ifdef HAVE_OPENSSL_CRYPTO +- return aes_decrypt((encryption_context_t *) kit->_cryptographic_context, ++ return aes_decrypt((encryption_context_t *) kit->_key, + (const unsigned char *) source, source_length); + #else +- return aes_decrypt((aes_key_t *)kit->_cryptographic_context, source, source_length); ++ return aes_decrypt((aes_key_t *)kit->_key, source, source_length); + #endif + } + + #ifdef HAVE_OPENSSL_CRYPTO + bool hashkit_key(hashkit_st *kit, const char *key, const size_t key_length) { +- kit->_cryptographic_context = (encryption_context_t *) malloc(sizeof(encryption_context_t)); +- ((encryption_context_t *) kit->_cryptographic_context)->encryption_context = EVP_CIPHER_CTX_new(); +- ((encryption_context_t *) kit->_cryptographic_context)->decryption_context = EVP_CIPHER_CTX_new(); +- if (((encryption_context_t *) kit->_cryptographic_context)->encryption_context == NULL +- || ((encryption_context_t *) kit->_cryptographic_context)->decryption_context == NULL) ++ kit->_key = (encryption_context_t *) malloc(sizeof(encryption_context_t)); ++ ((encryption_context_t *) kit->_key)->encryption_context = EVP_CIPHER_CTX_new(); ++ ((encryption_context_t *) kit->_key)->decryption_context = EVP_CIPHER_CTX_new(); ++ if (((encryption_context_t *) kit->_key)->encryption_context == NULL ++ || ((encryption_context_t *) kit->_key)->decryption_context == NULL) + { + return false; + } + return aes_initialize((const unsigned char *) key, key_length, +- (encryption_context_t *) kit->_cryptographic_context); ++ (encryption_context_t *) kit->_key); + } + #else + bool hashkit_key(hashkit_st *kit, const char *key, const size_t key_length) { +- if (kit->_cryptographic_context) { +- free(kit->_cryptographic_context); ++ if (kit->_key) { ++ free(kit->_key); + } + +- kit->_cryptographic_context = aes_create_key(key, key_length); ++ kit->_key = aes_create_key(key, key_length); + +- return bool(kit->_cryptographic_context); ++ return bool(kit->_key); + } + #endif +diff --git a/src/libhashkit/hashkit.cc b/src/libhashkit/hashkit.cc +index d15d7372..e61b014d 100644 +--- a/src/libhashkit/hashkit.cc ++++ b/src/libhashkit/hashkit.cc +@@ -27,7 +27,7 @@ static inline void _hashkit_init(hashkit_st *self) { + self->distribution_hash.context = NULL; + + self->flags.is_base_same_distributed = true; +- self->_cryptographic_context = NULL; ++ self->_key = NULL; + } + + static inline hashkit_st *_hashkit_create(hashkit_st *self) { +@@ -66,14 +66,14 @@ static void cryptographic_context_free(encryption_context_t *context) { + + void hashkit_free(hashkit_st *self) { + #ifdef HAVE_OPENSSL_CRYPTO +- if (self and self->_cryptographic_context) { +- cryptographic_context_free((encryption_context_t *)self->_cryptographic_context); +- self->_cryptographic_context = NULL; ++ if (self and self->_key) { ++ cryptographic_context_free((encryption_context_t *)self->_key); ++ self->_key = NULL; + } + #else +- if (self and self->_cryptographic_context) { +- free(self->_cryptographic_context); +- self->_cryptographic_context = NULL; ++ if (self and self->_key) { ++ free(self->_key); ++ self->_key = NULL; + } + #endif + +@@ -99,19 +99,19 @@ hashkit_st *hashkit_clone(hashkit_st *destination, const hashkit_st *source) { + destination->distribution_hash = source->distribution_hash; + destination->flags = source->flags; + #ifdef HAVE_OPENSSL_CRYPTO +- if (destination->_cryptographic_context) { +- cryptographic_context_free((encryption_context_t *)destination->_cryptographic_context); +- destination->_cryptographic_context = NULL; ++ if (destination->_key) { ++ cryptographic_context_free((encryption_context_t *)destination->_key); ++ destination->_key = NULL; + } +- if (source->_cryptographic_context) { +- destination->_cryptographic_context = +- aes_clone_cryptographic_context(((encryption_context_t *) source->_cryptographic_context)); +- if (destination->_cryptographic_context) { ++ if (source->_key) { ++ destination->_key = ++ aes_clone_cryptographic_context(((encryption_context_t *) source->_key)); ++ if (destination->_key) { + + } + } + #else +- destination->_cryptographic_context = aes_clone_key(static_cast(source->_cryptographic_context)); ++ destination->_key = aes_clone_key(static_cast(source->_key)); + #endif + + return destination; +diff --git a/src/libmemcached/is.h b/src/libmemcached/is.h +index 3987332f..229fd9b0 100644 +--- a/src/libmemcached/is.h ++++ b/src/libmemcached/is.h +@@ -17,7 +17,7 @@ + + /* These are private */ + #define memcached_is_allocated(__object) ((__object)->options.is_allocated) +-#define memcached_is_encrypted(__object) (!!(__object)->hashkit._cryptographic_context) ++#define memcached_is_encrypted(__object) (!!(__object)->hashkit._key) + #define memcached_is_initialized(__object) ((__object)->options.is_initialized) + #define memcached_is_purging(__object) ((__object)->state.is_purging) + #define memcached_is_processing_input(__object) ((__object)->state.is_processing_input) +-- +2.31.1 + +From 6f1f694418c7effef13972ea135ce1c735042a8f Mon Sep 17 00:00:00 2001 +From: Michael Wallner +Date: Mon, 12 Jul 2021 15:11:32 +0200 +Subject: [PATCH 4/7] libhashkit/aes: fix logic error in aes_initialize + +--- + src/libhashkit/aes.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libhashkit/aes.cc b/src/libhashkit/aes.cc +index d65a9d91..e4ae96f8 100644 +--- a/src/libhashkit/aes.cc ++++ b/src/libhashkit/aes.cc +@@ -30,7 +30,7 @@ bool aes_initialize(const unsigned char *key, const size_t key_length, + encryption_context_t *crypto_context) { + unsigned char aes_key[AES_KEY_NBYTES]; + unsigned char aes_iv[AES_IV_NBYTES]; +- if (aes_key == NULL || aes_iv == NULL) { ++ if (!key) { + return false; + } + +-- +2.31.1 + +From c8300fc7f692c617f1a583a9cb22732a840e7d3e Mon Sep 17 00:00:00 2001 +From: Michael Wallner +Date: Mon, 12 Jul 2021 15:13:53 +0200 +Subject: [PATCH 5/7] libhashkit/aes: fix code indentation + +--- + src/libhashkit/aes.cc | 94 ++++++++++++++++++++++--------------------- + 1 file changed, 48 insertions(+), 46 deletions(-) + +diff --git a/src/libhashkit/aes.cc b/src/libhashkit/aes.cc +index e4ae96f8..156bcd3d 100644 +--- a/src/libhashkit/aes.cc ++++ b/src/libhashkit/aes.cc +@@ -55,58 +55,60 @@ bool aes_initialize(const unsigned char *key, const size_t key_length, + + hashkit_string_st *aes_encrypt(encryption_context_t *crypto_context, const unsigned char *source, + size_t source_length) { +-EVP_CIPHER_CTX *encryption_context = crypto_context->encryption_context; +-int cipher_length = source_length + EVP_CIPHER_CTX_block_size(encryption_context); +-int final_length = 0; +-unsigned char *cipher_text = (unsigned char *) malloc(cipher_length); +-if (cipher_text == NULL) { +- return NULL; +-} +-if (EVP_EncryptInit_ex(encryption_context, NULL, NULL, NULL, NULL) != 1 +- || EVP_EncryptUpdate(encryption_context, cipher_text, &cipher_length, source, source_length) +- != 1 +- || EVP_EncryptFinal_ex(encryption_context, cipher_text + cipher_length, &final_length) != 1) +-{ +- free(cipher_text); +- return NULL; +-} ++ EVP_CIPHER_CTX *encryption_context = crypto_context->encryption_context; ++ int cipher_length = source_length + EVP_CIPHER_CTX_block_size(encryption_context); ++ int final_length = 0; ++ unsigned char *cipher_text = (unsigned char *) malloc(cipher_length); ++ if (cipher_text == NULL) { ++ return NULL; ++ } ++ if (EVP_EncryptInit_ex(encryption_context, NULL, NULL, NULL, NULL) != 1 ++ || EVP_EncryptUpdate(encryption_context, cipher_text, &cipher_length, source, source_length) ++ != 1 ++ || EVP_EncryptFinal_ex(encryption_context, cipher_text + cipher_length, &final_length) != 1) ++ { ++ free(cipher_text); ++ return NULL; ++ } + +-hashkit_string_st *destination = hashkit_string_create(cipher_length + final_length); +-if (destination == NULL) { +- return NULL; +-} +-char *dest = hashkit_string_c_str_mutable(destination); +-memcpy(dest, cipher_text, cipher_length + final_length); +-hashkit_string_set_length(destination, cipher_length + final_length); +-return destination; ++ hashkit_string_st *destination = hashkit_string_create(cipher_length + final_length); ++ if (destination == NULL) { ++ return NULL; ++ } ++ char *dest = hashkit_string_c_str_mutable(destination); ++ memcpy(dest, cipher_text, cipher_length + final_length); ++ hashkit_string_set_length(destination, cipher_length + final_length); ++ return destination; + } + + hashkit_string_st *aes_decrypt(encryption_context_t *crypto_context, const unsigned char *source, + size_t source_length) { +-EVP_CIPHER_CTX *decryption_context = crypto_context->decryption_context; +-int plain_text_length = source_length; +-int final_length = 0; +-unsigned char *plain_text = (unsigned char *) malloc(plain_text_length); +-if (plain_text == NULL) { +- return NULL; +-} +-if (EVP_DecryptInit_ex(decryption_context, NULL, NULL, NULL, NULL) != 1 +- || EVP_DecryptUpdate(decryption_context, plain_text, &plain_text_length, source, source_length) +- != 1 +- || EVP_DecryptFinal_ex(decryption_context, plain_text + plain_text_length, &final_length) != 1) +-{ +- free(plain_text); +- return NULL; +-} ++ EVP_CIPHER_CTX *decryption_context = crypto_context->decryption_context; ++ int plain_text_length = source_length; ++ int final_length = 0; ++ unsigned char *plain_text = (unsigned char *) malloc(plain_text_length); ++ if (plain_text == NULL) { ++ return NULL; ++ } ++ if (EVP_DecryptInit_ex(decryption_context, NULL, NULL, NULL, NULL) != 1 ++ || EVP_DecryptUpdate(decryption_context, plain_text, &plain_text_length, source, ++ source_length) ++ != 1 ++ || EVP_DecryptFinal_ex(decryption_context, plain_text + plain_text_length, &final_length) ++ != 1) ++ { ++ free(plain_text); ++ return NULL; ++ } + +-hashkit_string_st *destination = hashkit_string_create(plain_text_length + final_length); +-if (destination == NULL) { +- return NULL; +-} +-char *dest = hashkit_string_c_str_mutable(destination); +-memcpy(dest, plain_text, plain_text_length + final_length); +-hashkit_string_set_length(destination, plain_text_length + final_length); +-return destination; ++ hashkit_string_st *destination = hashkit_string_create(plain_text_length + final_length); ++ if (destination == NULL) { ++ return NULL; ++ } ++ char *dest = hashkit_string_c_str_mutable(destination); ++ memcpy(dest, plain_text, plain_text_length + final_length); ++ hashkit_string_set_length(destination, plain_text_length + final_length); ++ return destination; + } + + encryption_context_t *aes_clone_cryptographic_context(encryption_context_t *source) { +-- +2.31.1 + +From 72df8af3b9cc00f590afa31371be571c1169a268 Mon Sep 17 00:00:00 2001 +From: Michael Wallner +Date: Mon, 12 Jul 2021 15:59:57 +0200 +Subject: [PATCH 6/7] libhashkit/aes: simplify code + +--- + src/libhashkit/aes.cc | 125 ++++++++++++++++++++++++-------------- + src/libhashkit/aes.h | 26 +------- + src/libhashkit/encrypt.cc | 31 +--------- + src/libhashkit/hashkit.cc | 37 +---------- + 4 files changed, 87 insertions(+), 132 deletions(-) + +diff --git a/src/libhashkit/aes.cc b/src/libhashkit/aes.cc +index 156bcd3d..86a41dd7 100644 +--- a/src/libhashkit/aes.cc ++++ b/src/libhashkit/aes.cc +@@ -26,45 +26,60 @@ + #define AES_KEY_NBYTES 32 + #define AES_IV_NBYTES 32 + +-bool aes_initialize(const unsigned char *key, const size_t key_length, +- encryption_context_t *crypto_context) { ++struct aes_key_t { ++ EVP_CIPHER_CTX *encryption_context; ++ EVP_CIPHER_CTX *decryption_context; ++}; ++ ++ ++aes_key_t *aes_create_key(const char *key, const size_t key_length) { + unsigned char aes_key[AES_KEY_NBYTES]; + unsigned char aes_iv[AES_IV_NBYTES]; ++ const unsigned char *ukey = (const unsigned char *) key; ++ + if (!key) { +- return false; ++ return NULL; + } + +- int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha256(), NULL, key, key_length, DIGEST_ROUNDS, ++ int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha256(), NULL, ukey, key_length, DIGEST_ROUNDS, + aes_key, aes_iv); + if (i != AES_KEY_NBYTES) { +- return false; ++ return NULL; + } + +- EVP_CIPHER_CTX_init(crypto_context->encryption_context); +- EVP_CIPHER_CTX_init(crypto_context->decryption_context); +- if (EVP_EncryptInit_ex(crypto_context->encryption_context, EVP_aes_256_cbc(), NULL, key, aes_iv) +- != 1 +- || EVP_DecryptInit_ex(crypto_context->decryption_context, EVP_aes_256_cbc(), NULL, key, +- aes_iv) +- != 1) ++ aes_key_t *aes_ctx = (aes_key_t *) malloc(sizeof(aes_key_t)); ++ ++ if (!(aes_ctx->encryption_context = EVP_CIPHER_CTX_new())) { ++ return NULL; ++ } ++ if (!(aes_ctx->decryption_context = EVP_CIPHER_CTX_new())) { ++ EVP_CIPHER_CTX_free(aes_ctx->encryption_context); ++ return NULL; ++ } ++ ++ EVP_CIPHER_CTX_init(aes_ctx->encryption_context); ++ EVP_CIPHER_CTX_init(aes_ctx->decryption_context); ++ if (EVP_EncryptInit_ex(aes_ctx->encryption_context, EVP_aes_256_cbc(), NULL, ukey, aes_iv) != 1 ++ || EVP_DecryptInit_ex(aes_ctx->decryption_context, EVP_aes_256_cbc(), NULL, ukey, aes_iv) != 1) + { +- return false; ++ aes_free_key(aes_ctx); ++ return NULL; + } +- return true; ++ ++ return aes_ctx; + } + +-hashkit_string_st *aes_encrypt(encryption_context_t *crypto_context, const unsigned char *source, +- size_t source_length) { +- EVP_CIPHER_CTX *encryption_context = crypto_context->encryption_context; ++hashkit_string_st *aes_encrypt(aes_key_t *ctx, const char *source, size_t source_length) { ++ EVP_CIPHER_CTX *encryption_context = ctx->encryption_context; + int cipher_length = source_length + EVP_CIPHER_CTX_block_size(encryption_context); + int final_length = 0; ++ const unsigned char *usource = (const unsigned char *) source; + unsigned char *cipher_text = (unsigned char *) malloc(cipher_length); +- if (cipher_text == NULL) { ++ if (!cipher_text) { + return NULL; + } + if (EVP_EncryptInit_ex(encryption_context, NULL, NULL, NULL, NULL) != 1 +- || EVP_EncryptUpdate(encryption_context, cipher_text, &cipher_length, source, source_length) +- != 1 ++ || EVP_EncryptUpdate(encryption_context, cipher_text, &cipher_length, usource, source_length) != 1 + || EVP_EncryptFinal_ex(encryption_context, cipher_text + cipher_length, &final_length) != 1) + { + free(cipher_text); +@@ -72,7 +87,7 @@ hashkit_string_st *aes_encrypt(encryption_context_t *crypto_context, const unsig + } + + hashkit_string_st *destination = hashkit_string_create(cipher_length + final_length); +- if (destination == NULL) { ++ if (!destination) { + return NULL; + } + char *dest = hashkit_string_c_str_mutable(destination); +@@ -81,28 +96,25 @@ hashkit_string_st *aes_encrypt(encryption_context_t *crypto_context, const unsig + return destination; + } + +-hashkit_string_st *aes_decrypt(encryption_context_t *crypto_context, const unsigned char *source, +- size_t source_length) { +- EVP_CIPHER_CTX *decryption_context = crypto_context->decryption_context; ++hashkit_string_st *aes_decrypt(aes_key_t *ctx, const char *source, size_t source_length) { ++ EVP_CIPHER_CTX *decryption_context = ctx->decryption_context; + int plain_text_length = source_length; + int final_length = 0; ++ const unsigned char *usource = (const unsigned char *) source; + unsigned char *plain_text = (unsigned char *) malloc(plain_text_length); +- if (plain_text == NULL) { ++ if (!plain_text) { + return NULL; + } + if (EVP_DecryptInit_ex(decryption_context, NULL, NULL, NULL, NULL) != 1 +- || EVP_DecryptUpdate(decryption_context, plain_text, &plain_text_length, source, +- source_length) +- != 1 +- || EVP_DecryptFinal_ex(decryption_context, plain_text + plain_text_length, &final_length) +- != 1) ++ || EVP_DecryptUpdate(decryption_context, plain_text, &plain_text_length, usource, source_length) != 1 ++ || EVP_DecryptFinal_ex(decryption_context, plain_text + plain_text_length, &final_length) != 1) + { + free(plain_text); + return NULL; + } + + hashkit_string_st *destination = hashkit_string_create(plain_text_length + final_length); +- if (destination == NULL) { ++ if (!destination) { + return NULL; + } + char *dest = hashkit_string_c_str_mutable(destination); +@@ -111,22 +123,40 @@ hashkit_string_st *aes_decrypt(encryption_context_t *crypto_context, const unsig + return destination; + } + +-encryption_context_t *aes_clone_cryptographic_context(encryption_context_t *source) { +- encryption_context_t *new_context = (encryption_context_t *) malloc(sizeof(encryption_context_t)); +- if (new_context == NULL) ++aes_key_t *aes_clone_key(aes_key_t *old_context) { ++ if (!old_context) { + return NULL; ++ } + +- new_context->encryption_context = EVP_CIPHER_CTX_new(); +- new_context->decryption_context = EVP_CIPHER_CTX_new(); +- if (new_context->encryption_context == NULL || new_context->decryption_context == NULL) { +- free(new_context); +- return NULL; ++ aes_key_t *new_context = (aes_key_t *) malloc(sizeof(aes_key_t)); ++ if (new_context) { ++ new_context->encryption_context = EVP_CIPHER_CTX_new(); ++ new_context->decryption_context = EVP_CIPHER_CTX_new(); ++ if (!new_context->encryption_context || !new_context->decryption_context) { ++ aes_free_key(new_context); ++ return NULL; ++ } ++ EVP_CIPHER_CTX_copy(new_context->encryption_context, old_context->encryption_context); ++ EVP_CIPHER_CTX_copy(new_context->decryption_context, old_context->decryption_context); + } +- EVP_CIPHER_CTX_copy(new_context->encryption_context, source->encryption_context); +- EVP_CIPHER_CTX_copy(new_context->decryption_context, source->decryption_context); ++ + return new_context; + } + ++void aes_free_key(aes_key_t *context) { ++ if (context) { ++ if (context->encryption_context) { ++ EVP_CIPHER_CTX_free(context->encryption_context); ++ context->encryption_context = NULL; ++ } ++ if (context->decryption_context) { ++ EVP_CIPHER_CTX_free(context->decryption_context); ++ context->decryption_context = NULL; ++ } ++ free(context); ++ } ++} ++ + #else + + # include "libhashkit/rijndael.hpp" +@@ -172,7 +202,7 @@ aes_key_t *aes_create_key(const char *key, const size_t key_length) { + } + + aes_key_t *aes_clone_key(aes_key_t *_aes_key) { +- if (_aes_key == NULL) { ++ if (!_aes_key) { + return NULL; + } + +@@ -185,7 +215,7 @@ aes_key_t *aes_clone_key(aes_key_t *_aes_key) { + } + + hashkit_string_st *aes_encrypt(aes_key_t *_aes_key, const char *source, size_t source_length) { +- if (_aes_key == NULL) { ++ if (!_aes_key) { + return NULL; + } + +@@ -214,7 +244,7 @@ hashkit_string_st *aes_encrypt(aes_key_t *_aes_key, const char *source, size_t s + } + + hashkit_string_st *aes_decrypt(aes_key_t *_aes_key, const char *source, size_t source_length) { +- if (_aes_key == NULL) { ++ if (!_aes_key) { + return NULL; + } + +@@ -252,4 +282,11 @@ hashkit_string_st *aes_decrypt(aes_key_t *_aes_key, const char *source, size_t s + + return destination; + } ++ ++void aes_free_key(aes_key_t *key) { ++ if (key) { ++ free(key); ++ } ++} ++ + #endif +diff --git a/src/libhashkit/aes.h b/src/libhashkit/aes.h +index 243d501f..4d3e6d7f 100644 +--- a/src/libhashkit/aes.h ++++ b/src/libhashkit/aes.h +@@ -15,34 +15,14 @@ + + #pragma once + +-#ifdef HAVE_OPENSSL_CRYPTO +- +-#include +- +-typedef struct encryption_context { +- EVP_CIPHER_CTX *encryption_context; +- EVP_CIPHER_CTX *decryption_context; +-} encryption_context_t; +- +-hashkit_string_st *aes_encrypt(encryption_context_t *crypto_context, const unsigned char *source, +- size_t source_length); +- +-hashkit_string_st *aes_decrypt(encryption_context_t *crypto_context, const unsigned char *source, +- size_t source_length); +- +-bool aes_initialize(const unsigned char *key, const size_t key_length, +- encryption_context_t *crypto_context); +- +-encryption_context_t *aes_clone_cryptographic_context(encryption_context_t *source); +-#else +- + struct aes_key_t; + + hashkit_string_st *aes_encrypt(aes_key_t *_aes_key, const char *source, size_t source_length); + + hashkit_string_st *aes_decrypt(aes_key_t *_aes_key, const char *source, size_t source_length); + +-aes_key_t *aes_create_key(const char *key, const size_t key_length); ++aes_key_t *aes_create_key(const char *key, size_t key_length); + + aes_key_t *aes_clone_key(aes_key_t *_aes_key); +-#endif ++ ++void aes_free_key(aes_key_t *_aes_key); +diff --git a/src/libhashkit/encrypt.cc b/src/libhashkit/encrypt.cc +index effa299f..ff269c05 100644 +--- a/src/libhashkit/encrypt.cc ++++ b/src/libhashkit/encrypt.cc +@@ -15,50 +15,21 @@ + + #include "libhashkit/common.h" + +-#ifdef HAVE_OPENSSL_CRYPTO +-# include +-#endif +- + hashkit_string_st *hashkit_encrypt(hashkit_st *kit, const char *source, size_t source_length) { +-#ifdef HAVE_OPENSSL_CRYPTO +- return aes_encrypt((encryption_context_t *) kit->_key, +- (const unsigned char *) source, source_length); +-#else + return aes_encrypt((aes_key_t *) kit->_key, source, + source_length); +-#endif + } + + hashkit_string_st *hashkit_decrypt(hashkit_st *kit, const char *source, size_t source_length) { +-#ifdef HAVE_OPENSSL_CRYPTO +- return aes_decrypt((encryption_context_t *) kit->_key, +- (const unsigned char *) source, source_length); +-#else + return aes_decrypt((aes_key_t *)kit->_key, source, source_length); +-#endif + } + +-#ifdef HAVE_OPENSSL_CRYPTO +-bool hashkit_key(hashkit_st *kit, const char *key, const size_t key_length) { +- kit->_key = (encryption_context_t *) malloc(sizeof(encryption_context_t)); +- ((encryption_context_t *) kit->_key)->encryption_context = EVP_CIPHER_CTX_new(); +- ((encryption_context_t *) kit->_key)->decryption_context = EVP_CIPHER_CTX_new(); +- if (((encryption_context_t *) kit->_key)->encryption_context == NULL +- || ((encryption_context_t *) kit->_key)->decryption_context == NULL) +- { +- return false; +- } +- return aes_initialize((const unsigned char *) key, key_length, +- (encryption_context_t *) kit->_key); +-} +-#else + bool hashkit_key(hashkit_st *kit, const char *key, const size_t key_length) { + if (kit->_key) { +- free(kit->_key); ++ aes_free_key((aes_key_t *) kit->_key); + } + + kit->_key = aes_create_key(key, key_length); + + return bool(kit->_key); + } +-#endif +diff --git a/src/libhashkit/hashkit.cc b/src/libhashkit/hashkit.cc +index e61b014d..63b7f62e 100644 +--- a/src/libhashkit/hashkit.cc ++++ b/src/libhashkit/hashkit.cc +@@ -15,10 +15,6 @@ + + #include "libhashkit/common.h" + +-#ifdef HAVE_OPENSSL_CRYPTO +-# include +-#endif +- + static inline void _hashkit_init(hashkit_st *self) { + self->base_hash.function = hashkit_one_at_a_time; + self->base_hash.context = NULL; +@@ -56,26 +52,11 @@ hashkit_st *hashkit_create(hashkit_st *self) { + return self; + } + +-#ifdef HAVE_OPENSSL_CRYPTO +-static void cryptographic_context_free(encryption_context_t *context) { +- EVP_CIPHER_CTX_free(context->encryption_context); +- EVP_CIPHER_CTX_free(context->decryption_context); +- free(context); +-} +-#endif +- + void hashkit_free(hashkit_st *self) { +-#ifdef HAVE_OPENSSL_CRYPTO + if (self and self->_key) { +- cryptographic_context_free((encryption_context_t *)self->_key); ++ aes_free_key((aes_key_t *) self->_key); + self->_key = NULL; + } +-#else +- if (self and self->_key) { +- free(self->_key); +- self->_key = NULL; +- } +-#endif + + if (hashkit_is_allocated(self)) { + free(self); +@@ -98,21 +79,7 @@ hashkit_st *hashkit_clone(hashkit_st *destination, const hashkit_st *source) { + destination->base_hash = source->base_hash; + destination->distribution_hash = source->distribution_hash; + destination->flags = source->flags; +-#ifdef HAVE_OPENSSL_CRYPTO +- if (destination->_key) { +- cryptographic_context_free((encryption_context_t *)destination->_key); +- destination->_key = NULL; +- } +- if (source->_key) { +- destination->_key = +- aes_clone_cryptographic_context(((encryption_context_t *) source->_key)); +- if (destination->_key) { +- +- } +- } +-#else +- destination->_key = aes_clone_key(static_cast(source->_key)); +-#endif ++ destination->_key = aes_clone_key((aes_key_t *) source->_key); + + return destination; + } +-- +2.31.1 + diff --git a/libmemcached-awesome-catch.patch b/libmemcached-awesome-catch.patch new file mode 100644 index 0000000..3950dd1 --- /dev/null +++ b/libmemcached-awesome-catch.patch @@ -0,0 +1,905 @@ +From ec4b275c7dab0af781c8e2571021d4821736eef9 Mon Sep 17 00:00:00 2001 +From: Michael Wallner +Date: Fri, 25 Jun 2021 08:17:53 +0200 +Subject: [PATCH] fix gh issue #113 + +--- + ChangeLog-1.1.md | 8 + + docs/source/ChangeLog-1.1.rst | 12 + + scripts/download_catch2.sh | 5 + + test/lib/catch.hpp | 548 +++++++++++++++++++++------------- + 4 files changed, 368 insertions(+), 205 deletions(-) + create mode 100755 scripts/download_catch2.sh + +diff --git a/test/lib/catch.hpp b/test/lib/catch.hpp +index cf1fae15..36eaeb27 100644 +--- a/test/lib/catch.hpp ++++ b/test/lib/catch.hpp +@@ -1,9 +1,9 @@ + /* +- * Catch v2.13.0 +- * Generated: 2020-07-12 20:07:49.015950 ++ * Catch v2.13.6 ++ * Generated: 2021-04-16 18:23:38.044268 + * ---------------------------------------------------------- + * This file has been merged from multiple headers. Please don't edit it directly +- * Copyright (c) 2020 Two Blue Cubes Ltd. All rights reserved. ++ * Copyright (c) 2021 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +@@ -15,7 +15,7 @@ + + #define CATCH_VERSION_MAJOR 2 + #define CATCH_VERSION_MINOR 13 +-#define CATCH_VERSION_PATCH 0 ++#define CATCH_VERSION_PATCH 6 + + #ifdef __clang__ + # pragma clang system_header +@@ -66,13 +66,16 @@ + #if !defined(CATCH_CONFIG_IMPL_ONLY) + // start catch_platform.h + ++// See e.g.: ++// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html + #ifdef __APPLE__ +-# include +-# if TARGET_OS_OSX == 1 +-# define CATCH_PLATFORM_MAC +-# elif TARGET_OS_IPHONE == 1 +-# define CATCH_PLATFORM_IPHONE +-# endif ++# include ++# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ ++ (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) ++# define CATCH_PLATFORM_MAC ++# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) ++# define CATCH_PLATFORM_IPHONE ++# endif + + #elif defined(linux) || defined(__linux) || defined(__linux__) + # define CATCH_PLATFORM_LINUX +@@ -132,13 +135,9 @@ namespace Catch { + + #endif + +-#if defined(__cpp_lib_uncaught_exceptions) +-# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +-#endif +- +-// We have to avoid both ICC and Clang, because they try to mask themselves +-// as gcc, and we want only GCC in this block +-#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) ++// Only GCC compiler should be used in this block, so other compilers trying to ++// mask themselves as GCC should be ignored. ++#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) + # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) + # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) + +@@ -162,7 +161,7 @@ namespace Catch { + // ``` + // + // Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. +-# if !defined(__ibmxl__) ++# if !defined(__ibmxl__) && !defined(__CUDACC__) + # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ + # endif + +@@ -244,10 +243,6 @@ namespace Catch { + # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) + # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) + +-# if _MSC_VER >= 1900 // Visual Studio 2015 or newer +-# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +-# endif +- + // Universal Windows platform does not support SEH + // Or console colours (or console at all...) + # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +@@ -330,7 +325,10 @@ namespace Catch { + + // Check if byte is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) +- # define CATCH_INTERNAL_CONFIG_CPP17_BYTE ++ # include ++ # if __cpp_lib_byte > 0 ++ # define CATCH_INTERNAL_CONFIG_CPP17_BYTE ++ # endif + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if variant is available and usable +@@ -373,10 +371,6 @@ namespace Catch { + # define CATCH_CONFIG_CPP17_OPTIONAL + #endif + +-#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) +-# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +-#endif +- + #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) + # define CATCH_CONFIG_CPP17_STRING_VIEW + #endif +@@ -1105,7 +1099,7 @@ struct AutoReg : NonCopyable { + int index = 0; \ + constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\ + using expander = int[];\ +- (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \ ++ (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \ + }\ + };\ + static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ +@@ -1151,7 +1145,7 @@ struct AutoReg : NonCopyable { + constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\ + constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\ + constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\ +- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */\ ++ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++)... };/* NOLINT */\ + } \ + }; \ + static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \ +@@ -1195,7 +1189,7 @@ struct AutoReg : NonCopyable { + void reg_tests() { \ + int index = 0; \ + using expander = int[]; \ +- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */\ ++ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */\ + } \ + };\ + static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \ +@@ -1229,7 +1223,7 @@ struct AutoReg : NonCopyable { + int index = 0; \ + constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\ + using expander = int[];\ +- (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \ ++ (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \ + }\ + };\ + static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ +@@ -1278,7 +1272,7 @@ struct AutoReg : NonCopyable { + constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\ + constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\ + constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\ +- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */ \ ++ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++)... };/* NOLINT */ \ + }\ + };\ + static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ +@@ -1325,7 +1319,7 @@ struct AutoReg : NonCopyable { + void reg_tests(){\ + int index = 0;\ + using expander = int[];\ +- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */ \ ++ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \ + }\ + };\ + static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ +@@ -1829,8 +1823,8 @@ namespace Catch { + #endif + + namespace Detail { +- template +- std::string rangeToString(InputIterator first, InputIterator last) { ++ template ++ std::string rangeToString(InputIterator first, Sentinel last) { + ReusableStringStream rss; + rss << "{ "; + if (first != last) { +@@ -7063,8 +7057,8 @@ namespace Catch { + double b2 = bias - z1; + double a1 = a(b1); + double a2 = a(b2); +- auto lo = std::max(cumn(a1), 0); +- auto hi = std::min(cumn(a2), n - 1); ++ auto lo = (std::max)(cumn(a1), 0); ++ auto hi = (std::min)(cumn(a2), n - 1); + + return { point, resample[lo], resample[hi], confidence_level }; + } +@@ -7133,7 +7127,9 @@ namespace Catch { + } + template + EnvironmentEstimate> estimate_clock_cost(FloatDuration resolution) { +- auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration(clock_cost_estimation_time_limit)); ++ auto time_limit = (std::min)( ++ resolution * clock_cost_estimation_tick_limit, ++ FloatDuration(clock_cost_estimation_time_limit)); + auto time_clock = [](int k) { + return Detail::measure([k] { + for (int i = 0; i < k; ++i) { +@@ -7611,6 +7607,10 @@ namespace TestCaseTracking { + + void addInitialFilters( std::vector const& filters ); + void addNextFilters( std::vector const& filters ); ++ //! Returns filters active in this tracker ++ std::vector const& getFilters() const; ++ //! Returns whitespace-trimmed name of the tracked section ++ std::string const& trimmedName() const; + }; + + } // namespace TestCaseTracking +@@ -7776,7 +7776,7 @@ namespace Catch { + double sb = stddev.point; + double mn = mean.point / n; + double mg_min = mn / 2.; +- double sg = std::min(mg_min / 4., sb / std::sqrt(n)); ++ double sg = (std::min)(mg_min / 4., sb / std::sqrt(n)); + double sg2 = sg * sg; + double sb2 = sb * sb; + +@@ -7795,7 +7795,7 @@ namespace Catch { + return (nc / n) * (sb2 - nc * sg2); + }; + +- return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2; ++ return (std::min)(var_out(1), var_out((std::min)(c_max(0.), c_max(mg_min)))) / sb2; + } + + bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector::iterator first, std::vector::iterator last) { +@@ -7985,86 +7985,58 @@ namespace Catch { + + // start catch_fatal_condition.h + +-// start catch_windows_h_proxy.h +- +- +-#if defined(CATCH_PLATFORM_WINDOWS) +- +-#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) +-# define CATCH_DEFINED_NOMINMAX +-# define NOMINMAX +-#endif +-#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) +-# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN +-# define WIN32_LEAN_AND_MEAN +-#endif +- +-#ifdef __AFXDLL +-#include +-#else +-#include +-#endif +- +-#ifdef CATCH_DEFINED_NOMINMAX +-# undef NOMINMAX +-#endif +-#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN +-# undef WIN32_LEAN_AND_MEAN +-#endif +- +-#endif // defined(CATCH_PLATFORM_WINDOWS) +- +-// end catch_windows_h_proxy.h +-#if defined( CATCH_CONFIG_WINDOWS_SEH ) ++#include + + namespace Catch { + +- struct FatalConditionHandler { +- +- static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo); ++ // Wrapper for platform-specific fatal error (signals/SEH) handlers ++ // ++ // Tries to be cooperative with other handlers, and not step over ++ // other handlers. This means that unknown structured exceptions ++ // are passed on, previous signal handlers are called, and so on. ++ // ++ // Can only be instantiated once, and assumes that once a signal ++ // is caught, the binary will end up terminating. Thus, there ++ class FatalConditionHandler { ++ bool m_started = false; ++ ++ // Install/disengage implementation for specific platform. ++ // Should be if-defed to work on current platform, can assume ++ // engage-disengage 1:1 pairing. ++ void engage_platform(); ++ void disengage_platform(); ++ public: ++ // Should also have platform-specific implementations as needed + FatalConditionHandler(); +- static void reset(); + ~FatalConditionHandler(); + +- private: +- static bool isSet; +- static ULONG guaranteeSize; +- static PVOID exceptionHandlerHandle; +- }; +- +-} // namespace Catch +- +-#elif defined ( CATCH_CONFIG_POSIX_SIGNALS ) +- +-#include +- +-namespace Catch { +- +- struct FatalConditionHandler { +- +- static bool isSet; +- static struct sigaction oldSigActions[]; +- static stack_t oldSigStack; +- static char altStackMem[]; +- +- static void handleSignal( int sig ); ++ void engage() { ++ assert(!m_started && "Handler cannot be installed twice."); ++ m_started = true; ++ engage_platform(); ++ } + +- FatalConditionHandler(); +- ~FatalConditionHandler(); +- static void reset(); ++ void disengage() { ++ assert(m_started && "Handler cannot be uninstalled without being installed first"); ++ m_started = false; ++ disengage_platform(); ++ } + }; + +-} // namespace Catch +- +-#else +- +-namespace Catch { +- struct FatalConditionHandler { +- void reset(); ++ //! Simple RAII guard for (dis)engaging the FatalConditionHandler ++ class FatalConditionHandlerGuard { ++ FatalConditionHandler* m_handler; ++ public: ++ FatalConditionHandlerGuard(FatalConditionHandler* handler): ++ m_handler(handler) { ++ m_handler->engage(); ++ } ++ ~FatalConditionHandlerGuard() { ++ m_handler->disengage(); ++ } + }; +-} + +-#endif ++} // end namespace Catch + + // end catch_fatal_condition.h + #include +@@ -8190,6 +8162,7 @@ namespace Catch { + std::vector m_unfinishedSections; + std::vector m_activeSections; + TrackerContext m_trackerContext; ++ FatalConditionHandler m_fatalConditionhandler; + bool m_lastAssertionPassed = false; + bool m_shouldReportUnexpected = true; + bool m_includeSuccessfulResults; +@@ -10062,6 +10035,36 @@ namespace Catch { + } + + // end catch_errno_guard.h ++// start catch_windows_h_proxy.h ++ ++ ++#if defined(CATCH_PLATFORM_WINDOWS) ++ ++#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) ++# define CATCH_DEFINED_NOMINMAX ++# define NOMINMAX ++#endif ++#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) ++# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN ++# define WIN32_LEAN_AND_MEAN ++#endif ++ ++#ifdef __AFXDLL ++#include ++#else ++#include ++#endif ++ ++#ifdef CATCH_DEFINED_NOMINMAX ++# undef NOMINMAX ++#endif ++#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN ++# undef WIN32_LEAN_AND_MEAN ++#endif ++ ++#endif // defined(CATCH_PLATFORM_WINDOWS) ++ ++// end catch_windows_h_proxy.h + #include + + namespace Catch { +@@ -10578,7 +10581,7 @@ namespace Catch { + // Extracts the actual name part of an enum instance + // In other words, it returns the Blue part of Bikeshed::Colour::Blue + StringRef extractInstanceName(StringRef enumInstance) { +- // Find last occurence of ":" ++ // Find last occurrence of ":" + size_t name_start = enumInstance.size(); + while (name_start > 0 && enumInstance[name_start - 1] != ':') { + --name_start; +@@ -10740,25 +10743,47 @@ namespace Catch { + // end catch_exception_translator_registry.cpp + // start catch_fatal_condition.cpp + +-#if defined(__GNUC__) +-# pragma GCC diagnostic push +-# pragma GCC diagnostic ignored "-Wmissing-field-initializers" +-#endif ++#include ++ ++#if !defined( CATCH_CONFIG_WINDOWS_SEH ) && !defined( CATCH_CONFIG_POSIX_SIGNALS ) ++ ++namespace Catch { ++ ++ // If neither SEH nor signal handling is required, the handler impls ++ // do not have to do anything, and can be empty. ++ void FatalConditionHandler::engage_platform() {} ++ void FatalConditionHandler::disengage_platform() {} ++ FatalConditionHandler::FatalConditionHandler() = default; ++ FatalConditionHandler::~FatalConditionHandler() = default; ++ ++} // end namespace Catch ++ ++#endif // !CATCH_CONFIG_WINDOWS_SEH && !CATCH_CONFIG_POSIX_SIGNALS ++ ++#if defined( CATCH_CONFIG_WINDOWS_SEH ) && defined( CATCH_CONFIG_POSIX_SIGNALS ) ++#error "Inconsistent configuration: Windows' SEH handling and POSIX signals cannot be enabled at the same time" ++#endif // CATCH_CONFIG_WINDOWS_SEH && CATCH_CONFIG_POSIX_SIGNALS + + #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS ) + + namespace { +- // Report the error condition ++ //! Signals fatal error message to the run context + void reportFatal( char const * const message ) { + Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message ); + } +-} + +-#endif // signals/SEH handling ++ //! Minimal size Catch2 needs for its own fatal error handling. ++ //! Picked anecdotally, so it might not be sufficient on all ++ //! platforms, and for all configurations. ++ constexpr std::size_t minStackSizeForErrors = 32 * 1024; ++} // end unnamed namespace ++ ++#endif // CATCH_CONFIG_WINDOWS_SEH || CATCH_CONFIG_POSIX_SIGNALS + + #if defined( CATCH_CONFIG_WINDOWS_SEH ) + + namespace Catch { ++ + struct SignalDefs { DWORD id; const char* name; }; + + // There is no 1-1 mapping between signals and windows exceptions. +@@ -10771,7 +10796,7 @@ namespace Catch { + { static_cast(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" }, + }; + +- LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { ++ static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { + for (auto const& def : signalDefs) { + if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) { + reportFatal(def.name); +@@ -10782,38 +10807,50 @@ namespace Catch { + return EXCEPTION_CONTINUE_SEARCH; + } + ++ // Since we do not support multiple instantiations, we put these ++ // into global variables and rely on cleaning them up in outlined ++ // constructors/destructors ++ static PVOID exceptionHandlerHandle = nullptr; ++ ++ // For MSVC, we reserve part of the stack memory for handling ++ // memory overflow structured exception. + FatalConditionHandler::FatalConditionHandler() { +- isSet = true; +- // 32k seems enough for Catch to handle stack overflow, +- // but the value was found experimentally, so there is no strong guarantee +- guaranteeSize = 32 * 1024; +- exceptionHandlerHandle = nullptr; ++ ULONG guaranteeSize = static_cast(minStackSizeForErrors); ++ if (!SetThreadStackGuarantee(&guaranteeSize)) { ++ // We do not want to fully error out, because needing ++ // the stack reserve should be rare enough anyway. ++ Catch::cerr() ++ << "Failed to reserve piece of stack." ++ << " Stack overflows will not be reported successfully."; ++ } ++ } ++ ++ // We do not attempt to unset the stack guarantee, because ++ // Windows does not support lowering the stack size guarantee. ++ FatalConditionHandler::~FatalConditionHandler() = default; ++ ++ void FatalConditionHandler::engage_platform() { + // Register as first handler in current chain + exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); +- // Pass in guarantee size to be filled +- SetThreadStackGuarantee(&guaranteeSize); ++ if (!exceptionHandlerHandle) { ++ CATCH_RUNTIME_ERROR("Could not register vectored exception handler"); ++ } + } + +- void FatalConditionHandler::reset() { +- if (isSet) { +- RemoveVectoredExceptionHandler(exceptionHandlerHandle); +- SetThreadStackGuarantee(&guaranteeSize); +- exceptionHandlerHandle = nullptr; +- isSet = false; ++ void FatalConditionHandler::disengage_platform() { ++ if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) { ++ CATCH_RUNTIME_ERROR("Could not unregister vectored exception handler"); + } ++ exceptionHandlerHandle = nullptr; + } + +- FatalConditionHandler::~FatalConditionHandler() { +- reset(); +- } ++} // end namespace Catch + +-bool FatalConditionHandler::isSet = false; +-ULONG FatalConditionHandler::guaranteeSize = 0; +-PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr; ++#endif // CATCH_CONFIG_WINDOWS_SEH + +-} // namespace Catch ++#if defined( CATCH_CONFIG_POSIX_SIGNALS ) + +-#elif defined( CATCH_CONFIG_POSIX_SIGNALS ) ++#include + + namespace Catch { + +@@ -10822,10 +10859,6 @@ namespace Catch { + const char* name; + }; + +- // 32kb for the alternate stack seems to be sufficient. However, this value +- // is experimentally determined, so that's not guaranteed. +- static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ; +- + static SignalDefs signalDefs[] = { + { SIGINT, "SIGINT - Terminal interrupt signal" }, + { SIGILL, "SIGILL - Illegal instruction signal" }, +@@ -10835,7 +10868,32 @@ namespace Catch { + { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } + }; + +- void FatalConditionHandler::handleSignal( int sig ) { ++// Older GCCs trigger -Wmissing-field-initializers for T foo = {} ++// which is zero initialization, but not explicit. We want to avoid ++// that. ++#if defined(__GNUC__) ++# pragma GCC diagnostic push ++# pragma GCC diagnostic ignored "-Wmissing-field-initializers" ++#endif ++ ++ static char* altStackMem = nullptr; ++ static std::size_t altStackSize = 0; ++ static stack_t oldSigStack{}; ++ static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]{}; ++ ++ static void restorePreviousSignalHandlers() { ++ // We set signal handlers back to the previous ones. Hopefully ++ // nobody overwrote them in the meantime, and doesn't expect ++ // their signal handlers to live past ours given that they ++ // installed them after ours.. ++ for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { ++ sigaction(signalDefs[i].id, &oldSigActions[i], nullptr); ++ } ++ // Return the old stack ++ sigaltstack(&oldSigStack, nullptr); ++ } ++ ++ static void handleSignal( int sig ) { + char const * name = ""; + for (auto const& def : signalDefs) { + if (sig == def.id) { +@@ -10843,16 +10901,33 @@ namespace Catch { + break; + } + } +- reset(); +- reportFatal(name); ++ // We need to restore previous signal handlers and let them do ++ // their thing, so that the users can have the debugger break ++ // when a signal is raised, and so on. ++ restorePreviousSignalHandlers(); ++ reportFatal( name ); + raise( sig ); + } + + FatalConditionHandler::FatalConditionHandler() { +- isSet = true; ++ assert(!altStackMem && "Cannot initialize POSIX signal handler when one already exists"); ++ if (altStackSize == 0) { ++ altStackSize = std::max(static_cast(SIGSTKSZ), minStackSizeForErrors); ++ } ++ altStackMem = new char[altStackSize](); ++ } ++ ++ FatalConditionHandler::~FatalConditionHandler() { ++ delete[] altStackMem; ++ // We signal that another instance can be constructed by zeroing ++ // out the pointer. ++ altStackMem = nullptr; ++ } ++ ++ void FatalConditionHandler::engage_platform() { + stack_t sigStack; + sigStack.ss_sp = altStackMem; +- sigStack.ss_size = sigStackSize; ++ sigStack.ss_size = altStackSize; + sigStack.ss_flags = 0; + sigaltstack(&sigStack, &oldSigStack); + struct sigaction sa = { }; +@@ -10864,40 +10939,17 @@ namespace Catch { + } + } + +- FatalConditionHandler::~FatalConditionHandler() { +- reset(); +- } ++#if defined(__GNUC__) ++# pragma GCC diagnostic pop ++#endif + +- void FatalConditionHandler::reset() { +- if( isSet ) { +- // Set signals back to previous values -- hopefully nobody overwrote them in the meantime +- for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) { +- sigaction(signalDefs[i].id, &oldSigActions[i], nullptr); +- } +- // Return the old stack +- sigaltstack(&oldSigStack, nullptr); +- isSet = false; +- } ++ void FatalConditionHandler::disengage_platform() { ++ restorePreviousSignalHandlers(); + } + +- bool FatalConditionHandler::isSet = false; +- struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {}; +- stack_t FatalConditionHandler::oldSigStack = {}; +- char FatalConditionHandler::altStackMem[sigStackSize] = {}; +- +-} // namespace Catch +- +-#else +- +-namespace Catch { +- void FatalConditionHandler::reset() {} +-} +- +-#endif // signals/SEH handling ++} // end namespace Catch + +-#if defined(__GNUC__) +-# pragma GCC diagnostic pop +-#endif ++#endif // CATCH_CONFIG_POSIX_SIGNALS + // end catch_fatal_condition.cpp + // start catch_generators.cpp + +@@ -11452,7 +11504,8 @@ namespace { + return lhs == rhs; + } + +- auto ulpDiff = std::abs(lc - rc); ++ // static cast as a workaround for IBM XLC ++ auto ulpDiff = std::abs(static_cast(lc - rc)); + return static_cast(ulpDiff) <= maxUlpDiff; + } + +@@ -11626,7 +11679,6 @@ Floating::WithinRelMatcher WithinRel(float target) { + + } // namespace Matchers + } // namespace Catch +- + // end catch_matchers_floating.cpp + // start catch_matchers_generic.cpp + +@@ -12042,7 +12094,7 @@ namespace Catch { + if (tmpnam_s(m_buffer)) { + CATCH_RUNTIME_ERROR("Could not get a temp filename"); + } +- if (fopen_s(&m_file, m_buffer, "w")) { ++ if (fopen_s(&m_file, m_buffer, "w+")) { + char buffer[100]; + if (strerror_s(buffer, errno)) { + CATCH_RUNTIME_ERROR("Could not translate errno to a string"); +@@ -12580,13 +12632,53 @@ namespace Catch { + // `SECTION`s. + // **The check for m_children.empty cannot be removed**. + // doing so would break `GENERATE` _not_ followed by `SECTION`s. +- const bool should_wait_for_child = +- !m_children.empty() && +- std::find_if( m_children.begin(), +- m_children.end(), +- []( TestCaseTracking::ITrackerPtr tracker ) { +- return tracker->hasStarted(); +- } ) == m_children.end(); ++ const bool should_wait_for_child = [&]() { ++ // No children -> nobody to wait for ++ if ( m_children.empty() ) { ++ return false; ++ } ++ // If at least one child started executing, don't wait ++ if ( std::find_if( ++ m_children.begin(), ++ m_children.end(), ++ []( TestCaseTracking::ITrackerPtr tracker ) { ++ return tracker->hasStarted(); ++ } ) != m_children.end() ) { ++ return false; ++ } ++ ++ // No children have started. We need to check if they _can_ ++ // start, and thus we should wait for them, or they cannot ++ // start (due to filters), and we shouldn't wait for them ++ auto* parent = m_parent; ++ // This is safe: there is always at least one section ++ // tracker in a test case tracking tree ++ while ( !parent->isSectionTracker() ) { ++ parent = &( parent->parent() ); ++ } ++ assert( parent && ++ "Missing root (test case) level section" ); ++ ++ auto const& parentSection = ++ static_cast( *parent ); ++ auto const& filters = parentSection.getFilters(); ++ // No filters -> no restrictions on running sections ++ if ( filters.empty() ) { ++ return true; ++ } ++ ++ for ( auto const& child : m_children ) { ++ if ( child->isSectionTracker() && ++ std::find( filters.begin(), ++ filters.end(), ++ static_cast( *child ) ++ .trimmedName() ) != ++ filters.end() ) { ++ return true; ++ } ++ } ++ return false; ++ }(); + + // This check is a bit tricky, because m_generator->next() + // has a side-effect, where it consumes generator's current +@@ -12920,9 +13012,8 @@ namespace Catch { + } + + void RunContext::invokeActiveTestCase() { +- FatalConditionHandler fatalConditionHandler; // Handle signals ++ FatalConditionHandlerGuard _(&m_fatalConditionhandler); + m_activeTestCase->invoke(); +- fatalConditionHandler.reset(); + } + + void RunContext::handleUnfinishedSections() { +@@ -14091,24 +14182,28 @@ namespace Catch { + + namespace { + struct TestHasher { +- explicit TestHasher(Catch::SimplePcg32& rng) { +- basis = rng(); +- basis <<= 32; +- basis |= rng(); +- } ++ using hash_t = uint64_t; + +- uint64_t basis; ++ explicit TestHasher( hash_t hashSuffix ): ++ m_hashSuffix{ hashSuffix } {} + +- uint64_t operator()(TestCase const& t) const { +- // Modified FNV-1a hash +- static constexpr uint64_t prime = 1099511628211; +- uint64_t hash = basis; +- for (const char c : t.name) { ++ uint32_t operator()( TestCase const& t ) const { ++ // FNV-1a hash with multiplication fold. ++ const hash_t prime = 1099511628211u; ++ hash_t hash = 14695981039346656037u; ++ for ( const char c : t.name ) { + hash ^= c; + hash *= prime; + } +- return hash; ++ hash ^= m_hashSuffix; ++ hash *= prime; ++ const uint32_t low{ static_cast( hash ) }; ++ const uint32_t high{ static_cast( hash >> 32 ) }; ++ return low * high; + } ++ ++ private: ++ hash_t m_hashSuffix; + }; + } // end unnamed namespace + +@@ -14126,9 +14221,9 @@ namespace Catch { + + case RunTests::InRandomOrder: { + seedRng( config ); +- TestHasher h( rng() ); ++ TestHasher h{ config.rngSeed() }; + +- using hashedTest = std::pair; ++ using hashedTest = std::pair; + std::vector indexed_tests; + indexed_tests.reserve( unsortedTestCases.size() ); + +@@ -14458,6 +14553,14 @@ namespace TestCaseTracking { + m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() ); + } + ++ std::vector const& SectionTracker::getFilters() const { ++ return m_filters; ++ } ++ ++ std::string const& SectionTracker::trimmedName() const { ++ return m_trimmed_name; ++ } ++ + } // namespace TestCaseTracking + + using TestCaseTracking::ITracker; +@@ -15192,6 +15295,41 @@ namespace Catch { + // end catch_totals.cpp + // start catch_uncaught_exceptions.cpp + ++// start catch_config_uncaught_exceptions.hpp ++ ++// Copyright Catch2 Authors ++// Distributed under the Boost Software License, Version 1.0. ++// (See accompanying file LICENSE_1_0.txt or copy at ++// https://www.boost.org/LICENSE_1_0.txt) ++ ++// SPDX-License-Identifier: BSL-1.0 ++ ++#ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP ++#define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP ++ ++#if defined(_MSC_VER) ++# if _MSC_VER >= 1900 // Visual Studio 2015 or newer ++# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS ++# endif ++#endif ++ ++#include ++ ++#if defined(__cpp_lib_uncaught_exceptions) \ ++ && !defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) ++ ++# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS ++#endif // __cpp_lib_uncaught_exceptions ++ ++#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) \ ++ && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) \ ++ && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) ++ ++# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS ++#endif ++ ++#endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP ++// end catch_config_uncaught_exceptions.hpp + #include + + namespace Catch { +@@ -15238,7 +15376,7 @@ namespace Catch { + } + + Version const& libraryVersion() { +- static Version version( 2, 13, 0, "", 0 ); ++ static Version version( 2, 13, 6, "", 0 ); + return version; + } + diff --git a/libmemcached-awesome.spec b/libmemcached-awesome.spec new file mode 100644 index 0000000..674e1b3 --- /dev/null +++ b/libmemcached-awesome.spec @@ -0,0 +1,196 @@ +# Fedora spec file for libmemcached-awesome from +# +# remirepo spec file for libmemcached-awesome +# +# Copyright (c) 2009-2021 Remi Collet +# License: CC-BY-SA +# https://creativecommons.org/licenses/by-sa/4.0/ +# +# Please, preserve the changelog entries +# + +%bcond_without tests + +%global libname libmemcached + +%global gh_commit 0ff88be3322a493773956028d4022d995f3cb193 +%global gh_short %(c=%{gh_commit}; echo ${c:0:7}) +%global gh_owner awesomized +%global gh_project libmemcached + +%global upstream_version 1.1.0 +#global upstream_prever beta3 + +Name: %{libname}-awesome +Summary: Client library and command line tools for memcached server +Version: %{upstream_version}%{?upstream_prever:~%{upstream_prever}} +Release: 3%{?dist} +License: BSD +URL: https://github.com/%{gh_owner}/%{gh_project} +Source0: https://github.com/%{gh_owner}/%{gh_project}/archive/%{gh_commit}/%{gh_project}-%{version}-%{gh_short}.tar.gz + +Patch0: %{name}-catch.patch +Patch1: %{name}-aes.patch + +BuildRequires: cmake >= 3.9 +BuildRequires: gcc +BuildRequires: gcc-c++ +BuildRequires: python3-sphinx +BuildRequires: cyrus-sasl-devel +BuildRequires: flex +BuildRequires: bison +BuildRequires: memcached +BuildRequires: systemtap-sdt-devel +BuildRequires: libevent-devel > 2 +BuildRequires: openssl-devel + +Provides: bundled(bobjenkins-hash) +# package rename +Obsoletes: %{libname}-libs < 1.1 +Provides: %{libname}-libs = %{version}-%{release} +Provides: %{libname}-libs%{?_isa} = %{version}-%{release} + + +%description +%{name} is a C/C++ client library and tools for the memcached +server (https://memcached.org/). It has been designed to be light +on memory usage, and provide full access to server side methods. + +This is a resurrection of the original work from Brian Aker at libmemcached.org. + + +%package devel +Summary: Header files and development libraries for %{name} + +Requires: %{name}%{?_isa} = %{version}-%{release} +# package rename +Obsoletes: %{libname}-devel < 1.1 +Provides: %{libname}-devel = %{version}-%{release} +Provides: %{libname}-devel%{?_isa} = %{version}-%{release} + +%description devel +This package contains the header files and development libraries +for %{name}. If you like to develop programs using %{name}, +you will need to install %{name}-devel. + +Documentation: https://awesomized.github.io/libmemcached + + +%package tools +Summary: %{name} tools + +Requires: %{name}%{?_isa} = %{version}-%{release} +# package rename +Obsoletes: %{libname} < 1.1 +Provides: %{libname} = %{version}-%{release} +Provides: %{libname}%{?_isa} = %{version}-%{release} + +%description tools +This package contains the %{libname}-awesome command line tools: + +memaslap Load testing and benchmarking a server +memcapable Checking a Memcached server capibilities and compatibility +memcat Copy the value of a key to standard output +memcp Copy data to a server +memdump Dumping your server +memerror Translate an error code to a string +memexist Check for the existance of a key +memflush Flush the contents of your servers +memparse Parse an option string +memping Test to see if a server is available. +memrm Remove a key(s) from the server +memslap Generate testing loads on a memcached cluster +memstat Dump the stats of your servers to standard output +memtouch Touches a key + + +%prep +%setup -q -n %{gh_project}-%{gh_commit} +%patch0 -p1 +%patch1 -p1 + +# drop test hanging in mock +# and requiring some memcached build options +rm test/tests/memcached/sasl.cpp + + +%build +%cmake \ + -DBUILD_TESTING:BOOL=ON \ + -DBUILD_DOCS_MAN:BOOL=ON \ + -DBUILD_DOCS_MANGZ:BOOL=OFF \ + -DENABLE_SASL:BOOL=ON \ + -DENABLE_DTRACE:BOOL=ON \ + -DENABLE_OPENSSL_CRYPTO:BOOL=ON \ + -DENABLE_HASH_HSIEH:BOOL=ON \ + -DENABLE_HASH_FNV64:BOOL=ON \ + -DENABLE_HASH_MURMUR:BOOL=ON \ + -DENABLE_MEMASLAP:BOOL=ON + +%cmake_build + + +%install +%cmake_install + +mv %{buildroot}%{_datadir}/%{name}/example.cnf support + +rm -r %{buildroot}%{_datadir}/doc/%{name}/ + + +%check +%if %{with tests} +: Run test suite +%ctest +%else +: Skip test suite +%endif + + +%files tools +%{_bindir}/mem* +%{_mandir}/man1/mem* + +%files +%license LICENSE +%{_libdir}/libhashkit.so.2* +%{_libdir}/libmemcached.so.11* +%{_libdir}/libmemcachedprotocol.so.0* +%{_libdir}/libmemcachedutil.so.2* + +%files devel +%doc example +%doc *.md +%doc AUTHORS +%doc support/example.cnf +%{_includedir}/libmemcached +%{_includedir}/libmemcached-1.0 +%{_includedir}/libhashkit +%{_includedir}/libhashkit-1.0 +%{_includedir}/libmemcachedprotocol-0.0 +%{_includedir}/libmemcachedutil-1.0 +%{_libdir}/libhashkit.so +%{_libdir}/libmemcached.so +%{_libdir}/libmemcachedprotocol.so +%{_libdir}/libmemcachedutil.so +%{_libdir}/pkgconfig/libmemcached.pc +%{_libdir}/cmake/%{name} +%{_datadir}/aclocal/ax_libmemcached.m4 +%{_mandir}/man3/libmemcached* +%{_mandir}/man3/libhashkit* +%{_mandir}/man3/memcached* +%{_mandir}/man3/hashkit* + + +%changelog +* Tue Jul 13 2021 Remi Collet - 1.1.0-3 +- use upstream patch for libcrypto + +* Fri Jun 25 2021 Remi Collet - 1.1.0-2 +- remove internal AES implementation and use libcrypto + https://github.com/awesomized/libmemcached/pull/114 +- fix build ussing upstream patch to update catch version + +* Thu Jun 24 2021 Remi Collet - 1.1.0-1 +- Initial RPM from libmemcached-awesome + from old libmemcached spec file diff --git a/sources b/sources new file mode 100644 index 0000000..5ebde64 --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (libmemcached-1.1.0-0ff88be.tar.gz) = 58a6958003b1ce2730cb72f6ad8d863331c5356b2b88e92bf7f2bcc2fe1d1418778ff8a8b181ff679a328453ad6e393c1b26d43fa181f62313847c8f6f9c4487