Skip to content

Memory leak in meos stringarr_to_string function #524

@junderw

Description

@junderw

In line 746 of /meos/src/general/type_util.c, there is this part // pfree(strings[i]); /* ??? */ where the pfree call is commented out.

Does anyone remember why this was commented? It is leaking the strings that were allocated at each pointer.

If we call any of the public spanset_out functions like floatspanset_out, it calls span_out in a loop, the returned pointer is an allocated string that needs freeing and is placed in the char ** of strings.

/**
* @ingroup meos_internal_setspan_inout
* @brief Return the Well-Known Text (WKT) representation of a span set
* @param[in] ss Span set
* @param[in] maxdd Maximum number of decimal digits
* @csqlfn #Spanset_out()
*/
char *
spanset_out(const SpanSet *ss, int maxdd)
{
assert(ss);
/* Ensure validity of the arguments */
if (! ensure_not_negative(maxdd))
return NULL;
char **strings = palloc(sizeof(char *) * ss->count);
size_t outlen = 0;
for (int i = 0; i < ss->count; i++)
{
strings[i] = span_out(SPANSET_SP_N(ss, i), maxdd);
outlen += strlen(strings[i]) + 1;
}
return stringarr_to_string(strings, ss->count, outlen, "", '{', '}',
QUOTES_NO, SPACES);
}

Then inside stringarr_to_string we allocate a new chunk of memory and copy over the data allocated in span_out, but after commenting out that line, it is leaked.

/**
* @brief Return the string resulting from assembling the array of strings
* @param[in] strings Array of strings to ouput
* @param[in] count Number of elements in the input array
* @param[in] outlen Total length of the elements and the additional ','
* @param[in] prefix Prefix to add to the string (e.g., for interpolation)
* @param[in] open, close Starting/ending character (e.g., '{' and '}')
* @param[in] quotes True when elements should be enclosed into quotes
* @param[in] spaces True when elements should be separated by spaces
* @note The function frees the memory of the input strings after finishing
*/
char *
stringarr_to_string(char **strings, int count, size_t outlen, char *prefix,
char open, char close, bool quotes, bool spaces)
{
size_t size = strlen(prefix) + outlen + 3;
if (quotes)
size += count * 4;
if (spaces)
size += count;
char *result = palloc(size);
size_t pos = 0;
strcpy(result, prefix);
pos += strlen(prefix);
result[pos++] = open;
for (int i = 0; i < count; i++)
{
if (quotes)
result[pos++] = '"';
strcpy(result + pos, strings[i]);
pos += strlen(strings[i]);
if (quotes)
result[pos++] = '"';
result[pos++] = ',';
if (spaces)
result[pos++] = ' ';
// pfree(strings[i]); /* ??? */
}
if (spaces)
{
result[pos - 2] = close;
result[pos - 1] = '\0';
}
else
{
result[pos - 1] = close;
result[pos] = '\0';
}
pfree(strings);
return result;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions