Fix realloc bug destroying memory in stack

This commit is contained in:
Doyle Thai 2018-01-28 12:43:53 +11:00
parent 86d2db397c
commit 06b0f25f2a

121
dqn.h
View File

@ -478,13 +478,14 @@ public:
// API // API
// ============================================================================================= // =============================================================================================
// return: These functions return false if allocation failed. String is preserved. // return: These functions return false if allocation failed. String is preserved.
bool Expand (const i32 newMax); bool Expand (i32 newMax);
bool Sprintf(char const *const fmt, ...); bool Sprintf (char const *const fmt, ...);
bool Append (DqnString const string); bool VSprintf(char const *const fmt, va_list argList);
bool Append (char const *const cstr, i32 bytesToCopy = -1); bool Append (DqnString const string);
bool Append (char const *const cstr, i32 bytesToCopy = -1);
void Clear (); void Clear ();
void Free (); void Free ();
// return: -1 if invalid, or if bufSize is 0 the required buffer length in wchar_t characters // return: -1 if invalid, or if bufSize is 0 the required buffer length in wchar_t characters
i32 ToWChar(wchar_t *const buf, i32 const bufSize); i32 ToWChar(wchar_t *const buf, i32 const bufSize);
@ -493,6 +494,12 @@ public:
wchar_t *ToWChar(DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR); wchar_t *ToWChar(DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR);
}; };
class DqnSmartString : public DqnString
{
public:
~DqnSmartString() { this->Free(); }
};
DQN_FILE_SCOPE DqnString DqnString_(DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR); DQN_FILE_SCOPE DqnString DqnString_(DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR);
DQN_FILE_SCOPE DqnString DqnString_(DqnMemStack *const stack); DQN_FILE_SCOPE DqnString DqnString_(DqnMemStack *const stack);
@ -526,8 +533,9 @@ public:
bool InitSize (isize size_, DqnMemStack *const stack); bool InitSize (isize size_, DqnMemStack *const stack);
void Free (); void Free ();
bool Resize (isize newMax); bool Resize (isize newMax); // If (newMax < count), it will destroy the left over elements.
bool Grow (isize multiplier = 2); bool Grow (isize multiplier = 2);
T *Make (); // Get a ptr to the next free element in the array, increment count.
T *Push (T const *item, isize num); T *Push (T const *item, isize num);
T *Push (T const item); T *Push (T const item);
T *Insert (T const item, isize index); T *Insert (T const item, isize index);
@ -681,6 +689,24 @@ bool DqnArray<T>::Grow(isize multiplier)
return result; return result;
} }
template <typename T>
T *DqnArray<T>::Make()
{
bool accessible = true;
if (!this->data || this->count >= this->max)
{
accessible = this->Grow();
}
if (accessible)
{
T *result = this->data[this->count++];
return result;
}
return nullptr;
}
template <typename T> template <typename T>
T *DqnArray<T>::Push(T const *item, isize num) T *DqnArray<T>::Push(T const *item, isize num)
{ {
@ -2815,26 +2841,23 @@ DQN_FILE_SCOPE void DqnLog(char *file, char const *const functionName, i32 const
char userMsg[2048]; char userMsg[2048];
userMsg[0] = '\0'; userMsg[0] = '\0';
if (msg) va_list argList;
va_start(argList, msg);
{ {
va_list argList; u32 numCopied = Dqn_vsprintf(userMsg, msg, argList);
va_start(argList, msg); if (numCopied > DQN_ARRAY_COUNT(userMsg))
{ {
u32 numCopied = Dqn_vsprintf(userMsg, msg, argList); (*((int *)0)) = 0;
if (numCopied > DQN_ARRAY_COUNT(userMsg))
{
(*((int *)0)) = 0;
}
} }
va_end(argList);
} }
va_end(argList);
char const *const formatStr = "DqnLog:%s:%s,%d: %s\n"; char const *const formatStr = "DqnLog:%s:%s,%d: %s\n";
fprintf(stderr, formatStr, file, functionName, lineNum, userMsg); fprintf(stderr, formatStr, file, functionName, lineNum, userMsg);
#if defined(DQN_WIN32_PLATFORM) #if defined(DQN_WIN32_PLATFORM)
DqnWin32_OutputDebugString(formatStr, file, functionName, lineNum, userMsg); DqnWin32_OutputDebugString(formatStr, file, functionName, lineNum, userMsg);
#endif #endif
} }
DQN_FILE_SCOPE void DqnLog(char *file, char const *const functionName, i32 const lineNum, DQN_FILE_SCOPE void DqnLog(char *file, char const *const functionName, i32 const lineNum,
@ -2853,19 +2876,16 @@ DQN_FILE_SCOPE void DqnLog(char *file, char const *const functionName, i32 const
char userMsg[2048]; char userMsg[2048];
userMsg[0] = '\0'; userMsg[0] = '\0';
if (msg) va_list argList;
va_start(argList, msg);
{ {
va_list argList; u32 numCopied = Dqn_vsprintf(userMsg, msg, argList);
va_start(argList, msg); if (numCopied > DQN_ARRAY_COUNT(userMsg))
{ {
u32 numCopied = Dqn_vsprintf(userMsg, msg, argList); (*((int *)0)) = 0;
if (numCopied > DQN_ARRAY_COUNT(userMsg))
{
(*((int *)0)) = 0;
}
} }
va_end(argList);
} }
va_end(argList);
char const *const formatStr = "DqnLog:%s:%s,%d(%s): %s\n"; char const *const formatStr = "DqnLog:%s:%s,%d(%s): %s\n";
fprintf(stderr, formatStr, file, functionName, lineNum, expr, userMsg); fprintf(stderr, formatStr, file, functionName, lineNum, expr, userMsg);
@ -3084,7 +3104,7 @@ FILE_SCOPE u8 *DqnMemAPIInternal_StackAllocatorCallback(DqnMemAPI *api, DqnMemAP
u8 *checkPtr = currUsagePtr - DQN_ALIGN_POW_N(request->oldSize, stack->byteAlign); u8 *checkPtr = currUsagePtr - DQN_ALIGN_POW_N(request->oldSize, stack->byteAlign);
// Last allocation, can safely allocate the remainder space. // Last allocation, can safely allocate the remainder space.
if (checkPtr == (u8 *)request->oldMemPtr || request->oldMemPtr == block->memory) if (checkPtr == (u8 *)request->oldMemPtr)
{ {
size_t remainingBytesToAlloc = request->newRequestSize - request->oldSize; size_t remainingBytesToAlloc = request->newRequestSize - request->oldSize;
DQN_ASSERT(remainingBytesToAlloc > 0); DQN_ASSERT(remainingBytesToAlloc > 0);
@ -5612,7 +5632,7 @@ bool DqnString::InitLiteralNoAlloc(char *const cstr, i32 cstrLen)
return true; return true;
} }
bool DqnString::Expand(const i32 newMax) bool DqnString::Expand(i32 newMax)
{ {
if (newMax < this->max) if (newMax < this->max)
{ {
@ -5696,6 +5716,16 @@ DQN_FILE_SCOPE bool DqnStringInternal_Append(DqnString *const str, char const *c
} }
bool DqnString::Sprintf(char const *fmt, ...) bool DqnString::Sprintf(char const *fmt, ...)
{
va_list argList;
va_start(argList, fmt);
bool result = this->VSprintf(fmt, argList);
va_end(argList);
return result;
}
bool DqnString::VSprintf(char const *fmt, va_list argList)
{ {
LOCAL_PERSIST char tmp[STB_SPRINTF_MIN]; LOCAL_PERSIST char tmp[STB_SPRINTF_MIN];
@ -5705,26 +5735,21 @@ bool DqnString::Sprintf(char const *fmt, ...)
return buf; return buf;
}; };
va_list argList; i32 const reqLen = Dqn_vsprintfcb(PrintCallback, nullptr, tmp, fmt, argList);
va_start(argList, fmt); auto const remainingSpace = this->max - this->len;
if (reqLen > remainingSpace)
{ {
i32 const reqLen = Dqn_vsprintfcb(PrintCallback, nullptr, tmp, fmt, argList); i32 const newMax = this->max + reqLen;
auto const remainingSpace = this->max - this->len; if (!this->Expand(newMax))
if (reqLen > remainingSpace)
{ {
i32 const newMax = this->max + reqLen; return false;
if (!this->Expand(newMax))
{
return false;
}
} }
char *bufStart = this->str + this->len;
i32 numCopied = Dqn_vsprintf(bufStart, fmt, argList);
this->len += numCopied;
DQN_ASSERT(this->len <= this->max);
} }
va_end(argList);
char *bufStart = this->str + this->len;
i32 numCopied = Dqn_vsprintf(bufStart, fmt, argList);
this->len += numCopied;
DQN_ASSERT(this->len <= this->max);
return true; return true;
} }