Index: src/backend/lib/stringinfo.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/lib/stringinfo.c,v retrieving revision 1.48 diff -p -u -c -r1.48 stringinfo.c *** src/backend/lib/stringinfo.c 15 Nov 2007 21:14:35 -0000 1.48 --- src/backend/lib/stringinfo.c 23 Nov 2007 09:51:13 -0000 *************** appendStringInfo(StringInfo str, const c *** 81,97 **** { va_list args; bool success; /* Try to format the data. */ va_start(args, fmt); ! success = appendStringInfoVA(str, fmt, args); va_end(args); if (success) break; /* Double the buffer size and try again. */ ! enlargeStringInfo(str, str->maxlen); } } --- 81,98 ---- { va_list args; bool success; + int needmore; /* Try to format the data. */ va_start(args, fmt); ! success = appendStringInfoVA(str, fmt, args, &needmore); va_end(args); if (success) break; /* Double the buffer size and try again. */ ! enlargeStringInfo(str, needmore); } } *************** appendStringInfo(StringInfo str, const c *** 110,119 **** * that from here. */ bool ! appendStringInfoVA(StringInfo str, const char *fmt, va_list args) { int avail, ! nprinted; Assert(str != NULL); --- 111,120 ---- * that from here. */ bool ! appendStringInfoVA(StringInfo str, const char *fmt, va_list args, int *needmore) { int avail, ! nprinted = 0; Assert(str != NULL); *************** appendStringInfoVA(StringInfo str, const *** 123,129 **** */ avail = str->maxlen - str->len - 1; if (avail < 16) ! return false; /* * Assert check here is to catch buggy vsnprintf that overruns the --- 124,130 ---- */ avail = str->maxlen - str->len - 1; if (avail < 16) ! goto no_room; /* * Assert check here is to catch buggy vsnprintf that overruns the *************** appendStringInfoVA(StringInfo str, const *** 152,157 **** --- 153,166 ---- /* Restore the trailing null so that str is unmodified. */ str->data[str->len] = '\0'; + + /* + * Suggest how much more room is needed. On systems with broken + * vsnprintf() just double the buffer. + */ + no_room: + *needmore = (nprinted < str->maxlen) ? str->maxlen : nprinted + 1; + return false; } Index: src/backend/utils/adt/xml.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/xml.c,v retrieving revision 1.59 diff -p -u -c -r1.59 xml.c *** src/backend/utils/adt/xml.c 20 Nov 2007 23:14:41 -0000 1.59 --- src/backend/utils/adt/xml.c 23 Nov 2007 09:51:13 -0000 *************** xml_errorHandler(void *ctxt, const char *** 1402,1418 **** { va_list args; bool success; /* Try to format the data. */ va_start(args, msg); ! success = appendStringInfoVA(xml_err_buf, msg, args); va_end(args); if (success) break; ! /* Double the buffer size and try again. */ ! enlargeStringInfo(xml_err_buf, xml_err_buf->maxlen); } } --- 1402,1419 ---- { va_list args; bool success; + int needmore; /* Try to format the data. */ va_start(args, msg); ! success = appendStringInfoVA(xml_err_buf, msg, args, &needmore); va_end(args); if (success) break; ! /* Increase the buffer size and try again. */ ! enlargeStringInfo(xml_err_buf, needmore); } } Index: src/backend/utils/error/elog.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/error/elog.c,v retrieving revision 1.198 diff -p -u -c -r1.198 elog.c *** src/backend/utils/error/elog.c 15 Nov 2007 21:14:40 -0000 1.198 --- src/backend/utils/error/elog.c 23 Nov 2007 09:51:13 -0000 *************** errcode_for_socket_access(void) *** 610,621 **** { \ va_list args; \ bool success; \ va_start(args, fmt); \ ! success = appendStringInfoVA(&buf, fmtbuf, args); \ va_end(args); \ if (success) \ break; \ ! enlargeStringInfo(&buf, buf.maxlen); \ } \ /* Done with expanded fmt */ \ pfree(fmtbuf); \ --- 610,622 ---- { \ va_list args; \ bool success; \ + int needmore; \ va_start(args, fmt); \ ! success = appendStringInfoVA(&buf, fmtbuf, args, &needmore); \ va_end(args); \ if (success) \ break; \ ! enlargeStringInfo(&buf, needmore); \ } \ /* Done with expanded fmt */ \ pfree(fmtbuf); \ Index: src/include/lib/stringinfo.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/lib/stringinfo.h,v retrieving revision 1.34 diff -p -u -c -r1.34 stringinfo.h *** src/include/lib/stringinfo.h 3 Mar 2007 19:32:55 -0000 1.34 --- src/include/lib/stringinfo.h 23 Nov 2007 09:51:13 -0000 *************** __attribute__((format(printf, 2, 3))); *** 105,111 **** * without modifying str. Typically the caller would enlarge str and retry * on false return --- see appendStringInfo for standard usage pattern. */ ! extern bool appendStringInfoVA(StringInfo str, const char *fmt, va_list args); /*------------------------ * appendStringInfoString --- 105,111 ---- * without modifying str. Typically the caller would enlarge str and retry * on false return --- see appendStringInfo for standard usage pattern. */ ! extern bool appendStringInfoVA(StringInfo str, const char *fmt, va_list args, int *needmore); /*------------------------ * appendStringInfoString Index: src/pl/plpython/plpython.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/pl/plpython/plpython.c,v retrieving revision 1.105 diff -p -u -c -r1.105 plpython.c *** src/pl/plpython/plpython.c 23 Nov 2007 01:46:34 -0000 1.105 --- src/pl/plpython/plpython.c 23 Nov 2007 09:51:14 -0000 *************** PLy_elog(int elevel, const char *fmt,... *** 2908,2920 **** { va_list ap; bool success; va_start(ap, fmt); ! success = appendStringInfoVA(&emsg, fmt, ap); va_end(ap); if (success) break; ! enlargeStringInfo(&emsg, emsg.maxlen); } PG_TRY(); --- 2908,2921 ---- { va_list ap; bool success; + int needmore; va_start(ap, fmt); ! success = appendStringInfoVA(&emsg, fmt, ap, &needmore); va_end(ap); if (success) break; ! enlargeStringInfo(&emsg, needmore); } PG_TRY();