Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8f5ff4c

Browse files
committed
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.
1 parent 4f920a6 commit 8f5ff4c

File tree

1 file changed

+20
-19
lines changed

1 file changed

+20
-19
lines changed

src/backend/lib/stringinfo.c

+20-19
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/lib/stringinfo.c,v 1.11 1998/09/01 03:22:39 momjian Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/lib/stringinfo.c,v 1.12 1998/11/08 19:22:24 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -31,27 +31,22 @@ StringInfo
3131
makeStringInfo()
3232
{
3333
StringInfo res;
34-
long size;
34+
int size;
3535

3636
res = (StringInfo) palloc(sizeof(StringInfoData));
3737
if (res == NULL)
3838
elog(ERROR, "makeStringInfo: Out of memory!");
3939

40-
size = 100;
40+
size = 256; /* initial default size */
4141
res->data = palloc(size);
4242
if (res->data == NULL)
4343
{
4444
elog(ERROR,
45-
"makeStringInfo: Out of memory! (%ld bytes requested)", size);
45+
"makeStringInfo: Out of memory! (%d bytes requested)", size);
4646
}
4747
res->maxlen = size;
4848
res->len = 0;
49-
50-
/*
51-
* NOTE: we must initialize `res->data' to the empty string because we
52-
* use 'strcat' in 'appendStringInfo', which of course it always
53-
* expects a null terminated string.
54-
*/
49+
/* Make sure the string is empty initially. */
5550
res->data[0] = '\0';
5651

5752
return res;
@@ -71,7 +66,8 @@ void
7166
appendStringInfo(StringInfo str, char *buffer)
7267
{
7368
int buflen,
74-
newlen;
69+
newlen,
70+
needed;
7571
char *s;
7672

7773
Assert(str != NULL);
@@ -84,15 +80,16 @@ appendStringInfo(StringInfo str, char *buffer)
8480
* some more.
8581
*/
8682
buflen = strlen(buffer);
87-
if (buflen + str->len >= str->maxlen - 1)
83+
needed = str->len + buflen + 1;
84+
if (needed > str->maxlen)
8885
{
8986

9087
/*
9188
* how much more space to allocate ? Let's say double the current
9289
* space... However we must check if this is enough!
9390
*/
94-
newlen = 2 * str->len;
95-
while (buflen + str->len >= newlen - 1)
91+
newlen = 2 * str->maxlen;
92+
while (needed > newlen)
9693
newlen = 2 * newlen;
9794

9895
/*
@@ -105,18 +102,22 @@ appendStringInfo(StringInfo str, char *buffer)
105102
"appendStringInfo: Out of memory (%d bytes requested)",
106103
newlen);
107104
}
108-
memmove(s, str->data, str->len + 1);
105+
/*
106+
* transfer the data. strcpy() would work, but is probably a tad
107+
* slower than memcpy(), and since we know the string length...
108+
*/
109+
memcpy(s, str->data, str->len + 1);
109110
pfree(str->data);
110111
str->maxlen = newlen;
111112
str->data = s;
112113
}
113114

114115
/*
115116
* OK, we have enough space now, append 'buffer' at the end of the
116-
* string & update the string length. NOTE: this is a text string
117-
* (i.e. printable characters) so 'strcat' will do the job (no need to
118-
* use 'bcopy' et all...)
117+
* string & update the string length. NOTE: strcat() would work,
118+
* but is certainly slower than just memcpy'ing the data to the right
119+
* place.
119120
*/
120-
strcat(str->data, buffer);
121+
memcpy(str->data + str->len, buffer, buflen + 1);
121122
str->len += buflen;
122123
}

0 commit comments

Comments
 (0)