Skip to content

Commit

Permalink
Convert the result of zNewFmt() into an object.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dwsteele committed Mar 30, 2023
1 parent 295b53e commit fe0fd71
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 7 deletions.
9 changes: 6 additions & 3 deletions src/common/type/buffer.c
Expand Up @@ -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, '}');
}
14 changes: 12 additions & 2 deletions src/common/type/stringZ.c
Expand Up @@ -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"

/**********************************************************************************************************************************/
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/storage/helper.c
Expand Up @@ -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);
}
Expand Down
17 changes: 17 additions & 0 deletions test/src/module/common/typeStringTest.c
Expand Up @@ -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
}

// *****************************************************************************************************************************
Expand Down
7 changes: 6 additions & 1 deletion test/src/module/storage/posixTest.c
Expand Up @@ -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));

Expand Down

0 comments on commit fe0fd71

Please sign in to comment.