BUG #12917: C program created by ecpg core dumped due to “varcharsize * offset” - Mailing list pgsql-bugs
From | chjischj@163.com |
---|---|
Subject | BUG #12917: C program created by ecpg core dumped due to “varcharsize * offset” |
Date | |
Msg-id | 20150330111334.2492.38927@wrigleys.postgresql.org Whole thread Raw |
Responses |
Re: BUG #12917: C program created by ecpg core dumped due to
"varcharsize * offset"
|
List | 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 by date: