BUG #12917: C program created by ecpg core dumped due to “varcharsize * offset”

From: chjischj(at)163(dot)com
To: pgsql-bugs(at)postgresql(dot)org
Subject: BUG #12917: C program created by ecpg core dumped due to “varcharsize * offset”
Date: 2015-03-30 11:13:34
Message-ID: 20150330111334.2492.38927@wrigleys.postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

The following bug has been logged on the website:

Bug reference: 12917
Logged by: Chen Huajun
Email address: chjischj(at)163(dot)com
PostgreSQL version: 9.4.1
Operating system: RHEL6.5
Description:

I found a strange code in ecpg.

1)Problem 1
src/interfaces/ecpg/ecpglib/data.c:241
do
{
if (binary)
{
if (varcharsize == 0 || varcharsize * offset >= size)//!!! why
"varcharsize * offset" ? !!!
memcpy(var + offset * act_tuple, pval, size);
...

According to the mean of varcharsize(from the following comment),i think the
"varcharsize * offset >= size" above should be "varcharsize >= size" or
"offset >= size".

src\interfaces\ecpg\ecpglib\execute.c:
/*------
* create a list of variables

* varcharsize - length of string in case we have a stringvariable, else 0
* offset - offset between ith and (i+1)th entry in an array, normally

*------*/

2)Problem 2
And that,according to the comment above, the varcharsize should be setted to
0 for non stringvariable data type.
But the varcharsize is setted to 1 in C code which created by ecpg. Does
this a problem, or just my misunderstand ?

src\interfaces\ecpg\test\expected\sql-desc.c:81

#line 23 "desc.pgc"

{ ECPGset_desc(__LINE__, "indesc", 1,ECPGd_data,
ECPGt_int,&(val1),(long)1,(long)1,sizeof(int), ECPGd_EODT);
^^^^^^

3)Test
The problem 1 could cause memory overflow, as the following.

Environment:
PG 9.4.1
RHEL6.5

Table and data:
create table empl(idnum integer, name char (10000000));
insert into empl values(1,'abcdddd1123444ddffdfdffddfdfffd');

test app:
binary.pgc:
----------------------
#include <stdio.h>
#include <stdlib.h>
EXEC SQL BEGIN DECLARE SECTION;
struct TBempl
{
long idnum;
char name[10000];
};
EXEC SQL END DECLARE SECTION;
int main (void)
{
EXEC SQL BEGIN DECLARE SECTION;
struct TBempl empl;
EXEC SQL END DECLARE SECTION;
ECPGdebug (1, stderr);
empl.idnum = 1;
EXEC SQL connect to postgres USER postgres;
memset(empl.name, 0, 21L);
EXEC SQL DECLARE B BINARY CURSOR FOR select name from empl where idnum
=:empl.idnum;
EXEC SQL OPEN B;
EXEC SQL FETCH B INTO :empl.name;
EXEC SQL CLOSE B;
printf ("name=%s, byte=", empl.name);
printf("\n");
EXEC SQL disconnect;
exit (0);
}

Test:
export INCLUDE_PATH=/usr/local/pgsql/include
export LIB_PATH=/usr/local/pgsql/lib
export PATH=/usr/local/pgsql/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/pgsql/lib:$LD_LIBRARY_PATH
ecpg binary.pgc
gcc binary.c -o binary -I$INCLUDE_PATH -L$LIB_PATH -lecpg
./binary
[9547]: ECPGdebug: set to 1
[9547]: ECPGconnect: opening database regcob1 on <DEFAULT> port <DEFAULT>
for user postgres
[9547]: ecpg_execute on line 24: query: declare B binary cursor for select
name from empl where idnum = $1 ; with 1 parameter(s) on connection regcob1
[9547]: ecpg_execute on line 24: using PQexecParams
[9547]: ecpg_free_params on line 24: parameter 1 = 1
[9547]: ecpg_process_output on line 24: OK: DECLARE CURSOR
[9547]: ecpg_execute on line 25: query: fetch B; with 0 parameter(s) on
connection regcob1
[9547]: ecpg_execute on line 25: using PQexec
[9547]: ecpg_process_output on line 25: correctly got 1 tuples with 1
fields
[9547]: ecpg_get_data on line 25: RESULT: BINARY offset: 10000; array: no
セグメンテーション違反です (core dumped)

(gdb) bt
#0 0x0029557e in ecpg_get_data (results=0x8d673f8, act_tuple=0,
act_field=0, lineno=25, type=ECPGt_char, ind_type=ECPGt_NO_INDICATOR,
var=0xbfaa7bf0 "abcdddd1123444ddffdfdffddfdfffd", ' ' <repeats 169
times>..., ind=0x0, varcharsize=10000, offset=10000, ind_offset=0,
isarray=ECPG_ARRAY_NONE, compat=ECPG_COMPAT_PGSQL, force_indicator=1
'\001') at data.c:246
#1 0x0028d45e in ecpg_store_result (results=0x8d673f8, act_field=0,
stmt=0x8d667e0, var=0x8d66820) at execute.c:455
#2 0x00290770 in ecpg_process_output (stmt=0x8d667e0, clear_result=1
'\001') at execute.c:1693
#3 0x002911cc in ecpg_do (lineno=25, compat=0, force_indicator=1,
connection_name=0x0, questionmarks=0 '\000', st=0,
query=0x8048908 "fetch B", args=0xbfaa7bac "\033") at execute.c:2056
#4 0x0029125a in ECPGdo (lineno=25, compat=0, force_indicator=1,
connection_name=0x0, questionmarks=0 '\000', st=0,
query=0x8048908 "fetch B") at execute.c:2078
#5 0x08048749 in main ()
(gdb) list
241 do
242 {
243 if (binary)
244 {
245 if (varcharsize == 0 || varcharsize * offset >= size)
246 memcpy(var + offset * act_tuple, pval, size); //!!! core dumped here
!!!
247 else
248 {
249 memcpy(var + offset * act_tuple, pval, varcharsize * offset);
250

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Kistler, Winnie C. 2015-03-30 13:50:09 Problem with date formatting and FM
Previous Message Jeff Davis 2015-03-30 05:43:33 Re: pg_get_constraintdef() doesn't always give an equal constraint