mirror of
https://github.com/shadps4-emu/ext-cryptopp.git
synced 2024-11-23 09:59:42 +00:00
fix possible race condition in Singleton::Ref()
tolerate double destruction of Singleton and g_nullNameValuePairs fix #include of standard headers
This commit is contained in:
parent
b110830c7f
commit
d60229a02a
@ -30,7 +30,14 @@ const std::string DEFAULT_CHANNEL;
|
||||
const std::string AAD_CHANNEL = "AAD";
|
||||
const std::string &BufferedTransformation::NULL_CHANNEL = DEFAULT_CHANNEL;
|
||||
|
||||
const NullNameValuePairs g_nullNameValuePairs;
|
||||
class NullNameValuePairs : public NameValuePairs
|
||||
{
|
||||
public:
|
||||
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const {return false;}
|
||||
};
|
||||
|
||||
simple_ptr<NullNameValuePairs> s_pNullNameValuePairs(new NullNameValuePairs);
|
||||
const NameValuePairs &g_nullNameValuePairs = *s_pNullNameValuePairs.m_p;
|
||||
|
||||
BufferedTransformation & TheBitBucket()
|
||||
{
|
||||
|
@ -318,14 +318,7 @@ DOCUMENTED_NAMESPACE_BEGIN(Name)
|
||||
DOCUMENTED_NAMESPACE_END
|
||||
|
||||
//! empty set of name-value pairs
|
||||
class CRYPTOPP_DLL NullNameValuePairs : public NameValuePairs
|
||||
{
|
||||
public:
|
||||
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const {return false;}
|
||||
};
|
||||
|
||||
//! _
|
||||
extern CRYPTOPP_DLL const NullNameValuePairs g_nullNameValuePairs;
|
||||
extern CRYPTOPP_DLL const NameValuePairs &g_nullNameValuePairs;
|
||||
|
||||
// ********************************************************
|
||||
|
||||
|
45
misc.h
45
misc.h
@ -6,7 +6,6 @@
|
||||
#include <string.h> // for memcpy and memmove
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <stdlib.h>
|
||||
#if _MSC_VER >= 1400
|
||||
// VC2005 workaround: disable declarations that conflict with winnt.h
|
||||
#define _interlockedbittestandset CRYPTOPP_DISABLED_INTRINSIC_1
|
||||
@ -101,9 +100,9 @@ struct NewObject
|
||||
T* operator()() const {return new T;}
|
||||
};
|
||||
|
||||
/*! This function safely initializes a static object in a multithreaded environment without using locks.
|
||||
It may leak memory when two threads try to initialize the static object at the same time
|
||||
but this should be acceptable since each static object is only initialized once per session.
|
||||
/*! This function safely initializes a static object in a multithreaded environment without using locks (for portability).
|
||||
Note that if two threads call Ref() at the same time, they may get back different references, and one object
|
||||
may end up being memory leaked. This is by design.
|
||||
*/
|
||||
template <class T, class F = NewObject<T>, int instance=0>
|
||||
class Singleton
|
||||
@ -121,31 +120,23 @@ private:
|
||||
template <class T, class F, int instance>
|
||||
const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
|
||||
{
|
||||
static simple_ptr<T> s_pObject;
|
||||
static volatile char s_objectState = 0;
|
||||
static volatile simple_ptr<T> s_pObject;
|
||||
T *p = s_pObject.m_p;
|
||||
|
||||
retry:
|
||||
switch (s_objectState)
|
||||
if (p)
|
||||
return *p;
|
||||
|
||||
T *newObject = m_objectFactory();
|
||||
p = s_pObject.m_p;
|
||||
|
||||
if (p)
|
||||
{
|
||||
case 0:
|
||||
s_objectState = 1;
|
||||
try
|
||||
{
|
||||
s_pObject.m_p = m_objectFactory();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
s_objectState = 0;
|
||||
throw;
|
||||
}
|
||||
s_objectState = 2;
|
||||
break;
|
||||
case 1:
|
||||
goto retry;
|
||||
default:
|
||||
break;
|
||||
delete newObject;
|
||||
return *p;
|
||||
}
|
||||
return *s_pObject.m_p;
|
||||
|
||||
s_pObject.m_p = newObject;
|
||||
return *newObject;
|
||||
}
|
||||
|
||||
// ************** misc functions ***************
|
||||
@ -555,7 +546,7 @@ static std::string StringNarrow(const wchar_t *str, bool throwOnError = true)
|
||||
#pragma warning(disable: 4996) // 'wcstombs': This function or variable may be unsafe.
|
||||
#endif
|
||||
size_t size = wcstombs(NULL, str, 0);
|
||||
if (size == -1)
|
||||
if (size == size_t(0)-1)
|
||||
{
|
||||
if (throwOnError)
|
||||
throw InvalidArgument("StringNarrow: wcstombs() call failed");
|
||||
|
@ -69,14 +69,6 @@ being unloaded from L1 cache, until that round is finished.
|
||||
#include "misc.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#ifdef __sun
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
#ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
|
||||
|
@ -9,8 +9,6 @@
|
||||
|
||||
#if defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE) || defined(QNX)
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
@ -352,8 +350,11 @@ public:
|
||||
//! copy contents and size from another SecBlock
|
||||
void Assign(const SecBlock<T, A> &t)
|
||||
{
|
||||
New(t.m_size);
|
||||
memcpy_s(m_ptr, m_size*sizeof(T), t.m_ptr, m_size*sizeof(T));
|
||||
if (this != &t)
|
||||
{
|
||||
New(t.m_size);
|
||||
memcpy_s(m_ptr, m_size*sizeof(T), t.m_ptr, m_size*sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
SecBlock<T, A>& operator=(const SecBlock<T, A> &t)
|
||||
|
@ -9,8 +9,8 @@ NAMESPACE_BEGIN(CryptoPP)
|
||||
template <class T> class simple_ptr
|
||||
{
|
||||
public:
|
||||
simple_ptr() : m_p(NULL) {}
|
||||
~simple_ptr() {delete m_p;}
|
||||
simple_ptr(T *p = NULL) : m_p(p) {}
|
||||
~simple_ptr() {delete m_p; m_p = NULL;} // set m_p to NULL so double destruction (which might occur in Singleton) will be harmless
|
||||
T *m_p;
|
||||
};
|
||||
|
||||
|
18
stdcpp.h
18
stdcpp.h
@ -4,24 +4,28 @@
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <exception>
|
||||
#include <typeinfo>
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <string.h> // CodeWarrior doesn't have memory.h
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
// re-disable this
|
||||
#pragma warning(disable: 4231)
|
||||
// for alloca
|
||||
#ifdef __sun
|
||||
#include <alloca.h>
|
||||
#elif defined(__MINGW32__)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && defined(_CRTAPI1)
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4231) // re-disable this
|
||||
#ifdef _CRTAPI1
|
||||
#define CRYPTOPP_MSVCRT6
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user