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

Поиск
Список
Период
Сортировка
От chjischj@163.com
Тема BUG #12917: C program created by ecpg core dumped due to “varcharsize * offset”
Дата
Msg-id 20150330111334.2492.38927@wrigleys.postgresql.org
обсуждение исходный текст
Ответы Re: BUG #12917: C program created by ecpg core dumped due to "varcharsize * offset"  (Michael Paquier <michael.paquier@gmail.com>)
Список pgsql-bugs
The following bug has been logged on the website:

Bug reference:      12917
Logged by:          Chen Huajun
Email address:      chjischj@163.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



В списке pgsql-bugs по дате отправления:

Предыдущее
От: Jeff Davis
Дата:
Сообщение: Re: pg_get_constraintdef() doesn't always give an equal constraint
Следующее
От: Stephen Frost
Дата:
Сообщение: Re: pg_get_constraintdef() doesn't always give an equal constraint