1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-02-19 19:44:38 +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:
David Steele 2023-03-30 10:00:58 +05:00
parent 295b53e845
commit fe0fd71be2
5 changed files with 42 additions and 7 deletions

View File

@ -343,7 +343,10 @@ bufUsedZero(Buffer *this)
FN_EXTERN void
bufToLog(const Buffer *const this, StringStatic *const debugLog)
{
strStcFmt(
debugLog, "{used: %zu, size: %zu%s", bufUsed(this), bufSize(this),
bufSizeLimit(this) ? zNewFmt(", sizeAlloc: %zu}", bufSizeAlloc(this)) : "}");
strStcFmt(debugLog, "{used: %zu, size: %zu", bufUsed(this), bufSize(this));
if (bufSizeLimit(this))
strStcFmt(debugLog, ", sizeAlloc: %zu", bufSizeAlloc(this));
strStcCatChr(debugLog, '}');
}

View File

@ -8,6 +8,7 @@ Zero-Terminated String Handler
#include "common/debug.h"
#include "common/memContext.h"
#include "common/type/object.h"
#include "common/type/stringZ.h"
/**********************************************************************************************************************************/
@ -20,13 +21,22 @@ zNewFmt(const char *const format, ...)
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_start(argumentList, format);
const size_t size = (size_t)vsnprintf(NULL, 0, format, argumentList) + 1;
char *const result = memNew(size);
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
va_start(argumentList, format);
vsnprintf(result, size, format, argumentList);

View File

@ -340,7 +340,7 @@ storageRepoPathExpression(const String *const expression, const String *const pa
else
THROW_FMT(AssertError, "invalid expression '%s'", strZ(expression));
ASSERT(result != 0);
ASSERT(result != NULL);
FUNCTION_TEST_RETURN(STRING, result);
}

View File

@ -705,7 +705,24 @@ testRun(void)
// *****************************************************************************************************************************
if (testBegin("z*()"))
{
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("small string");
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
}
// *****************************************************************************************************************************

View File

@ -19,7 +19,12 @@ storageTestPathExpression(const String *expression, const String *path)
String *result = NULL;
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)
THROW_FMT(AssertError, "invalid expression '%s'", strZ(expression));