You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-07-13 01:00:23 +02:00
Convert the result of zNewFmt() into an object.
The result is not intended to be freed directly so this makes memory tracking more accurate. Fix a few places where memory was leaking after a call to zNewFmt(). Also update an assert to make it clearer.
This commit is contained in:
@ -343,7 +343,10 @@ bufUsedZero(Buffer *this)
|
|||||||
FN_EXTERN void
|
FN_EXTERN void
|
||||||
bufToLog(const Buffer *const this, StringStatic *const debugLog)
|
bufToLog(const Buffer *const this, StringStatic *const debugLog)
|
||||||
{
|
{
|
||||||
strStcFmt(
|
strStcFmt(debugLog, "{used: %zu, size: %zu", bufUsed(this), bufSize(this));
|
||||||
debugLog, "{used: %zu, size: %zu%s", bufUsed(this), bufSize(this),
|
|
||||||
bufSizeLimit(this) ? zNewFmt(", sizeAlloc: %zu}", bufSizeAlloc(this)) : "}");
|
if (bufSizeLimit(this))
|
||||||
|
strStcFmt(debugLog, ", sizeAlloc: %zu", bufSizeAlloc(this));
|
||||||
|
|
||||||
|
strStcCatChr(debugLog, '}');
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ Zero-Terminated String Handler
|
|||||||
|
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "common/memContext.h"
|
#include "common/memContext.h"
|
||||||
|
#include "common/type/object.h"
|
||||||
#include "common/type/stringZ.h"
|
#include "common/type/stringZ.h"
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
@ -20,13 +21,22 @@ zNewFmt(const char *const format, ...)
|
|||||||
|
|
||||||
ASSERT(format != NULL);
|
ASSERT(format != NULL);
|
||||||
|
|
||||||
// Determine how long the allocated string needs to be and create object
|
// Determine how long the allocated string needs to be
|
||||||
va_list argumentList;
|
va_list argumentList;
|
||||||
va_start(argumentList, format);
|
va_start(argumentList, format);
|
||||||
const size_t size = (size_t)vsnprintf(NULL, 0, format, argumentList) + 1;
|
const size_t size = (size_t)vsnprintf(NULL, 0, format, argumentList) + 1;
|
||||||
char *const result = memNew(size);
|
|
||||||
va_end(argumentList);
|
va_end(argumentList);
|
||||||
|
|
||||||
|
// Allocate the string as extra or a separate allocation based on how large it is
|
||||||
|
char *result;
|
||||||
|
|
||||||
|
OBJ_NEW_BASE_EXTRA_BEGIN(
|
||||||
|
char *, size > MEM_CONTEXT_ALLOC_EXTRA_MAX ? 0 : (uint16_t)size, .allocQty = size > MEM_CONTEXT_ALLOC_EXTRA_MAX ? 1 : 0)
|
||||||
|
{
|
||||||
|
result = size > MEM_CONTEXT_ALLOC_EXTRA_MAX ? memNew(size) : OBJ_NEW_ALLOC();
|
||||||
|
}
|
||||||
|
OBJ_NEW_END();
|
||||||
|
|
||||||
// Format string
|
// Format string
|
||||||
va_start(argumentList, format);
|
va_start(argumentList, format);
|
||||||
vsnprintf(result, size, format, argumentList);
|
vsnprintf(result, size, format, argumentList);
|
||||||
|
@ -340,7 +340,7 @@ storageRepoPathExpression(const String *const expression, const String *const pa
|
|||||||
else
|
else
|
||||||
THROW_FMT(AssertError, "invalid expression '%s'", strZ(expression));
|
THROW_FMT(AssertError, "invalid expression '%s'", strZ(expression));
|
||||||
|
|
||||||
ASSERT(result != 0);
|
ASSERT(result != NULL);
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(STRING, result);
|
FUNCTION_TEST_RETURN(STRING, result);
|
||||||
}
|
}
|
||||||
|
@ -705,7 +705,24 @@ testRun(void)
|
|||||||
// *****************************************************************************************************************************
|
// *****************************************************************************************************************************
|
||||||
if (testBegin("z*()"))
|
if (testBegin("z*()"))
|
||||||
{
|
{
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("small string");
|
||||||
|
|
||||||
TEST_RESULT_Z(zNewFmt("id=%d", 777), "id=777", "format");
|
TEST_RESULT_Z(zNewFmt("id=%d", 777), "id=777", "format");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("string large enough to need separate allocation");
|
||||||
|
|
||||||
|
char *format = memNew(MEM_CONTEXT_ALLOC_EXTRA_MAX + 1);
|
||||||
|
memset(format, 'A', MEM_CONTEXT_ALLOC_EXTRA_MAX);
|
||||||
|
format[MEM_CONTEXT_ALLOC_EXTRA_MAX] = '\0';
|
||||||
|
format[0] = '%';
|
||||||
|
format[1] = 's';
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||||
|
TEST_RESULT_Z(zNewFmt(format, "%s"), format, "compare");
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
}
|
}
|
||||||
|
|
||||||
// *****************************************************************************************************************************
|
// *****************************************************************************************************************************
|
||||||
|
@ -19,7 +19,12 @@ storageTestPathExpression(const String *expression, const String *path)
|
|||||||
String *result = NULL;
|
String *result = NULL;
|
||||||
|
|
||||||
if (strcmp(strZ(expression), "<TEST>") == 0)
|
if (strcmp(strZ(expression), "<TEST>") == 0)
|
||||||
result = strNewFmt("test%s", path == NULL ? "" : zNewFmt("/%s", strZ(path)));
|
{
|
||||||
|
result = strCatZ(strNew(), "test");
|
||||||
|
|
||||||
|
if (path != NULL)
|
||||||
|
strCatFmt(result, "/%s", strZ(path));
|
||||||
|
}
|
||||||
else if (strcmp(strZ(expression), "<NULL>") != 0)
|
else if (strcmp(strZ(expression), "<NULL>") != 0)
|
||||||
THROW_FMT(AssertError, "invalid expression '%s'", strZ(expression));
|
THROW_FMT(AssertError, "invalid expression '%s'", strZ(expression));
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user