Patch for snprintf problem (bug #1000650)

Patch for snprintf problem (bug #1000650)

am 07.06.2006 19:39:10 von Ludek Finstrle

--3MwIy2ne0vdjdPXF
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hello,

I found the problem in snprintf on linux (maybe another unix) boxes
in info.c (CVS HEAD). The problematic part is something like:

buf = "text";
snprintf(buf,size,"%s append",buf);

buf = "text append" on Windows (MS VC compiler)
buf = " append" on linux (gcc compiler)

I solve it this way (main idea):
snprintf(buf + strlen(buf), " append");

There are more parameters (char *, int, ...) in real usage.
More details is here:
http://pgfoundry.org/tracker/index.php?func=detail&aid=10006 50&group_id=1000125&atid=538

The patch is created againist CVS.

Comments are welcome

Luf

--3MwIy2ne0vdjdPXF
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="psqlodbc_snprintf.diff"

diff -c psqlodbc.orig\info.c psqlodbc\info.c
*** psqlodbc.orig\info.c Mon May 29 20:26:44 2006
--- psqlodbc\info.c Wed Jun 07 18:35:10 2006
***************
*** 1943,1961 ****
" inner join pg_catalog.pg_namespace n on n.oid = c.relnamespace",
sizeof(columns_query));
if (search_by_ids)
! snprintf(columns_query, sizeof(columns_query), "%s and c.oid = %u", columns_query, reloid);
else
{
if (escTableName)
! snprintf(columns_query, sizeof(columns_query), "%s and c.relname %s '%s'", columns_query, like_or_eq, escTableName);
schema_strcat1(columns_query, " and n.nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
strcat(columns_query, ") inner join pg_catalog.pg_attribute a"
" on (not a.attisdropped) and a.attnum > 0");
if (search_by_ids)
! snprintf(columns_query, sizeof(columns_query), "%s and a.attnum = %d", columns_query, attnum);
else if (escColumnName)
! snprintf(columns_query, sizeof(columns_query), "%s and a.attname %s '%s'", columns_query, like_or_eq, escColumnName);
strcat(columns_query,
" and a.attrelid = c.oid) inner join pg_catalog.pg_type t"
" on t.oid = a.atttypid) left outer join pg_attrdef d"
--- 1943,1962 ----
" inner join pg_catalog.pg_namespace n on n.oid = c.relnamespace",
sizeof(columns_query));
if (search_by_ids)
! snprintf(columns_query + strlen(columns_query), sizeof(columns_query), " and c.oid = %u", reloid);
else
{
if (escTableName)
! snprintf(columns_query + strlen(columns_query), sizeof(columns_query), " and c.relname %s '%s'", like_or_eq, escTableName);
schema_strcat1(columns_query, " and n.nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
strcat(columns_query, ") inner join pg_catalog.pg_attribute a"
" on (not a.attisdropped) and a.attnum > 0");
+
if (search_by_ids)
! snprintf(columns_query + strlen(columns_query), sizeof(columns_query), " and a.attnum = %d", attnum);
else if (escColumnName)
! snprintf(columns_query + strlen(columns_query), sizeof(columns_query), " and a.attname %s '%s'", like_or_eq, escColumnName);
strcat(columns_query,
" and a.attrelid = c.oid) inner join pg_catalog.pg_type t"
" on t.oid = a.atttypid) left outer join pg_attrdef d"
***************
*** 1973,1982 ****
" and a.atttypid = t.oid and (a.attnum > 0)",
PG_VERSION_LE(conn, 6.2) ? "a.attlen" : "a.atttypmod");
if (escTableName)
! snprintf(columns_query, sizeof(columns_query), "%s and c.relname %s '%s'", columns_query, like_or_eq, escTableName);
my_strcat1(columns_query, " and u.usename %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escColumnName)
! snprintf(columns_query, sizeof(columns_query), "%s and a.attname %s '%s'", columns_query, like_or_eq, escColumnName);
strcat(columns_query, " order by c.relname, attnum");
}

--- 1974,1983 ----
" and a.atttypid = t.oid and (a.attnum > 0)",
PG_VERSION_LE(conn, 6.2) ? "a.attlen" : "a.atttypmod");
if (escTableName)
! snprintf(columns_query + strlen(columns_query), sizeof(columns_query), " and c.relname %s '%s'", like_or_eq, escTableName);
my_strcat1(columns_query, " and u.usename %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escColumnName)
! snprintf(columns_query + strlen(columns_query), sizeof(columns_query), " and a.attname %s '%s'", like_or_eq, escColumnName);
strcat(columns_query, " order by c.relname, attnum");
}

***************
*** 2537,2543 ****
/* TableName cannot contain a string search pattern */
/* my_strcat(columns_query, " and c.relname = '%.*s'", szTableName, cbTableName); */
if (escTableName)
! snprintf(columns_query, sizeof(columns_query), "%s and c.relname = '%s'", columns_query, escTableName);
/* SchemaName cannot contain a string search pattern */
if (conn->schema_support)
schema_strcat(columns_query, " and u.nspname = '%.*s'", escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
--- 2538,2544 ----
/* TableName cannot contain a string search pattern */
/* my_strcat(columns_query, " and c.relname = '%.*s'", szTableName, cbTableName); */
if (escTableName)
! snprintf(columns_query + strlen(columns_query), sizeof(columns_query), " and c.relname = '%s'", escTableName);
/* SchemaName cannot contain a string search pattern */
if (conn->schema_support)
schema_strcat(columns_query, " and u.nspname = '%.*s'", escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
***************
*** 3217,3222 ****
--- 3218,3224 ----
char *escSchemaName = NULL, *escTableName = NULL, *escColumnName = NULL;
const char *like_or_eq;
char column_query[INFO_INQUIRY_LEN];
+ int cq_len;
BOOL search_pattern;
QResultClass *res;

***************
*** 3245,3259 ****
" table_name, column_name, grantor, grantee,"
" privilege_type as PRIVILEGE, is_grantable from"
" information_schema.column_privileges where true");
if (escSchemaName)
! snprintf(column_query, sizeof(column_query),
! "%s and table_schem = '%s'", column_query, escSchemaName);
if (escTableName)
! snprintf(column_query, sizeof(column_query),
! "%s and table_name = '%s'", column_query, escTableName);
if (escColumnName)
! snprintf(column_query, sizeof(column_query),
! "%s and column_name %s '%s'", column_query, like_or_eq, escColumnName);
if (res = CC_send_query(conn, column_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(res))
{
SC_set_error(stmt, STMT_EXEC_ERROR, "PGAPI_ColumnPrivileges query error", func);
--- 3247,3262 ----
" table_name, column_name, grantor, grantee,"
" privilege_type as PRIVILEGE, is_grantable from"
" information_schema.column_privileges where true");
+ cq_len = strlen(column_query);
if (escSchemaName)
! cq_len += strlen_snprintf(column_query + cq_len, sizeof(column_query),
! " and table_schem = '%s'", escSchemaName);
if (escTableName)
! cq_len += strlen_snprintf(column_query + cq_len, sizeof(column_query),
! " and table_name = '%s'", escTableName);
if (escColumnName)
! cq_len += strlen_snprintf(column_query + cq_len, sizeof(column_query),
! " and column_name %s '%s'", like_or_eq, escColumnName);
if (res = CC_send_query(conn, column_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(res))
{
SC_set_error(stmt, STMT_EXEC_ERROR, "PGAPI_ColumnPrivileges query error", func);
***************
*** 4570,4576 ****
strcat(proc_query, " has_function_privilege(p.oid, 'EXECUTE')");
my_strcat1(proc_query, " and nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escProcName)
! snprintf(proc_query, sizeof(proc_query), "%s and proname %s '%s'", proc_query, like_or_eq, escProcName);
strcat(proc_query, " order by nspname, proname, p.oid, attnum");
}
else
--- 4573,4579 ----
strcat(proc_query, " has_function_privilege(p.oid, 'EXECUTE')");
my_strcat1(proc_query, " and nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escProcName)
! snprintf(proc_query + strlen(proc_query), sizeof(proc_query), " and proname %s '%s'", like_or_eq, escProcName);
strcat(proc_query, " order by nspname, proname, p.oid, attnum");
}
else
***************
*** 4580,4586 ****
"(not proretset)");
ret_col = 5;
if (escProcName)
! snprintf(proc_query, sizeof(proc_query), " and proname %s '%s'", proc_query, like_or_eq, escProcName);
strcat(proc_query, " order by proname, proretset");
}
if (tres = CC_send_query(conn, proc_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(tres))
--- 4583,4589 ----
"(not proretset)");
ret_col = 5;
if (escProcName)
! snprintf(proc_query + strlen(proc_query), sizeof(proc_query), " and proname %s '%s'", like_or_eq, escProcName);
strcat(proc_query, " order by proname, proretset");
}
if (tres = CC_send_query(conn, proc_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(tres))
***************
*** 5115,5121 ****
schema_strcat1(proc_query, " nspname %s '%.*s' and", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
if (escTableName)
! snprintf(proc_query, sizeof(proc_query), "%s relname %s '%s' and", proc_query, like_or_eq, escTableName);
if (conn->schema_support)
{
strcat(proc_query, " pg_namespace.oid = relnamespace and relkind in ('r', 'v') and");
--- 5118,5124 ----
schema_strcat1(proc_query, " nspname %s '%.*s' and", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
if (escTableName)
! snprintf(proc_query + strlen(proc_query), sizeof(proc_query), " relname %s '%s' and", like_or_eq, escTableName);
if (conn->schema_support)
{
strcat(proc_query, " pg_namespace.oid = relnamespace and relkind in ('r', 'v') and");
diff -c psqlodbc.orig\misc.c psqlodbc\misc.c
*** psqlodbc.orig\misc.c Mon May 29 20:26:44 2006
--- psqlodbc\misc.c Wed Jun 07 18:59:15 2006
***************
*** 291,293 ****
--- 291,311 ----
}
return my_strcat1(buf, fmt, s1, s, len);
}
+
+ /*
+ * strlen_snprintf is a extension to snprintf
+ * It returns strlen of buf every time (not -1 when truncated)
+ */
+
+ int
+ strlen_snprintf(char *buf, size_t size, const char *format, ...)
+ {
+ int len;
+ va_list arglist;
+
+ va_start(arglist, buf);
+ if ((len = vsnprintf(buf, size, format, arglist)) < 0)
+ len = size;
+ va_end(arglist);
+ return len;
+ }
diff -c psqlodbc.orig\misc.h psqlodbc\misc.h
*** psqlodbc.orig\misc.h Mon May 29 20:26:44 2006
--- psqlodbc\misc.h Wed Jun 07 15:37:52 2006
***************
*** 132,137 ****
--- 132,138 ----
char *schema_strcat1(char *buf, const char *fmt, const char *s1,
const char *s, int len,
const char *, int, ConnectionClass *conn);
+ int strlen_snprintf(char *buf, size_t size, const char *format, ...);
/* #define GET_SCHEMA_NAME(nspname) (stricmp(nspname, "public") ? nspname : "") */
#define GET_SCHEMA_NAME(nspname) (nspname)

diff -c psqlodbc.orig\psqlodbc.h psqlodbc\psqlodbc.h
*** psqlodbc.orig\psqlodbc.h Mon May 29 20:28:38 2006
--- psqlodbc\psqlodbc.h Wed Jun 07 18:15:47 2006
***************
*** 110,115 ****
--- 110,116 ----
#define strnicmp _strnicmp
#define stricmp _stricmp
#define strdup _strdup
+ #define vsnprintf _vsnprintf
#endif

#ifndef SQL_ATTR_APP_ROW_DESC

--3MwIy2ne0vdjdPXF
Content-Type: text/plain
Content-Disposition: inline
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable


---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster

--3MwIy2ne0vdjdPXF--

Re: Patch for snprintf problem (bug #1000650)

am 07.06.2006 22:15:16 von Ludek Finstrle

--k1lZvvs/B4yU6o8G
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

> I solve it this way (main idea):
> snprintf(buf + strlen(buf), " append");

Ugh typo mistake:

snprintf(buf + strlen(buf), sizeof(buf), " append");

My hands are faster than my head :-(
There is buffer overrun erron becouse I have to decrease sizeof(buf) with
strlen(buf).

So I attach second try of this patch againist CVS HEAD.

Comments are welcome

Luf

--k1lZvvs/B4yU6o8G
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="psqlodbc_snprintf_2try.diff"

diff -c psqlodbc.orig\info.c psqlodbc\info.c
*** psqlodbc.orig\info.c Mon May 29 20:26:44 2006
--- psqlodbc\info.c Wed Jun 07 21:39:03 2006
***************
*** 1943,1961 ****
" inner join pg_catalog.pg_namespace n on n.oid = c.relnamespace",
sizeof(columns_query));
if (search_by_ids)
! snprintf(columns_query, sizeof(columns_query), "%s and c.oid = %u", columns_query, reloid);
else
{
if (escTableName)
! snprintf(columns_query, sizeof(columns_query), "%s and c.relname %s '%s'", columns_query, like_or_eq, escTableName);
schema_strcat1(columns_query, " and n.nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
strcat(columns_query, ") inner join pg_catalog.pg_attribute a"
" on (not a.attisdropped) and a.attnum > 0");
if (search_by_ids)
! snprintf(columns_query, sizeof(columns_query), "%s and a.attnum = %d", columns_query, attnum);
else if (escColumnName)
! snprintf(columns_query, sizeof(columns_query), "%s and a.attname %s '%s'", columns_query, like_or_eq, escColumnName);
strcat(columns_query,
" and a.attrelid = c.oid) inner join pg_catalog.pg_type t"
" on t.oid = a.atttypid) left outer join pg_attrdef d"
--- 1943,1962 ----
" inner join pg_catalog.pg_namespace n on n.oid = c.relnamespace",
sizeof(columns_query));
if (search_by_ids)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and c.oid = %u", reloid);
else
{
if (escTableName)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and c.relname %s '%s'", like_or_eq, escTableName);
schema_strcat1(columns_query, " and n.nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
strcat(columns_query, ") inner join pg_catalog.pg_attribute a"
" on (not a.attisdropped) and a.attnum > 0");
+
if (search_by_ids)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and a.attnum = %d", attnum);
else if (escColumnName)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and a.attname %s '%s'", like_or_eq, escColumnName);
strcat(columns_query,
" and a.attrelid = c.oid) inner join pg_catalog.pg_type t"
" on t.oid = a.atttypid) left outer join pg_attrdef d"
***************
*** 1973,1982 ****
" and a.atttypid = t.oid and (a.attnum > 0)",
PG_VERSION_LE(conn, 6.2) ? "a.attlen" : "a.atttypmod");
if (escTableName)
! snprintf(columns_query, sizeof(columns_query), "%s and c.relname %s '%s'", columns_query, like_or_eq, escTableName);
my_strcat1(columns_query, " and u.usename %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escColumnName)
! snprintf(columns_query, sizeof(columns_query), "%s and a.attname %s '%s'", columns_query, like_or_eq, escColumnName);
strcat(columns_query, " order by c.relname, attnum");
}

--- 1974,1983 ----
" and a.atttypid = t.oid and (a.attnum > 0)",
PG_VERSION_LE(conn, 6.2) ? "a.attlen" : "a.atttypmod");
if (escTableName)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and c.relname %s '%s'", like_or_eq, escTableName);
my_strcat1(columns_query, " and u.usename %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escColumnName)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and a.attname %s '%s'", like_or_eq, escColumnName);
strcat(columns_query, " order by c.relname, attnum");
}

***************
*** 2537,2543 ****
/* TableName cannot contain a string search pattern */
/* my_strcat(columns_query, " and c.relname = '%.*s'", szTableName, cbTableName); */
if (escTableName)
! snprintf(columns_query, sizeof(columns_query), "%s and c.relname = '%s'", columns_query, escTableName);
/* SchemaName cannot contain a string search pattern */
if (conn->schema_support)
schema_strcat(columns_query, " and u.nspname = '%.*s'", escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
--- 2538,2544 ----
/* TableName cannot contain a string search pattern */
/* my_strcat(columns_query, " and c.relname = '%.*s'", szTableName, cbTableName); */
if (escTableName)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and c.relname = '%s'", escTableName);
/* SchemaName cannot contain a string search pattern */
if (conn->schema_support)
schema_strcat(columns_query, " and u.nspname = '%.*s'", escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
***************
*** 3217,3222 ****
--- 3218,3224 ----
char *escSchemaName = NULL, *escTableName = NULL, *escColumnName = NULL;
const char *like_or_eq;
char column_query[INFO_INQUIRY_LEN];
+ int cq_len;
BOOL search_pattern;
QResultClass *res;

***************
*** 3245,3259 ****
" table_name, column_name, grantor, grantee,"
" privilege_type as PRIVILEGE, is_grantable from"
" information_schema.column_privileges where true");
if (escSchemaName)
! snprintf(column_query, sizeof(column_query),
! "%s and table_schem = '%s'", column_query, escSchemaName);
if (escTableName)
! snprintf(column_query, sizeof(column_query),
! "%s and table_name = '%s'", column_query, escTableName);
if (escColumnName)
! snprintf(column_query, sizeof(column_query),
! "%s and column_name %s '%s'", column_query, like_or_eq, escColumnName);
if (res = CC_send_query(conn, column_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(res))
{
SC_set_error(stmt, STMT_EXEC_ERROR, "PGAPI_ColumnPrivileges query error", func);
--- 3247,3262 ----
" table_name, column_name, grantor, grantee,"
" privilege_type as PRIVILEGE, is_grantable from"
" information_schema.column_privileges where true");
+ cq_len = strlen(column_query);
if (escSchemaName)
! cq_len += snprintf_addlen(column_query, cq_len, sizeof(column_query),
! " and table_schem = '%s'", escSchemaName);
if (escTableName)
! cq_len += snprintf_addlen(column_query, cq_len, sizeof(column_query),
! " and table_name = '%s'", escTableName);
if (escColumnName)
! cq_len += snprintf_addlen(column_query, cq_len, sizeof(column_query),
! " and column_name %s '%s'", like_or_eq, escColumnName);
if (res = CC_send_query(conn, column_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(res))
{
SC_set_error(stmt, STMT_EXEC_ERROR, "PGAPI_ColumnPrivileges query error", func);
***************
*** 4570,4576 ****
strcat(proc_query, " has_function_privilege(p.oid, 'EXECUTE')");
my_strcat1(proc_query, " and nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escProcName)
! snprintf(proc_query, sizeof(proc_query), "%s and proname %s '%s'", proc_query, like_or_eq, escProcName);
strcat(proc_query, " order by nspname, proname, p.oid, attnum");
}
else
--- 4573,4579 ----
strcat(proc_query, " has_function_privilege(p.oid, 'EXECUTE')");
my_strcat1(proc_query, " and nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escProcName)
! snprintf_add(proc_query, strlen(proc_query), sizeof(proc_query), " and proname %s '%s'", like_or_eq, escProcName);
strcat(proc_query, " order by nspname, proname, p.oid, attnum");
}
else
***************
*** 4580,4586 ****
"(not proretset)");
ret_col = 5;
if (escProcName)
! snprintf(proc_query, sizeof(proc_query), " and proname %s '%s'", proc_query, like_or_eq, escProcName);
strcat(proc_query, " order by proname, proretset");
}
if (tres = CC_send_query(conn, proc_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(tres))
--- 4583,4589 ----
"(not proretset)");
ret_col = 5;
if (escProcName)
! snprintf_add(proc_query, strlen(proc_query), sizeof(proc_query), " and proname %s '%s'", like_or_eq, escProcName);
strcat(proc_query, " order by proname, proretset");
}
if (tres = CC_send_query(conn, proc_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(tres))
***************
*** 5115,5121 ****
schema_strcat1(proc_query, " nspname %s '%.*s' and", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
if (escTableName)
! snprintf(proc_query, sizeof(proc_query), "%s relname %s '%s' and", proc_query, like_or_eq, escTableName);
if (conn->schema_support)
{
strcat(proc_query, " pg_namespace.oid = relnamespace and relkind in ('r', 'v') and");
--- 5118,5124 ----
schema_strcat1(proc_query, " nspname %s '%.*s' and", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
if (escTableName)
! snprintf_add(proc_query, strlen(proc_query), sizeof(proc_query), " relname %s '%s' and", like_or_eq, escTableName);
if (conn->schema_support)
{
strcat(proc_query, " pg_namespace.oid = relnamespace and relkind in ('r', 'v') and");
diff -c psqlodbc.orig\misc.c psqlodbc\misc.c
*** psqlodbc.orig\misc.c Mon May 29 20:26:44 2006
--- psqlodbc\misc.c Wed Jun 07 21:56:09 2006
***************
*** 291,293 ****
--- 291,328 ----
}
return my_strcat1(buf, fmt, s1, s, len);
}
+
+ /*
+ * snprintf_add is a extension to snprintf
+ * It add format to buf at given pos
+ */
+
+ int
+ snprintf_add(char *buf, size_t pos, size_t size, const char *format, ...)
+ {
+ int len;
+ va_list arglist;
+
+ va_start(arglist, format);
+ len = vsnprintf(buf + pos, size - pos, format, arglist);
+ va_end(arglist);
+ return len;
+ }
+
+ /*
+ * snprintf_addlen is a extension to snprintf_add
+ * It returns strlen of buf every time (not -1 when truncated)
+ */
+
+ int
+ snprintf_addlen(char *buf, size_t pos, size_t size, const char *format, ...)
+ {
+ int len;
+ va_list arglist;
+
+ va_start(arglist, format);
+ if ((len = vsnprintf(buf + pos, size - pos, format, arglist)) < 0)
+ len = size;
+ va_end(arglist);
+ return len;
+ }
diff -c psqlodbc.orig\misc.h psqlodbc\misc.h
*** psqlodbc.orig\misc.h Mon May 29 20:26:44 2006
--- psqlodbc\misc.h Wed Jun 07 21:40:25 2006
***************
*** 132,137 ****
--- 132,139 ----
char *schema_strcat1(char *buf, const char *fmt, const char *s1,
const char *s, int len,
const char *, int, ConnectionClass *conn);
+ int snprintf_add(char *buf, size_t pos, size_t size, const char *format, ...);
+ int snprintf_addlen(char *buf, size_t pos, size_t size, const char *format, ...);
/* #define GET_SCHEMA_NAME(nspname) (stricmp(nspname, "public") ? nspname : "") */
#define GET_SCHEMA_NAME(nspname) (nspname)

diff -c psqlodbc.orig\psqlodbc.h psqlodbc\psqlodbc.h
*** psqlodbc.orig\psqlodbc.h Mon May 29 20:28:38 2006
--- psqlodbc\psqlodbc.h Wed Jun 07 18:15:47 2006
***************
*** 110,115 ****
--- 110,116 ----
#define strnicmp _strnicmp
#define stricmp _stricmp
#define strdup _strdup
+ #define vsnprintf _vsnprintf
#endif

#ifndef SQL_ATTR_APP_ROW_DESC

--k1lZvvs/B4yU6o8G
Content-Type: text/plain
Content-Disposition: inline
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable


---------------------------(end of broadcast)---------------------------
TIP 1: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to majordomo@postgresql.org so that your
message can get through to the mailing list cleanly

--k1lZvvs/B4yU6o8G--

Re: Patch for snprintf problem (bug #1000650)

am 09.06.2006 01:46:50 von Hiroshi Inoue

Ludek Finstrle wrote:
> Hello,
>
> I found the problem in snprintf on linux (maybe another unix) boxes
> in info.c (CVS HEAD). The problematic part is something like:
>
> buf = "text";
> snprintf(buf,size,"%s append",buf);
>
> buf = "text append" on Windows (MS VC compiler)
> buf = " append" on linux (gcc compiler)
>
> I solve it this way (main idea):
> snprintf(buf + strlen(buf), " append");

Hmm bad news.
If so, it may be better to use the sequence like the following for example.

char *query_ptr;
size_t bufsize_res;
int slen;

/* Initialize */
query_ptr = columns_query;
bufsize_res = sizeof(columns_query);

if (..)
{
if ((slen = snprintf(query_ptr, bufsize_res, .., )) <= 0)
{
.. error_handling ..
}
query_ptr += slen;
bufsize_res -= slen;
}

...

regards,
Hiroshi Inoue

---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?

http://archives.postgresql.org

Re: Patch for snprintf problem (bug #1000650)

am 09.06.2006 10:16:37 von Ludek Finstrle

> > buf = "text";
> > snprintf(buf,size,"%s append",buf);
> >
> > buf = "text append" on Windows (MS VC compiler)
> > buf = " append" on linux (gcc compiler)
> >
> > I solve it this way (main idea):
> > snprintf(buf + strlen(buf), " append");
>
> Hmm bad news.
> If so, it may be better to use the sequence like the following for example.
>
> char *query_ptr;
> size_t bufsize_res;
> int slen;
>
> /* Initialize */
> query_ptr = columns_query;
> bufsize_res = sizeof(columns_query);
>
> if (..)
> {
> if ((slen = snprintf(query_ptr, bufsize_res, .., )) <= 0)
> {
> .. error_handling ..
> }
> query_ptr += slen;
> bufsize_res -= slen;
> }
>
> ...

I'm not sure. There are a lot of strcat, my_strcat, schema_strcat calls
between snprintf. There is only one place where snprintf could be called
after another snprintf.
BTW it's something what snprintf_addlen is doing. Or am I miss something?

I do the patch with minimal changes in mind. In my opinion strcat
may be faster in joining more char *.

Regards,

Luf

---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster

Re: Patch for snprintf problem (bug #1000650) 3-rd try

am 09.06.2006 14:13:23 von Ludek Finstrle

> > > buf = "text";
> > > snprintf(buf,size,"%s append",buf);
> > >
> > > buf = "text append" on Windows (MS VC compiler)
> > > buf = " append" on linux (gcc compiler)
> > >
> > > I solve it this way (main idea):
> > > snprintf(buf + strlen(buf), " append");
> >
> > Hmm bad news.
> > If so, it may be better to use the sequence like the following for example.
> >
> > char *query_ptr;
> > size_t bufsize_res;
> > int slen;
> >
> > /* Initialize */
> > query_ptr = columns_query;
> > bufsize_res = sizeof(columns_query);
> >
> > if (..)
> > {
> > if ((slen = snprintf(query_ptr, bufsize_res, .., )) <= 0)
> > {
> > .. error_handling ..
> > }
> > query_ptr += slen;
> > bufsize_res -= slen;
> > }
> >
> > ...
>
> I'm not sure. There are a lot of strcat, my_strcat, schema_strcat calls
> between snprintf. There is only one place where snprintf could be called
> after another snprintf.

I change the snprintf_addlen to snprintf_len as you mentioned.

Third try of patch attached.

Comments are welcome

Luf

---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend

Re: Patch for snprintf problem (bug #1000650) 3-rd try

am 09.06.2006 14:14:54 von Ludek Finstrle

--huq684BweRXVnRxX
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

> I change the snprintf_addlen to snprintf_len as you mentioned.
>
> Third try of patch attached.

I forgot attach the patch.

Luf

--huq684BweRXVnRxX
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="psqlodbc_snprintf_3try.diff"

diff -c psqlodbc.orig/info.c psqlodbc/info.c
*** psqlodbc.orig/info.c 2006-06-06 10:37:00.425541000 +0200
--- psqlodbc/info.c 2006-06-09 14:00:12.564965740 +0200
***************
*** 1943,1961 ****
" inner join pg_catalog.pg_namespace n on n.oid = c.relnamespace",
sizeof(columns_query));
if (search_by_ids)
! snprintf(columns_query, sizeof(columns_query), "%s and c.oid = %u", columns_query, reloid);
else
{
if (escTableName)
! snprintf(columns_query, sizeof(columns_query), "%s and c.relname %s '%s'", columns_query, like_or_eq, escTableName);
schema_strcat1(columns_query, " and n.nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
strcat(columns_query, ") inner join pg_catalog.pg_attribute a"
" on (not a.attisdropped) and a.attnum > 0");
if (search_by_ids)
! snprintf(columns_query, sizeof(columns_query), "%s and a.attnum = %d", columns_query, attnum);
else if (escColumnName)
! snprintf(columns_query, sizeof(columns_query), "%s and a.attname %s '%s'", columns_query, like_or_eq, escColumnName);
strcat(columns_query,
" and a.attrelid = c.oid) inner join pg_catalog.pg_type t"
" on t.oid = a.atttypid) left outer join pg_attrdef d"
--- 1943,1962 ----
" inner join pg_catalog.pg_namespace n on n.oid = c.relnamespace",
sizeof(columns_query));
if (search_by_ids)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and c.oid = %u", reloid);
else
{
if (escTableName)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and c.relname %s '%s'", like_or_eq, escTableName);
schema_strcat1(columns_query, " and n.nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
strcat(columns_query, ") inner join pg_catalog.pg_attribute a"
" on (not a.attisdropped) and a.attnum > 0");
+
if (search_by_ids)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and a.attnum = %d", attnum);
else if (escColumnName)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and a.attname %s '%s'", like_or_eq, escColumnName);
strcat(columns_query,
" and a.attrelid = c.oid) inner join pg_catalog.pg_type t"
" on t.oid = a.atttypid) left outer join pg_attrdef d"
***************
*** 1973,1982 ****
" and a.atttypid = t.oid and (a.attnum > 0)",
PG_VERSION_LE(conn, 6.2) ? "a.attlen" : "a.atttypmod");
if (escTableName)
! snprintf(columns_query, sizeof(columns_query), "%s and c.relname %s '%s'", columns_query, like_or_eq, escTableName);
my_strcat1(columns_query, " and u.usename %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escColumnName)
! snprintf(columns_query, sizeof(columns_query), "%s and a.attname %s '%s'", columns_query, like_or_eq, escColumnName);
strcat(columns_query, " order by c.relname, attnum");
}

--- 1974,1983 ----
" and a.atttypid = t.oid and (a.attnum > 0)",
PG_VERSION_LE(conn, 6.2) ? "a.attlen" : "a.atttypmod");
if (escTableName)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and c.relname %s '%s'", like_or_eq, escTableName);
my_strcat1(columns_query, " and u.usename %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escColumnName)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and a.attname %s '%s'", like_or_eq, escColumnName);
strcat(columns_query, " order by c.relname, attnum");
}

***************
*** 2537,2543 ****
/* TableName cannot contain a string search pattern */
/* my_strcat(columns_query, " and c.relname = '%.*s'", szTableName, cbTableName); */
if (escTableName)
! snprintf(columns_query, sizeof(columns_query), "%s and c.relname = '%s'", columns_query, escTableName);
/* SchemaName cannot contain a string search pattern */
if (conn->schema_support)
schema_strcat(columns_query, " and u.nspname = '%.*s'", escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
--- 2538,2544 ----
/* TableName cannot contain a string search pattern */
/* my_strcat(columns_query, " and c.relname = '%.*s'", szTableName, cbTableName); */
if (escTableName)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and c.relname = '%s'", escTableName);
/* SchemaName cannot contain a string search pattern */
if (conn->schema_support)
schema_strcat(columns_query, " and u.nspname = '%.*s'", escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
***************
*** 3217,3222 ****
--- 3218,3225 ----
char *escSchemaName = NULL, *escTableName = NULL, *escColumnName = NULL;
const char *like_or_eq;
char column_query[INFO_INQUIRY_LEN];
+ int cq_len,cq_size;
+ char *col_query;
BOOL search_pattern;
QResultClass *res;

***************
*** 3245,3259 ****
" table_name, column_name, grantor, grantee,"
" privilege_type as PRIVILEGE, is_grantable from"
" information_schema.column_privileges where true");
if (escSchemaName)
! snprintf(column_query, sizeof(column_query),
! "%s and table_schem = '%s'", column_query, escSchemaName);
if (escTableName)
! snprintf(column_query, sizeof(column_query),
! "%s and table_name = '%s'", column_query, escTableName);
if (escColumnName)
! snprintf(column_query, sizeof(column_query),
! "%s and column_name %s '%s'", column_query, like_or_eq, escColumnName);
if (res = CC_send_query(conn, column_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(res))
{
SC_set_error(stmt, STMT_EXEC_ERROR, "PGAPI_ColumnPrivileges query error", func);
--- 3248,3278 ----
" table_name, column_name, grantor, grantee,"
" privilege_type as PRIVILEGE, is_grantable from"
" information_schema.column_privileges where true");
+ cq_len = strlen(column_query);
+ cq_size = sizeof(column_query);
+ col_query = column_query;
if (escSchemaName)
! {
! col_query += cq_len;
! cq_size -= cq_len;
! cq_len = snprintf_len(col_query, cq_size,
! " and table_schem = '%s'", escSchemaName);
!
! }
if (escTableName)
! {
! col_query += cq_len;
! cq_size -= cq_len;
! cq_len += snprintf_len(col_query, cq_size,
! " and table_name = '%s'", escTableName);
! }
if (escColumnName)
! {
! col_query += cq_len;
! cq_size -= cq_len;
! cq_len += snprintf_len(col_query, cq_size,
! " and column_name %s '%s'", like_or_eq, escColumnName);
! }
if (res = CC_send_query(conn, column_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(res))
{
SC_set_error(stmt, STMT_EXEC_ERROR, "PGAPI_ColumnPrivileges query error", func);
***************
*** 4570,4576 ****
strcat(proc_query, " has_function_privilege(p.oid, 'EXECUTE')");
my_strcat1(proc_query, " and nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escProcName)
! snprintf(proc_query, sizeof(proc_query), "%s and proname %s '%s'", proc_query, like_or_eq, escProcName);
strcat(proc_query, " order by nspname, proname, p.oid, attnum");
}
else
--- 4589,4595 ----
strcat(proc_query, " has_function_privilege(p.oid, 'EXECUTE')");
my_strcat1(proc_query, " and nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escProcName)
! snprintf_add(proc_query, strlen(proc_query), sizeof(proc_query), " and proname %s '%s'", like_or_eq, escProcName);
strcat(proc_query, " order by nspname, proname, p.oid, attnum");
}
else
***************
*** 4580,4586 ****
"(not proretset)");
ret_col = 5;
if (escProcName)
! snprintf(proc_query, sizeof(proc_query), " and proname %s '%s'", proc_query, like_or_eq, escProcName);
strcat(proc_query, " order by proname, proretset");
}
if (tres = CC_send_query(conn, proc_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(tres))
--- 4599,4605 ----
"(not proretset)");
ret_col = 5;
if (escProcName)
! snprintf_add(proc_query, strlen(proc_query), sizeof(proc_query), " and proname %s '%s'", like_or_eq, escProcName);
strcat(proc_query, " order by proname, proretset");
}
if (tres = CC_send_query(conn, proc_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(tres))
***************
*** 5115,5121 ****
schema_strcat1(proc_query, " nspname %s '%.*s' and", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
if (escTableName)
! snprintf(proc_query, sizeof(proc_query), "%s relname %s '%s' and", proc_query, like_or_eq, escTableName);
if (conn->schema_support)
{
strcat(proc_query, " pg_namespace.oid = relnamespace and relkind in ('r', 'v') and");
--- 5134,5140 ----
schema_strcat1(proc_query, " nspname %s '%.*s' and", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
if (escTableName)
! snprintf_add(proc_query, strlen(proc_query), sizeof(proc_query), " relname %s '%s' and", like_or_eq, escTableName);
if (conn->schema_support)
{
strcat(proc_query, " pg_namespace.oid = relnamespace and relkind in ('r', 'v') and");
diff -c psqlodbc.orig/misc.c psqlodbc/misc.c
*** psqlodbc.orig/misc.c 2006-06-06 10:37:01.556841000 +0200
--- psqlodbc/misc.c 2006-06-09 14:01:29.639448842 +0200
***************
*** 291,293 ****
--- 291,328 ----
}
return my_strcat1(buf, fmt, s1, s, len);
}
+
+ /*
+ * snprintf_add is a extension to snprintf
+ * It add format to buf at given pos
+ */
+
+ int
+ snprintf_add(char *buf, size_t pos, size_t size, const char *format, ...)
+ {
+ int len;
+ va_list arglist;
+
+ va_start(arglist, format);
+ len = vsnprintf(buf + pos, size - pos, format, arglist);
+ va_end(arglist);
+ return len;
+ }
+
+ /*
+ * snprintf_addlen is a extension to snprintf
+ * It returns strlen of buf every time (not -1 when truncated)
+ */
+
+ int
+ snprintf_len(char *buf, size_t size, const char *format, ...)
+ {
+ int len;
+ va_list arglist;
+
+ va_start(arglist, format);
+ if ((len = vsnprintf(buf, size, format, arglist)) < 0)
+ len = size;
+ va_end(arglist);
+ return len;
+ }
diff -c psqlodbc.orig/misc.h psqlodbc/misc.h
*** psqlodbc.orig/misc.h 2006-06-06 10:37:01.559842000 +0200
--- psqlodbc/misc.h 2006-06-09 14:00:31.310947620 +0200
***************
*** 132,137 ****
--- 132,139 ----
char *schema_strcat1(char *buf, const char *fmt, const char *s1,
const char *s, int len,
const char *, int, ConnectionClass *conn);
+ int snprintf_add(char *buf, size_t pos, size_t size, const char *format, ...);
+ int snprintf_len(char *buf, size_t size, const char *format, ...);
/* #define GET_SCHEMA_NAME(nspname) (stricmp(nspname, "public") ? nspname : "") */
#define GET_SCHEMA_NAME(nspname) (nspname)

diff -c psqlodbc.orig/psqlodbc.h psqlodbc/psqlodbc.h
*** psqlodbc.orig/psqlodbc.h 2006-06-06 10:37:06.254090000 +0200
--- psqlodbc/psqlodbc.h 2006-06-09 13:53:42.085192915 +0200
***************
*** 110,115 ****
--- 110,116 ----
#define strnicmp _strnicmp
#define stricmp _stricmp
#define strdup _strdup
+ #define vsnprintf _vsnprintf
#endif

#ifndef SQL_ATTR_APP_ROW_DESC

--huq684BweRXVnRxX
Content-Type: text/plain
Content-Disposition: inline
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable


---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend

--huq684BweRXVnRxX--

Re: Patch for snprintf problem (bug #1000650)

am 09.06.2006 14:42:43 von Ludek Finstrle

--DocE+STaALJfprDB
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Fri, Jun 09, 2006 at 02:13:23PM +0200, Ludek Finstrle napsal(a):
> > > > buf = "text";
> > > > snprintf(buf,size,"%s append",buf);
> > > >
> > > > buf = "text append" on Windows (MS VC compiler)
> > > > buf = " append" on linux (gcc compiler)
> > > >
> > > > I solve it this way (main idea):
> > > > snprintf(buf + strlen(buf), " append");
> > >
> > > Hmm bad news.
> > > If so, it may be better to use the sequence like the following for example.
> > >
> > > char *query_ptr;
> > > size_t bufsize_res;
> > > int slen;
> > >
> > > /* Initialize */
> > > query_ptr = columns_query;
> > > bufsize_res = sizeof(columns_query);
> > >
> > > if (..)
> > > {
> > > if ((slen = snprintf(query_ptr, bufsize_res, .., )) <= 0)
> > > {
> > > .. error_handling ..
> > > }
> > > query_ptr += slen;
> > > bufsize_res -= slen;
> > > }
> > >
> > > ...
> >
> > I'm not sure. There are a lot of strcat, my_strcat, schema_strcat calls
> > between snprintf. There is only one place where snprintf could be called
> > after another snprintf.
>
> I change the snprintf_addlen to snprintf_len as you mentioned.

I take a look at all snprintf in psqlodbc an I find one more place
where it's problematic.
If we accept snprintf_add I change one call to it.

Additional patch attached, comments are welcome

Luf

--DocE+STaALJfprDB
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="psqlodbc_snprintf_next.diff"

diff -c psqlodbc.orig/connection.c psqlodbc/connection.c
*** psqlodbc.orig/connection.c 2006-06-06 10:36:53.756768000 +0200
--- psqlodbc/connection.c 2006-06-09 14:35:00.594874796 +0200
***************
*** 2320,2326 ****
{
if (CC_is_in_error_trans(self))
snprintf(cmd, sizeof(cmd), "ROLLBACK TO %s;", per_query_svp);
! snprintf(cmd, sizeof(cmd), "%sRELEASE %s", cmd, per_query_svp);
}
else if (CC_is_in_error_trans(self))
strcpy(cmd, "ROLLBACK");
--- 2320,2326 ----
{
if (CC_is_in_error_trans(self))
snprintf(cmd, sizeof(cmd), "ROLLBACK TO %s;", per_query_svp);
! snprintf_add(cmd, strlen(cmd), sizeof(cmd), "RELEASE %s", per_query_svp);
}
else if (CC_is_in_error_trans(self))
strcpy(cmd, "ROLLBACK");
diff -c psqlodbc.orig/results.c psqlodbc/results.c
*** psqlodbc.orig/results.c 2006-06-06 10:37:10.131120000 +0200
--- psqlodbc/results.c 2006-06-09 14:36:52.875714241 +0200
***************
*** 2977,2984 ****
Int4 slen;
/*snprintf(selstr, len, "%s where \"%s\" = %u", stmt->load_statement, bestitem, *oid);*/
snprintf(selstr, len, "%s where ", stmt->load_statement);
! slen = strlen(selstr);
! snprintf(selstr + slen, len - slen, bestqual, *oidint);
}
else
{
--- 2977,2983 ----
Int4 slen;
/*snprintf(selstr, len, "%s where \"%s\" = %u", stmt->load_statement, bestitem, *oid);*/
snprintf(selstr, len, "%s where ", stmt->load_statement);
! snprintf_add(selstr, strlen(selstr), len, bestqual, *oidint);
}
else
{

--DocE+STaALJfprDB
Content-Type: text/plain
Content-Disposition: inline
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable


---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings

--DocE+STaALJfprDB--

Re: Patch for snprintf problem (bug #1000650) 4-th try

am 13.06.2006 11:46:17 von Ludek Finstrle

--qDbXVdCdHGoSgWSk
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

> > > > buf = "text";
> > > > snprintf(buf,size,"%s append",buf);
> > > >
> > > > buf = "text append" on Windows (MS VC compiler)
> > > > buf = " append" on linux (gcc compiler)
> > > >
> > > > I solve it this way (main idea):
> > > > snprintf(buf + strlen(buf), " append");
> > >
> > > Hmm bad news.
> > > If so, it may be better to use the sequence like the following for example.
> > >
> > > char *query_ptr;
> > > size_t bufsize_res;
> > > int slen;
> > >
> > > /* Initialize */
> > > query_ptr = columns_query;
> > > bufsize_res = sizeof(columns_query);
> > >
> > > if (..)
> > > {
> > > if ((slen = snprintf(query_ptr, bufsize_res, .., )) <= 0)
> > > {
> > > .. error_handling ..
> > > }
> > > query_ptr += slen;
> > > bufsize_res -= slen;
> > > }
> > >
> > > ...
> >
> > I'm not sure. There are a lot of strcat, my_strcat, schema_strcat calls
> > between snprintf. There is only one place where snprintf could be called
> > after another snprintf.
>
> I change the snprintf_addlen to snprintf_len as you mentioned.
>
> Third try of patch attached.

I make patch againist CVS after yours huge commit. What's your opinion?
Could we fix linux bug? Or do you prefer ifdef or what's your
idea about change these lines:

snprintf(buf,bufsize,"%s adding 1",buf);
strcat(buf," adding 2");
snprintf(buf,bufsize,"%s adding 3",buf);

I think it's hard to maintain code you mentioned above. This calls
are only in catalog information (relatively short query - used not so
often).

Patch attached contains previous psqlodbc_snprintf_3try and
psqlodbc_snprintf_next.

Regards,

Luf

--qDbXVdCdHGoSgWSk
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="psqlodbc_snprintf_4try.diff"

diff -c psqlodbc.orig/connection.c psqlodbc.snprintf/connection.c
*** psqlodbc.orig/connection.c 2006-06-13 11:26:23.073862179 +0200
--- psqlodbc.snprintf/connection.c 2006-06-13 11:34:19.905583659 +0200
***************
*** 2318,2324 ****
{
if (CC_is_in_error_trans(self))
snprintf(cmd, sizeof(cmd), "ROLLBACK TO %s;", per_query_svp);
! snprintf(cmd, sizeof(cmd), "%sRELEASE %s", cmd, per_query_svp);
}
else if (CC_is_in_error_trans(self))
strcpy(cmd, "ROLLBACK");
--- 2318,2324 ----
{
if (CC_is_in_error_trans(self))
snprintf(cmd, sizeof(cmd), "ROLLBACK TO %s;", per_query_svp);
! snprintf_add(cmd, strlen(cmd), sizeof(cmd), "RELEASE %s", per_query_svp);
}
else if (CC_is_in_error_trans(self))
strcpy(cmd, "ROLLBACK");
diff -c psqlodbc.orig/info.c psqlodbc.snprintf/info.c
*** psqlodbc.orig/info.c 2006-06-13 11:26:23.482970903 +0200
--- psqlodbc.snprintf/info.c 2006-06-13 11:36:14.388008192 +0200
***************
*** 1955,1965 ****
" inner join pg_catalog.pg_namespace n on n.oid = c.relnamespace",
sizeof(columns_query));
if (search_by_ids)
! snprintf(columns_query, sizeof(columns_query), "%s and c.oid = %u", columns_query, reloid);
else
{
if (escTableName)
! snprintf(columns_query, sizeof(columns_query), "%s and c.relname %s '%s'", columns_query, like_or_eq, escTableName);
schema_strcat1(columns_query, " and n.nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
strcat(columns_query, ") inner join pg_catalog.pg_attribute a"
--- 1955,1965 ----
" inner join pg_catalog.pg_namespace n on n.oid = c.relnamespace",
sizeof(columns_query));
if (search_by_ids)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and c.oid = %u", reloid);
else
{
if (escTableName)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and c.relname %s '%s'", like_or_eq, escTableName);
schema_strcat1(columns_query, " and n.nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
strcat(columns_query, ") inner join pg_catalog.pg_attribute a"
***************
*** 1969,1978 ****
if (search_by_ids)
{
if (attnum != 0)
! snprintf(columns_query, sizeof(columns_query), "%s and a.attnum = %d", columns_query, attnum);
}
else if (escColumnName)
! snprintf(columns_query, sizeof(columns_query), "%s and a.attname %s '%s'", columns_query, like_or_eq, escColumnName);
strcat(columns_query,
" and a.attrelid = c.oid) inner join pg_catalog.pg_type t"
" on t.oid = a.atttypid) left outer join pg_attrdef d"
--- 1969,1978 ----
if (search_by_ids)
{
if (attnum != 0)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and a.attnum = %d", attnum);
}
else if (escColumnName)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and a.attname %s '%s'", like_or_eq, escColumnName);
strcat(columns_query,
" and a.attrelid = c.oid) inner join pg_catalog.pg_type t"
" on t.oid = a.atttypid) left outer join pg_attrdef d"
***************
*** 1990,1999 ****
" and a.atttypid = t.oid and (a.attnum > 0)",
PG_VERSION_LE(conn, 6.2) ? "a.attlen" : "a.atttypmod");
if (escTableName)
! snprintf(columns_query, sizeof(columns_query), "%s and c.relname %s '%s'", columns_query, like_or_eq, escTableName);
my_strcat1(columns_query, " and u.usename %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escColumnName)
! snprintf(columns_query, sizeof(columns_query), "%s and a.attname %s '%s'", columns_query, like_or_eq, escColumnName);
strcat(columns_query, " order by c.relname, attnum");
}

--- 1990,1999 ----
" and a.atttypid = t.oid and (a.attnum > 0)",
PG_VERSION_LE(conn, 6.2) ? "a.attlen" : "a.atttypmod");
if (escTableName)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and c.relname %s '%s'", like_or_eq, escTableName);
my_strcat1(columns_query, " and u.usename %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escColumnName)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and a.attname %s '%s'", like_or_eq, escColumnName);
strcat(columns_query, " order by c.relname, attnum");
}

***************
*** 2566,2572 ****
/* TableName cannot contain a string search pattern */
/* my_strcat(columns_query, " and c.relname = '%.*s'", szTableName, cbTableName); */
if (escTableName)
! snprintf(columns_query, sizeof(columns_query), "%s and c.relname = '%s'", columns_query, escTableName);
/* SchemaName cannot contain a string search pattern */
if (conn->schema_support)
schema_strcat(columns_query, " and u.nspname = '%.*s'", escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
--- 2566,2572 ----
/* TableName cannot contain a string search pattern */
/* my_strcat(columns_query, " and c.relname = '%.*s'", szTableName, cbTableName); */
if (escTableName)
! snprintf_add(columns_query, strlen(columns_query), sizeof(columns_query), " and c.relname = '%s'", escTableName);
/* SchemaName cannot contain a string search pattern */
if (conn->schema_support)
schema_strcat(columns_query, " and u.nspname = '%.*s'", escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
***************
*** 3246,3251 ****
--- 3246,3253 ----
char *escSchemaName = NULL, *escTableName = NULL, *escColumnName = NULL;
const char *like_or_eq;
char column_query[INFO_INQUIRY_LEN];
+ int cq_len,cq_size;
+ char *col_query;
BOOL search_pattern;
QResultClass *res;

***************
*** 3274,3288 ****
" table_name, column_name, grantor, grantee,"
" privilege_type as PRIVILEGE, is_grantable from"
" information_schema.column_privileges where true");
if (escSchemaName)
! snprintf(column_query, sizeof(column_query),
! "%s and table_schem = '%s'", column_query, escSchemaName);
if (escTableName)
! snprintf(column_query, sizeof(column_query),
! "%s and table_name = '%s'", column_query, escTableName);
if (escColumnName)
! snprintf(column_query, sizeof(column_query),
! "%s and column_name %s '%s'", column_query, like_or_eq, escColumnName);
if (res = CC_send_query(conn, column_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(res))
{
SC_set_error(stmt, STMT_EXEC_ERROR, "PGAPI_ColumnPrivileges query error", func);
--- 3276,3306 ----
" table_name, column_name, grantor, grantee,"
" privilege_type as PRIVILEGE, is_grantable from"
" information_schema.column_privileges where true");
+ cq_len = strlen(column_query);
+ cq_size = sizeof(column_query);
+ col_query = column_query;
if (escSchemaName)
! {
! col_query += cq_len;
! cq_size -= cq_len;
! cq_len = snprintf_len(col_query, cq_size,
! " and table_schem = '%s'", escSchemaName);
!
! }
if (escTableName)
! {
! col_query += cq_len;
! cq_size -= cq_len;
! cq_len += snprintf_len(col_query, cq_size,
! " and table_name = '%s'", escTableName);
! }
if (escColumnName)
! {
! col_query += cq_len;
! cq_size -= cq_len;
! cq_len += snprintf_len(col_query, cq_size,
! " and column_name %s '%s'", like_or_eq, escColumnName);
! }
if (res = CC_send_query(conn, column_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(res))
{
SC_set_error(stmt, STMT_EXEC_ERROR, "PGAPI_ColumnPrivileges query error", func);
***************
*** 4599,4605 ****
strcat(proc_query, " has_function_privilege(p.oid, 'EXECUTE')");
my_strcat1(proc_query, " and nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escProcName)
! snprintf(proc_query, sizeof(proc_query), "%s and proname %s '%s'", proc_query, like_or_eq, escProcName);
strcat(proc_query, " order by nspname, proname, p.oid, attnum");
}
else
--- 4617,4623 ----
strcat(proc_query, " has_function_privilege(p.oid, 'EXECUTE')");
my_strcat1(proc_query, " and nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escProcName)
! snprintf_add(proc_query, strlen(proc_query), sizeof(proc_query), " and proname %s '%s'", like_or_eq, escProcName);
strcat(proc_query, " order by nspname, proname, p.oid, attnum");
}
else
***************
*** 4609,4615 ****
"(not proretset)");
ret_col = 5;
if (escProcName)
! snprintf(proc_query, sizeof(proc_query), " and proname %s '%s'", proc_query, like_or_eq, escProcName);
strcat(proc_query, " order by proname, proretset");
}
if (tres = CC_send_query(conn, proc_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(tres))
--- 4627,4633 ----
"(not proretset)");
ret_col = 5;
if (escProcName)
! snprintf_add(proc_query, strlen(proc_query), sizeof(proc_query), " and proname %s '%s'", like_or_eq, escProcName);
strcat(proc_query, " order by proname, proretset");
}
if (tres = CC_send_query(conn, proc_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(tres))
***************
*** 5144,5150 ****
schema_strcat1(proc_query, " nspname %s '%.*s' and", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
if (escTableName)
! snprintf(proc_query, sizeof(proc_query), "%s relname %s '%s' and", proc_query, like_or_eq, escTableName);
if (conn->schema_support)
{
strcat(proc_query, " pg_namespace.oid = relnamespace and relkind in ('r', 'v') and");
--- 5162,5168 ----
schema_strcat1(proc_query, " nspname %s '%.*s' and", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
if (escTableName)
! snprintf_add(proc_query, strlen(proc_query), sizeof(proc_query), " relname %s '%s' and", like_or_eq, escTableName);
if (conn->schema_support)
{
strcat(proc_query, " pg_namespace.oid = relnamespace and relkind in ('r', 'v') and");
diff -c psqlodbc.orig/misc.c psqlodbc.snprintf/misc.c
*** psqlodbc.orig/misc.c 2006-06-06 10:37:01.556841000 +0200
--- psqlodbc.snprintf/misc.c 2006-06-13 11:28:25.974523919 +0200
***************
*** 291,293 ****
--- 291,328 ----
}
return my_strcat1(buf, fmt, s1, s, len);
}
+
+ /*
+ * snprintf_add is a extension to snprintf
+ * It add format to buf at given pos
+ */
+
+ int
+ snprintf_add(char *buf, size_t pos, size_t size, const char *format, ...)
+ {
+ int len;
+ va_list arglist;
+
+ va_start(arglist, format);
+ len = vsnprintf(buf + pos, size - pos, format, arglist);
+ va_end(arglist);
+ return len;
+ }
+
+ /*
+ * snprintf_addlen is a extension to snprintf
+ * It returns strlen of buf every time (not -1 when truncated)
+ */
+
+ int
+ snprintf_len(char *buf, size_t size, const char *format, ...)
+ {
+ int len;
+ va_list arglist;
+
+ va_start(arglist, format);
+ if ((len = vsnprintf(buf, size, format, arglist)) < 0)
+ len = size;
+ va_end(arglist);
+ return len;
+ }
diff -c psqlodbc.orig/misc.h psqlodbc.snprintf/misc.h
*** psqlodbc.orig/misc.h 2006-06-06 10:37:01.559842000 +0200
--- psqlodbc.snprintf/misc.h 2006-06-13 11:28:25.975524185 +0200
***************
*** 132,137 ****
--- 132,139 ----
char *schema_strcat1(char *buf, const char *fmt, const char *s1,
const char *s, int len,
const char *, int, ConnectionClass *conn);
+ int snprintf_add(char *buf, size_t pos, size_t size, const char *format, ...);
+ int snprintf_len(char *buf, size_t size, const char *format, ...);
/* #define GET_SCHEMA_NAME(nspname) (stricmp(nspname, "public") ? nspname : "") */
#define GET_SCHEMA_NAME(nspname) (nspname)

diff -c psqlodbc.orig/psqlodbc.h psqlodbc.snprintf/psqlodbc.h
*** psqlodbc.orig/psqlodbc.h 2006-06-13 11:26:25.151414304 +0200
--- psqlodbc.snprintf/psqlodbc.h 2006-06-13 11:29:26.345567961 +0200
***************
*** 109,114 ****
--- 109,115 ----
#define strdup _strdup
#define strnicmp _strnicmp
#define stricmp _stricmp
+ #define vsnprintf _vsnprintf
#endif

#ifndef SQL_ATTR_APP_ROW_DESC
diff -c psqlodbc.orig/results.c psqlodbc.snprintf/results.c
*** psqlodbc.orig/results.c 2006-06-13 11:26:25.344465609 +0200
--- psqlodbc.snprintf/results.c 2006-06-13 11:37:55.312829693 +0200
***************
*** 3022,3032 ****
snprintf(selstr, len, "%s where ctid = currtid(0, '(,)') %s", stmt->load_statement, oideqstr);
else if (bestitem && oidint)
{
- Int4 slen;
/*snprintf(selstr, len, "%s where \"%s\" = %u", stmt->load_statement, bestitem, *oid);*/
snprintf(selstr, len, "%s where ", stmt->load_statement);
! slen = strlen(selstr);
! snprintf(selstr + slen, len - slen, bestqual, *oidint);
}
else
{
--- 3022,3030 ----
snprintf(selstr, len, "%s where ctid = currtid(0, '(,)') %s", stmt->load_statement, oideqstr);
else if (bestitem && oidint)
{
/*snprintf(selstr, len, "%s where \"%s\" = %u", stmt->load_statement, bestitem, *oid);*/
snprintf(selstr, len, "%s where ", stmt->load_statement);
! snprintf_add(selstr, strlen(selstr), len, bestqual, *oidint);
}
else
{

--qDbXVdCdHGoSgWSk
Content-Type: text/plain
Content-Disposition: inline
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable


---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?

http://archives.postgresql.org

--qDbXVdCdHGoSgWSk--

Re: Patch for snprintf problem (bug #1000650) 4-th try

am 13.06.2006 16:12:58 von Hiroshi Inoue

Ludek Finstrle wrote:
>
> I make patch againist CVS after yours huge commit. What's your opinion?
>

Is the second parameter of snprintf_add needed ?
Aren't the parameter values always strlen(the first parameter) ?

Is snprintf_len needed instead of snprintf ?
Though the current code ignores snprintf errors, it's simply
my negligence..

regards,
Hiroshi Inoue

---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?

http://www.postgresql.org/docs/faq

Re: Patch for snprintf problem (bug #1000650) 5-th try

am 14.06.2006 09:50:54 von Ludek Finstrle

--bp/iNruPH9dso1Pn
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Tue, Jun 13, 2006 at 11:12:58PM +0900, Hiroshi Inoue wrote:
> Ludek Finstrle wrote:
> >
> > I make patch againist CVS after yours huge commit. What's your opinion?
> >
>
> Is the second parameter of snprintf_add needed ?
> Aren't the parameter values always strlen(the first parameter) ?

You're right. I think more about it and "add" means add to the end
so I changed the patch as you pointed.

> Is snprintf_len needed instead of snprintf ?
> Though the current code ignores snprintf errors, it's simply
> my negligence..

I'm voting for keeping safer snprintf_len. But I can change it if
you wish.

New patch attached.

Regards,

Luf

--bp/iNruPH9dso1Pn
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="psqlodbc_snprintf_5try.diff"

diff -c psqlodbc.orig/connection.c psqlodbc.snprintf/connection.c
*** psqlodbc.orig/connection.c 2006-06-13 11:26:23.073862179 +0200
--- psqlodbc.snprintf/connection.c 2006-06-14 09:39:07.792064600 +0200
***************
*** 2318,2324 ****
{
if (CC_is_in_error_trans(self))
snprintf(cmd, sizeof(cmd), "ROLLBACK TO %s;", per_query_svp);
! snprintf(cmd, sizeof(cmd), "%sRELEASE %s", cmd, per_query_svp);
}
else if (CC_is_in_error_trans(self))
strcpy(cmd, "ROLLBACK");
--- 2318,2324 ----
{
if (CC_is_in_error_trans(self))
snprintf(cmd, sizeof(cmd), "ROLLBACK TO %s;", per_query_svp);
! snprintf_add(cmd, sizeof(cmd), "RELEASE %s", per_query_svp);
}
else if (CC_is_in_error_trans(self))
strcpy(cmd, "ROLLBACK");
diff -c psqlodbc.orig/info.c psqlodbc.snprintf/info.c
*** psqlodbc.orig/info.c 2006-06-13 11:26:23.482970903 +0200
--- psqlodbc.snprintf/info.c 2006-06-14 09:37:08.789438792 +0200
***************
*** 1955,1965 ****
" inner join pg_catalog.pg_namespace n on n.oid = c.relnamespace",
sizeof(columns_query));
if (search_by_ids)
! snprintf(columns_query, sizeof(columns_query), "%s and c.oid = %u", columns_query, reloid);
else
{
if (escTableName)
! snprintf(columns_query, sizeof(columns_query), "%s and c.relname %s '%s'", columns_query, like_or_eq, escTableName);
schema_strcat1(columns_query, " and n.nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
strcat(columns_query, ") inner join pg_catalog.pg_attribute a"
--- 1955,1965 ----
" inner join pg_catalog.pg_namespace n on n.oid = c.relnamespace",
sizeof(columns_query));
if (search_by_ids)
! snprintf_add(columns_query, sizeof(columns_query), " and c.oid = %u", reloid);
else
{
if (escTableName)
! snprintf_add(columns_query, sizeof(columns_query), " and c.relname %s '%s'", like_or_eq, escTableName);
schema_strcat1(columns_query, " and n.nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
strcat(columns_query, ") inner join pg_catalog.pg_attribute a"
***************
*** 1969,1978 ****
if (search_by_ids)
{
if (attnum != 0)
! snprintf(columns_query, sizeof(columns_query), "%s and a.attnum = %d", columns_query, attnum);
}
else if (escColumnName)
! snprintf(columns_query, sizeof(columns_query), "%s and a.attname %s '%s'", columns_query, like_or_eq, escColumnName);
strcat(columns_query,
" and a.attrelid = c.oid) inner join pg_catalog.pg_type t"
" on t.oid = a.atttypid) left outer join pg_attrdef d"
--- 1969,1978 ----
if (search_by_ids)
{
if (attnum != 0)
! snprintf_add(columns_query, sizeof(columns_query), " and a.attnum = %d", attnum);
}
else if (escColumnName)
! snprintf_add(columns_query, sizeof(columns_query), " and a.attname %s '%s'", like_or_eq, escColumnName);
strcat(columns_query,
" and a.attrelid = c.oid) inner join pg_catalog.pg_type t"
" on t.oid = a.atttypid) left outer join pg_attrdef d"
***************
*** 1990,1999 ****
" and a.atttypid = t.oid and (a.attnum > 0)",
PG_VERSION_LE(conn, 6.2) ? "a.attlen" : "a.atttypmod");
if (escTableName)
! snprintf(columns_query, sizeof(columns_query), "%s and c.relname %s '%s'", columns_query, like_or_eq, escTableName);
my_strcat1(columns_query, " and u.usename %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escColumnName)
! snprintf(columns_query, sizeof(columns_query), "%s and a.attname %s '%s'", columns_query, like_or_eq, escColumnName);
strcat(columns_query, " order by c.relname, attnum");
}

--- 1990,1999 ----
" and a.atttypid = t.oid and (a.attnum > 0)",
PG_VERSION_LE(conn, 6.2) ? "a.attlen" : "a.atttypmod");
if (escTableName)
! snprintf_add(columns_query, sizeof(columns_query), " and c.relname %s '%s'", like_or_eq, escTableName);
my_strcat1(columns_query, " and u.usename %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escColumnName)
! snprintf_add(columns_query, sizeof(columns_query), " and a.attname %s '%s'", like_or_eq, escColumnName);
strcat(columns_query, " order by c.relname, attnum");
}

***************
*** 2566,2572 ****
/* TableName cannot contain a string search pattern */
/* my_strcat(columns_query, " and c.relname = '%.*s'", szTableName, cbTableName); */
if (escTableName)
! snprintf(columns_query, sizeof(columns_query), "%s and c.relname = '%s'", columns_query, escTableName);
/* SchemaName cannot contain a string search pattern */
if (conn->schema_support)
schema_strcat(columns_query, " and u.nspname = '%.*s'", escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
--- 2566,2572 ----
/* TableName cannot contain a string search pattern */
/* my_strcat(columns_query, " and c.relname = '%.*s'", szTableName, cbTableName); */
if (escTableName)
! snprintf_add(columns_query, sizeof(columns_query), " and c.relname = '%s'", escTableName);
/* SchemaName cannot contain a string search pattern */
if (conn->schema_support)
schema_strcat(columns_query, " and u.nspname = '%.*s'", escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
***************
*** 3246,3251 ****
--- 3246,3253 ----
char *escSchemaName = NULL, *escTableName = NULL, *escColumnName = NULL;
const char *like_or_eq;
char column_query[INFO_INQUIRY_LEN];
+ int cq_len,cq_size;
+ char *col_query;
BOOL search_pattern;
QResultClass *res;

***************
*** 3274,3288 ****
" table_name, column_name, grantor, grantee,"
" privilege_type as PRIVILEGE, is_grantable from"
" information_schema.column_privileges where true");
if (escSchemaName)
! snprintf(column_query, sizeof(column_query),
! "%s and table_schem = '%s'", column_query, escSchemaName);
if (escTableName)
! snprintf(column_query, sizeof(column_query),
! "%s and table_name = '%s'", column_query, escTableName);
if (escColumnName)
! snprintf(column_query, sizeof(column_query),
! "%s and column_name %s '%s'", column_query, like_or_eq, escColumnName);
if (res = CC_send_query(conn, column_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(res))
{
SC_set_error(stmt, STMT_EXEC_ERROR, "PGAPI_ColumnPrivileges query error", func);
--- 3276,3306 ----
" table_name, column_name, grantor, grantee,"
" privilege_type as PRIVILEGE, is_grantable from"
" information_schema.column_privileges where true");
+ cq_len = strlen(column_query);
+ cq_size = sizeof(column_query);
+ col_query = column_query;
if (escSchemaName)
! {
! col_query += cq_len;
! cq_size -= cq_len;
! cq_len = snprintf_len(col_query, cq_size,
! " and table_schem = '%s'", escSchemaName);
!
! }
if (escTableName)
! {
! col_query += cq_len;
! cq_size -= cq_len;
! cq_len += snprintf_len(col_query, cq_size,
! " and table_name = '%s'", escTableName);
! }
if (escColumnName)
! {
! col_query += cq_len;
! cq_size -= cq_len;
! cq_len += snprintf_len(col_query, cq_size,
! " and column_name %s '%s'", like_or_eq, escColumnName);
! }
if (res = CC_send_query(conn, column_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(res))
{
SC_set_error(stmt, STMT_EXEC_ERROR, "PGAPI_ColumnPrivileges query error", func);
***************
*** 4599,4605 ****
strcat(proc_query, " has_function_privilege(p.oid, 'EXECUTE')");
my_strcat1(proc_query, " and nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escProcName)
! snprintf(proc_query, sizeof(proc_query), "%s and proname %s '%s'", proc_query, like_or_eq, escProcName);
strcat(proc_query, " order by nspname, proname, p.oid, attnum");
}
else
--- 4617,4623 ----
strcat(proc_query, " has_function_privilege(p.oid, 'EXECUTE')");
my_strcat1(proc_query, " and nspname %s '%.*s'", like_or_eq, escSchemaName, SQL_NTS);
if (escProcName)
! snprintf_add(proc_query, sizeof(proc_query), " and proname %s '%s'", like_or_eq, escProcName);
strcat(proc_query, " order by nspname, proname, p.oid, attnum");
}
else
***************
*** 4609,4615 ****
"(not proretset)");
ret_col = 5;
if (escProcName)
! snprintf(proc_query, sizeof(proc_query), " and proname %s '%s'", proc_query, like_or_eq, escProcName);
strcat(proc_query, " order by proname, proretset");
}
if (tres = CC_send_query(conn, proc_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(tres))
--- 4627,4633 ----
"(not proretset)");
ret_col = 5;
if (escProcName)
! snprintf_add(proc_query, sizeof(proc_query), " and proname %s '%s'", like_or_eq, escProcName);
strcat(proc_query, " order by proname, proretset");
}
if (tres = CC_send_query(conn, proc_query, NULL, IGNORE_ABORT_ON_CONN, stmt), !QR_command_maybe_successful(tres))
***************
*** 5144,5150 ****
schema_strcat1(proc_query, " nspname %s '%.*s' and", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
if (escTableName)
! snprintf(proc_query, sizeof(proc_query), "%s relname %s '%s' and", proc_query, like_or_eq, escTableName);
if (conn->schema_support)
{
strcat(proc_query, " pg_namespace.oid = relnamespace and relkind in ('r', 'v') and");
--- 5162,5168 ----
schema_strcat1(proc_query, " nspname %s '%.*s' and", like_or_eq, escSchemaName, SQL_NTS, szTableName, cbTableName, conn);
}
if (escTableName)
! snprintf_add(proc_query, sizeof(proc_query), " relname %s '%s' and", like_or_eq, escTableName);
if (conn->schema_support)
{
strcat(proc_query, " pg_namespace.oid = relnamespace and relkind in ('r', 'v') and");
diff -c psqlodbc.orig/misc.c psqlodbc.snprintf/misc.c
*** psqlodbc.orig/misc.c 2006-06-06 10:37:01.556841000 +0200
--- psqlodbc.snprintf/misc.c 2006-06-14 09:34:22.160155854 +0200
***************
*** 291,293 ****
--- 291,329 ----
}
return my_strcat1(buf, fmt, s1, s, len);
}
+
+ /*
+ * snprintf_add is a extension to snprintf
+ * It add format to buf at given pos
+ */
+
+ int
+ snprintf_add(char *buf, size_t size, const char *format, ...)
+ {
+ int len;
+ size_t pos = strlen(buf);
+ va_list arglist;
+
+ va_start(arglist, format);
+ len = vsnprintf(buf + pos, size - pos, format, arglist);
+ va_end(arglist);
+ return len;
+ }
+
+ /*
+ * snprintf_addlen is a extension to snprintf
+ * It returns strlen of buf every time (not -1 when truncated)
+ */
+
+ int
+ snprintf_len(char *buf, size_t size, const char *format, ...)
+ {
+ int len;
+ va_list arglist;
+
+ va_start(arglist, format);
+ if ((len = vsnprintf(buf, size, format, arglist)) < 0)
+ len = size;
+ va_end(arglist);
+ return len;
+ }
diff -c psqlodbc.orig/misc.h psqlodbc.snprintf/misc.h
*** psqlodbc.orig/misc.h 2006-06-06 10:37:01.559842000 +0200
--- psqlodbc.snprintf/misc.h 2006-06-14 09:34:33.013040087 +0200
***************
*** 132,137 ****
--- 132,139 ----
char *schema_strcat1(char *buf, const char *fmt, const char *s1,
const char *s, int len,
const char *, int, ConnectionClass *conn);
+ int snprintf_add(char *buf, size_t size, const char *format, ...);
+ int snprintf_len(char *buf, size_t size, const char *format, ...);
/* #define GET_SCHEMA_NAME(nspname) (stricmp(nspname, "public") ? nspname : "") */
#define GET_SCHEMA_NAME(nspname) (nspname)

diff -c psqlodbc.orig/psqlodbc.h psqlodbc.snprintf/psqlodbc.h
*** psqlodbc.orig/psqlodbc.h 2006-06-13 11:26:25.151414304 +0200
--- psqlodbc.snprintf/psqlodbc.h 2006-06-13 11:29:26.345567961 +0200
***************
*** 109,114 ****
--- 109,115 ----
#define strdup _strdup
#define strnicmp _strnicmp
#define stricmp _stricmp
+ #define vsnprintf _vsnprintf
#endif

#ifndef SQL_ATTR_APP_ROW_DESC
diff -c psqlodbc.orig/results.c psqlodbc.snprintf/results.c
*** psqlodbc.orig/results.c 2006-06-13 11:26:25.344465609 +0200
--- psqlodbc.snprintf/results.c 2006-06-14 09:37:30.865305613 +0200
***************
*** 3022,3032 ****
snprintf(selstr, len, "%s where ctid = currtid(0, '(,)') %s", stmt->load_statement, oideqstr);
else if (bestitem && oidint)
{
- Int4 slen;
/*snprintf(selstr, len, "%s where \"%s\" = %u", stmt->load_statement, bestitem, *oid);*/
snprintf(selstr, len, "%s where ", stmt->load_statement);
! slen = strlen(selstr);
! snprintf(selstr + slen, len - slen, bestqual, *oidint);
}
else
{
--- 3022,3030 ----
snprintf(selstr, len, "%s where ctid = currtid(0, '(,)') %s", stmt->load_statement, oideqstr);
else if (bestitem && oidint)
{
/*snprintf(selstr, len, "%s where \"%s\" = %u", stmt->load_statement, bestitem, *oid);*/
snprintf(selstr, len, "%s where ", stmt->load_statement);
! snprintf_add(selstr, len, bestqual, *oidint);
}
else
{

--bp/iNruPH9dso1Pn
Content-Type: text/plain
Content-Disposition: inline
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable


---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match

--bp/iNruPH9dso1Pn--

Re: Patch for snprintf problem (bug #1000650) 5-th try

am 14.06.2006 23:28:59 von Hiroshi Inoue

Ludek Finstrle wrote:
> Tue, Jun 13, 2006 at 11:12:58PM +0900, Hiroshi Inoue wrote:
>
>> Ludek Finstrle wrote:
>>
>>> I make patch againist CVS after yours huge commit. What's your opinion?
>>>
>>>
>> Is the second parameter of snprintf_add needed ?
>> Aren't the parameter values always strlen(the first parameter) ?
>>
>
> You're right. I think more about it and "add" means add to the end
> so I changed the patch as you pointed.
>
>
>> Is snprintf_len needed instead of snprintf ?
>> Though the current code ignores snprintf errors, it's simply
>> my negligence..
>>
>
> I'm voting for keeping safer snprintf_len. But I can change it if
> you wish.
>
> New patch attached.
>

OK please commit it.

regards,
Hiroshi Inoue

---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend

Re: Patch for snprintf problem (bug #1000650) 5-th try

am 15.06.2006 09:10:20 von Ludek Finstrle

> OK please commit it.

Patch commited.

Thanks,

Luf

---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?

http://archives.postgresql.org