Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 19 additions & 30 deletions lib/gis/asprintf.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,19 @@ int G_vasprintf(char **out, const char *fmt, va_list ap)
#ifdef HAVE_ASPRINTF
return vasprintf(out, fmt, ap);
#else
size_t size = strlen(fmt) + 50;
char *buf = G_malloc(size);
va_list aq;
char *buf;
size_t size;
int count;

for (;;) {
/* BUG: according to man vsnprintf,
* va_start() should be called immediately before vsnprintf(),
* and va_end() immediately after vsnprintf()
* otherwise there will be memory corruption */
count = vsnprintf(buf, size, fmt, ap);
if (count >= 0 && count < size)
break;
size *= 2;
buf = G_realloc(buf, size);
}

buf = G_realloc(buf, count + 1);
va_copy(aq, ap);
/* determine a sufficient size */
count = vsnprintf(NULL, 0, fmt, ap);
/* count holds the number of printable characters; size must be +1 for '\0'
*/
buf = G_malloc(size = ++count);
count = vsnprintf(buf, size, fmt, aq);
va_end(aq);
*out = buf;

return count;
Expand Down Expand Up @@ -100,29 +96,22 @@ int G_asprintf(char **out, const char *fmt, ...)
int G_rasprintf(char **out, size_t *size, const char *fmt, ...)
{
va_list ap;
int count;
char *buf = *out;
size_t osize = *size;
int count;

if (osize < strlen(fmt) + 50) {
osize = strlen(fmt) + 50;
buf = G_realloc(buf, osize);
}
va_start(ap, fmt);
count = vsnprintf(buf, osize, fmt, ap);
va_end(ap);

for (;;) {
if (count >= osize) {

@nilason nilason Oct 25, 2024

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This addresses the warning, and take into account if the previous vsnprintf call fails.

Suggested change
if (count >= osize) {
if (count < 0)
return count;
if ((size_t)count >= osize) {

/* count holds the number of printable characters; osize must be +1 for
* '\0' */
buf = G_realloc(buf, osize = ++count);
va_start(ap, fmt);
count = vsnprintf(buf, osize, fmt, ap);
va_end(ap);
if (count >= 0 && (size_t)count < osize)
break;
if (count > -1)
osize = count + 1;
else
osize *= 2;

buf = G_realloc(buf, osize);
}

*out = buf;
*size = osize;

Expand Down