pgpool2.git / summary / log / commit / refs

commit    b5fc85549f7e34ea3e72ec9bb6d2b9e4c9cfcf41
Author:   Tatsuo Ishii <ishii@postgresql.org>
Date:     Tue May 20 08:17:20 2014 +0000

    Remove fix buffer size restrictionn of pool_extract_error_message().
    
    Per bug #90 (pool_extract_error_message: not enough buffer space).
    With upcoming 3.4, we can use StringInfo infrastructure, and can
    remove the restriction easily. The API for the function has been
    changed: returns palloc'd buffer space. To adopt this, some client
    functions in pool_process_query.c and pool_auth.c have been changed.


src/auth/pool_auth.c | 7 +++- src/protocol/pool_process_query.c | 72 +++++++++++++++------------------------ 2 files changed, 33 insertions(+), 46 deletions(-) diff --git a/src/auth/pool_auth.c b/src/auth/pool_auth.c index 9188491f1..b7c543a5a 100644 --- a/src/auth/pool_auth.c +++ b/src/auth/pool_auth.c @@ -1158,15 +1158,20 @@ signed char pool_read_kind(POOL_CONNECTION_POOL *cp) if (kind0 == 'E') { if (pool_extract_error_message(false, MASTER(cp), MAJOR(cp), true, &message) == 1) + { ereport(LOG, (errmsg("pool_read_kind: error message from master backend:%s", message))); - + pfree(message); + } } else if (kind == 'E') { if (pool_extract_error_message(false, CONNECTION(cp, i), MAJOR(cp), true, &message) == 1) + { ereport(LOG, (errmsg("pool_read_kind: error message from %d th backend:%s", i, message))); + pfree(message); + } } ereport(ERROR, (errmsg("unable to read message kind"), diff --git a/src/protocol/pool_process_query.c b/src/protocol/pool_process_query.c index f1c3dfd8c..f479626b9 100644 --- a/src/protocol/pool_process_query.c +++ b/src/protocol/pool_process_query.c @@ -3707,6 +3707,7 @@ POOL_STATUS read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_PO { string_append_char(msg, m); string_append_char(msg, "]"); + pfree(m); } else { @@ -4348,29 +4349,29 @@ static int detect_error(POOL_CONNECTION *backend, char *error_code, int major, c /* * pool_extract_error_message: Extract human readable message from - * ERROR/NOTICE reponse packet and return it. If read_kind is true, - * kind will be read in this function. If read_kind is false, kind + * ERROR/NOTICE reponse packet and return it. If "read_kind" is true, + * kind will be read in this function. If "read_kind" is false, kind * should have been already read and it should be either 'E' or - * 'N'.The returned string is placed in static buffer. Message larger - * than the buffer will be silently truncated. Be warned that next - * call to this function will break the buffer. If unread is true, - * the packet will be returned to the stream. + * 'N'. The returned string is in palloc'd buffer. Callers must pfree + * it if it becomes neccessary. + * + * If "unread" is true, the packet will be returned to the stream. * * Return values are: * 0: not error or notice message * 1: succeeded to extract error message * -1: error) - * we do not throw elog from this function */ int pool_extract_error_message(bool read_kind, POOL_CONNECTION *backend, int major, bool unread, char **message) { char kind; int readlen = 0, len; - static char buf[8192]; /* unread buffer */ - static char message_buf[8192]; /* mesasge buffer */ - char *p, *str; + StringInfo str_buf; /* unread buffer */ + StringInfo str_message_buf; /* message buffer */ + char *str; - p = buf; + str_buf = makeStringInfo(); + str_message_buf = makeStringInfo(); PG_TRY(); { @@ -4381,12 +4382,15 @@ int pool_extract_error_message(bool read_kind, POOL_CONNECTION *backend, int maj pool_read(backend, &kind, len); readlen += len; - memcpy(p, &kind, len); - p += len; + appendStringInfoChar(str_buf, kind); if (kind != 'E' && kind != 'N') { - pool_unread(backend, buf, readlen); + pool_unread(backend, str_buf->data, readlen); + pfree(str_message_buf->data); + pfree(str_message_buf); + pfree(str_buf->data); + pfree(str_buf); return 0; } } @@ -4398,26 +4402,14 @@ int pool_extract_error_message(bool read_kind, POOL_CONNECTION *backend, int maj pool_read(backend, &len, sizeof(len)); readlen += sizeof(len); - memcpy(p, &len, sizeof(len)); - p += sizeof(len); + appendBinaryStringInfo(str_buf, (const char *)&len, sizeof(len)); len = ntohl(len) - 4; str = palloc(len); pool_read(backend, str, len); readlen += len; - - if (readlen >= sizeof(buf)) - { - ereport(NOTICE, - (errmsg("unable to extract error message"), - errdetail("not enough buffer space"))); - - pfree(str); - return -1; - } - - memcpy(p, str, len); + appendBinaryStringInfo(str_buf, str, len); /* * Checks error code which is formatted 'Mxxxxxx' @@ -4429,8 +4421,7 @@ int pool_extract_error_message(bool read_kind, POOL_CONNECTION *backend, int maj if (*e == 'M') { e++; - strncpy(message_buf, e, sizeof(message_buf)-1); - message_buf[sizeof(message_buf)-1] = '\0'; + appendStringInfoString(str_message_buf, e); break; } else @@ -4441,29 +4432,20 @@ int pool_extract_error_message(bool read_kind, POOL_CONNECTION *backend, int maj else { str = pool_read_string(backend, &len, 0); - len = Min(sizeof(message_buf)-1, len); readlen += len; - - if (readlen >= sizeof(buf)) - { - ereport(NOTICE, - (errmsg("unable to extract error message"), - errdetail("not enough buffer space"))); - return -1; - } - - memcpy(p, str, len); - memcpy(message_buf, str, len); - message_buf[len] = '\0'; + appendStringInfoString(str_message_buf, str); } if (unread) { /* Put the message to read buffer */ - pool_unread(backend, buf, readlen); + pool_unread(backend, str_buf->data, readlen); } - *message = message_buf; + *message = str_message_buf->data; + pfree(str_message_buf); + pfree(str_buf->data); + pfree(str_buf); } PG_CATCH(); { [parent: 8e9f7edc33e6]