From 4b1145c455bfd164f44c477e22e974ad9b2546c0 Mon Sep 17 00:00:00 2001 From: Hiroshi Inoue Date: Sun, 24 Jan 2010 07:56:13 +0000 Subject: [PATCH] Removed the use of misused strcat_s together with snprintf_s (bug report from Jap-Peter Seifert) and use strlcat instead of strncat. --- configure.ac | 2 +- connection.c | 68 ++++++++++------------------------------------------ info.c | 4 ++-- misc.c | 27 +++++++++++++++++++++ misc.h | 3 +++ psqlodbc.h | 7 +----- qresult.c | 2 +- version.h | 2 +- 8 files changed, 49 insertions(+), 66 deletions(-) diff --git a/configure.ac b/configure.ac index 083e0c2..dbca4a7 100644 --- a/configure.ac +++ b/configure.ac @@ -274,7 +274,7 @@ AC_C_CONST # 7. Functions, global variables AC_FUNC_STRERROR_R -AC_CHECK_FUNCS(strtoul strtoll) +AC_CHECK_FUNCS(strtoul strtoll strlcpy) if test x"$enable_unicode" = xyes; then AC_CHECK_FUNCS(iswascii) diff --git a/connection.c b/connection.c index 53c1555..924632d 100644 --- a/connection.c +++ b/connection.c @@ -824,43 +824,24 @@ inolog("new_format=%d\n", new_format); truncated = SOCK_get_string(sock, new_format ? msgbuffer : msgbuf, new_format ? sizeof(msgbuffer) : buflen); if (new_format) { - size_t msgl; + size_t dstlen = 0; msgbuf[0] = '\0'; for (;msgbuffer[0];) { mylog("%s: 'E' - %s\n", comment, msgbuffer); qlog("ERROR from backend during %s: '%s'\n", comment, msgbuffer); - msgl = strlen(msgbuffer + 1); switch (msgbuffer[0]) { case 'S': - if (buflen > 0) - { - strncat(msgbuf, msgbuffer + 1, buflen); - buflen -= msgl; - } - if (buflen > 0) - { - strncat(msgbuf, ": ", buflen); - buflen -= 2; - } + strlcat(msgbuf, msgbuffer + 1, buflen); + dstlen = strlcat(msgbuf, ": ", buflen); break; case 'M': case 'D': - if (buflen > 0) - { - if (hasmsg) - { - strcat(msgbuf, "\n"); - buflen--; - } - if (buflen > 0) - { - strncat(msgbuf, msgbuffer + 1, buflen); - buflen -= msgl; - } - } + if (hasmsg) + strlcat(msgbuf, "\n", buflen); + dstlen = strlcat(msgbuf, msgbuffer + 1, buflen); if (truncated) msg_truncated = truncated; hasmsg = TRUE; @@ -870,8 +851,6 @@ inolog("new_format=%d\n", new_format); strncpy_null(sqlstate, msgbuffer + 1, 8); break; } - if (buflen < 0) - buflen = 0; while (truncated) truncated = SOCK_get_string(sock, msgbuffer, sizeof(msgbuffer)); truncated = SOCK_get_string(sock, msgbuffer, sizeof(msgbuffer)); @@ -929,7 +908,7 @@ handle_notice_message(ConnectionClass *self, char *msgbuf, size_t buflen, char * if (new_format) { - size_t msgl; + size_t dstlen = 0; msgbuf[0] = '\0'; for (;;) @@ -940,38 +919,17 @@ handle_notice_message(ConnectionClass *self, char *msgbuf, size_t buflen, char * mylog("%s: 'N' - %s\n", comment, msgbuffer); qlog("NOTICE from backend during %s: '%s'\n", comment, msgbuffer); - msgl = strlen(msgbuffer + 1); switch (msgbuffer[0]) { case 'S': - if (buflen > 0) - { - strncat(msgbuf, msgbuffer + 1, buflen); - buflen -= msgl; - } - if (buflen > 0) - { - strncat(msgbuf, ": ", buflen); - buflen -= 2; - } + strlcat(msgbuf, msgbuffer + 1, buflen); + dstlen = strlcat(msgbuf, ": ", buflen); break; case 'M': case 'D': - if (buflen > 0) - { - if (hasmsg) - { - strcat(msgbuf, "\n"); - buflen--; - } - if (buflen > 0) - { - strncat(msgbuf, msgbuffer + 1, buflen); - buflen -= msgl; - } - } - else - msg_truncated = TRUE; + if (hasmsg) + strlcat(msgbuf, "\n", buflen); + dstlen = strlcat(msgbuf, msgbuffer + 1, buflen); if (truncated) msg_truncated = truncated; hasmsg = TRUE; @@ -981,7 +939,7 @@ handle_notice_message(ConnectionClass *self, char *msgbuf, size_t buflen, char * strncpy_null(sqlstate, msgbuffer + 1, 8); break; } - if (buflen < 0) + if (dstlen >= buflen) msg_truncated = TRUE; while (truncated) truncated = SOCK_get_string(sock, msgbuffer, sizeof(msgbuffer)); diff --git a/info.c b/info.c index 2c71551..8ef8fe5 100644 --- a/info.c +++ b/info.c @@ -3713,7 +3713,7 @@ retry_public_schema: " where tc.oid = " FORMAT_UINT4 , reloid); - strncat(tables_query, + strlcat(tables_query, " AND tc.oid = i.indrelid" " AND n.oid = tc.relnamespace" " AND i.indisprimary = 't'" @@ -3743,7 +3743,7 @@ retry_public_schema: snprintf(tbqry, tsize, " where tc.oid = " FORMAT_UINT4, reloid); - strncat(tables_query, + strlcat(tables_query, " AND tc.oid = i.indrelid" " AND i.indisprimary = 't'" " AND ia.attrelid = i.indexrelid" diff --git a/misc.c b/misc.c index a226d75..71b94a0 100644 --- a/misc.c +++ b/misc.c @@ -330,3 +330,30 @@ snprintf_len(char *buf, size_t size, const char *format, ...) va_end(arglist); return len; } + +#ifndef HAVE_STRLCAT +size_t +strlcat(char *dst, const char *src, size_t size) +{ + size_t ttllen; + char *pd = dst; + const char *ps= src; + + for (ttllen = 0; ttllen < size; ttllen++, pd++) + { + if (0 == *pd) + break; + } + if (ttllen >= size - 1) + return ttllen + strlen(src); + for (; ttllen < size - 1; ttllen++, pd++, ps++) + { + if (0 == (*pd = *ps)) + return ttllen; + } + *pd = 0; + for (; *ps; ttllen++, ps++) + ; + return ttllen; +} +#endif /* HAVE_STRLCAT */ diff --git a/misc.h b/misc.h index 46d0423..c491409 100644 --- a/misc.h +++ b/misc.h @@ -128,6 +128,9 @@ void FinalizeLogging(); void remove_newlines(char *string); char *strncpy_null(char *dst, const char *src, ssize_t len); +#ifndef HAVE_STRLCPY +size_t strlcat(char *, const char *, size_t); +#endif /* HAVE_STRLCPY */ char *my_trim(char *string); char *make_string(const char *s, ssize_t len, char *buf, size_t bufsize); char *make_lstring_ifneeded(ConnectionClass *, const char *s, ssize_t len, BOOL); diff --git a/psqlodbc.h b/psqlodbc.h index 1c806a3..6b4314a 100644 --- a/psqlodbc.h +++ b/psqlodbc.h @@ -5,7 +5,7 @@ * * Comments: See "notice.txt" for copyright and license information. * - * $Id: psqlodbc.h,v 1.133 2010/01/17 13:10:41 hinoue Exp $ + * $Id: psqlodbc.h,v 1.134 2010/01/24 07:56:13 hinoue Exp $ * */ @@ -190,12 +190,7 @@ typedef double SDOUBLE; #define FALSE (BOOL)0 #endif /* FALSE */ #else -#if (_MSC_VER >= 1400) && !defined(_WIN64) -#define snprintf sprintf_s -#define strncat(d, s, l) strcat_s(d, l, s) -#else #define snprintf _snprintf -#endif #ifndef strdup #define strdup _strdup #endif /* strdup */ diff --git a/qresult.c b/qresult.c index 3d86cfe..01c24db 100644 --- a/qresult.c +++ b/qresult.c @@ -644,7 +644,7 @@ QR_close(QResultClass *self) CC_cursor_count(conn) <= 1) { mylog("QResult: END transaction on conn=%p\n", conn); - strncat(buf, ";commit", sizeof(buf)); + strlcat(buf, ";commit", sizeof(buf)); flag |= END_WITH_COMMIT; QR_set_cursor(self, NULL); } diff --git a/version.h b/version.h index 845fd74..25c78d7 100644 --- a/version.h +++ b/version.h @@ -12,6 +12,6 @@ #define POSTGRESDRIVERVERSION "08.04.0201" #define POSTGRES_RESOURCE_VERSION "08.04.0201\0" #define PG_DRVFILE_VERSION 8,4,02,01 -#define PG_BUILD_VERSION "201001230001" +#define PG_BUILD_VERSION "201001240001" #endif -- 2.39.5