Skip to content
Snippets Groups Projects
Commit 8f5ff4cf authored by Tom Lane's avatar Tom Lane
Browse files

Fix a potential infinite loop in appendStringInfo: would lock

up if first string to be appended to an empty StringInfo was longer
than the initial space allocation.
Also speed it up slightly.
parent 4f920a66
No related branches found
No related tags found
No related merge requests found
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/lib/stringinfo.c,v 1.11 1998/09/01 03:22:39 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/lib/stringinfo.c,v 1.12 1998/11/08 19:22:24 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -31,27 +31,22 @@ StringInfo ...@@ -31,27 +31,22 @@ StringInfo
makeStringInfo() makeStringInfo()
{ {
StringInfo res; StringInfo res;
long size; int size;
res = (StringInfo) palloc(sizeof(StringInfoData)); res = (StringInfo) palloc(sizeof(StringInfoData));
if (res == NULL) if (res == NULL)
elog(ERROR, "makeStringInfo: Out of memory!"); elog(ERROR, "makeStringInfo: Out of memory!");
size = 100; size = 256; /* initial default size */
res->data = palloc(size); res->data = palloc(size);
if (res->data == NULL) if (res->data == NULL)
{ {
elog(ERROR, elog(ERROR,
"makeStringInfo: Out of memory! (%ld bytes requested)", size); "makeStringInfo: Out of memory! (%d bytes requested)", size);
} }
res->maxlen = size; res->maxlen = size;
res->len = 0; res->len = 0;
/* Make sure the string is empty initially. */
/*
* NOTE: we must initialize `res->data' to the empty string because we
* use 'strcat' in 'appendStringInfo', which of course it always
* expects a null terminated string.
*/
res->data[0] = '\0'; res->data[0] = '\0';
return res; return res;
...@@ -71,7 +66,8 @@ void ...@@ -71,7 +66,8 @@ void
appendStringInfo(StringInfo str, char *buffer) appendStringInfo(StringInfo str, char *buffer)
{ {
int buflen, int buflen,
newlen; newlen,
needed;
char *s; char *s;
Assert(str != NULL); Assert(str != NULL);
...@@ -84,15 +80,16 @@ appendStringInfo(StringInfo str, char *buffer) ...@@ -84,15 +80,16 @@ appendStringInfo(StringInfo str, char *buffer)
* some more. * some more.
*/ */
buflen = strlen(buffer); buflen = strlen(buffer);
if (buflen + str->len >= str->maxlen - 1) needed = str->len + buflen + 1;
if (needed > str->maxlen)
{ {
/* /*
* how much more space to allocate ? Let's say double the current * how much more space to allocate ? Let's say double the current
* space... However we must check if this is enough! * space... However we must check if this is enough!
*/ */
newlen = 2 * str->len; newlen = 2 * str->maxlen;
while (buflen + str->len >= newlen - 1) while (needed > newlen)
newlen = 2 * newlen; newlen = 2 * newlen;
/* /*
...@@ -105,7 +102,11 @@ appendStringInfo(StringInfo str, char *buffer) ...@@ -105,7 +102,11 @@ appendStringInfo(StringInfo str, char *buffer)
"appendStringInfo: Out of memory (%d bytes requested)", "appendStringInfo: Out of memory (%d bytes requested)",
newlen); newlen);
} }
memmove(s, str->data, str->len + 1); /*
* transfer the data. strcpy() would work, but is probably a tad
* slower than memcpy(), and since we know the string length...
*/
memcpy(s, str->data, str->len + 1);
pfree(str->data); pfree(str->data);
str->maxlen = newlen; str->maxlen = newlen;
str->data = s; str->data = s;
...@@ -113,10 +114,10 @@ appendStringInfo(StringInfo str, char *buffer) ...@@ -113,10 +114,10 @@ appendStringInfo(StringInfo str, char *buffer)
/* /*
* OK, we have enough space now, append 'buffer' at the end of the * OK, we have enough space now, append 'buffer' at the end of the
* string & update the string length. NOTE: this is a text string * string & update the string length. NOTE: strcat() would work,
* (i.e. printable characters) so 'strcat' will do the job (no need to * but is certainly slower than just memcpy'ing the data to the right
* use 'bcopy' et all...) * place.
*/ */
strcat(str->data, buffer); memcpy(str->data + str->len, buffer, buflen + 1);
str->len += buflen; str->len += buflen;
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment