Обсуждение: BUG #2574: C function: arg TEXT data corrupt

Поиск
Список
Период
Сортировка

BUG #2574: C function: arg TEXT data corrupt

От
"Michael Enke"
Дата:
The following bug has been logged online:

Bug reference:      2574
Logged by:          Michael Enke
Email address:      michael.enke@wincor-nixdorf.com
PostgreSQL version: 8.1.4
Operating system:   Open Suse 10.1 and CentOS 4.3
Description:        C function: arg TEXT data corrupt
Details:

I created a C function:
extern Datum test_arg(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(test_arg);
Datum test_arg(PG_FUNCTION_ARGS) {
  elog(INFO, "arg: %s", VARDATA(PG_GETARG_TEXT_P(0)));
  PG_RETURN_INT16(0);
}
and used the
CREATE FUNCTION test_arg(TEXT) RETURNS INT4 AS 'path_to_lib.so' LANGUAGE
'C';

If I call this function "the first time"
after connecting with psql, the info output shows
corrupted data, the second and further call is ok:
me@noteme:~/uwx9/SVN/tpl/trunk/db/postgresql/src> psql -U tplinux
Welcome to psql 8.1.3, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help with psql commands
       \g or terminate with semicolon to execute query
       \q to quit

tplinux=> select test_arg('1');
INFO:  arg: 1s@3
 test_arg
----------
        0
(1 row)

tplinux=> select test_arg('1');
INFO:  arg: 1
 test_arg
----------
        0
(1 row)

The same problem is with input length of 2, 3, 4, 8 char (and may be more).
With input of 4 char I never get correct value.

No problem for first call with 5, 6 , 7 char,
but with 5 char problem if before called with 6 char.

Re: BUG #2574: C function: arg TEXT data corrupt

От
Tom Lane
Дата:
"Michael Enke" <michael.enke@wincor-nixdorf.com> writes:
> I created a C function:
> extern Datum test_arg(PG_FUNCTION_ARGS);
> PG_FUNCTION_INFO_V1(test_arg);
> Datum test_arg(PG_FUNCTION_ARGS) {
>   elog(INFO, "arg: %s", VARDATA(PG_GETARG_TEXT_P(0)));
>   PG_RETURN_INT16(0);

The VARDATA of a TEXT datum is not a C string; in particular it is not
guaranteed to be null-terminated.  This is an error in your code not
a bug.

The usual way to get a C string from a TEXT datum is to call textout,
eg

    str = DatumGetCString(DirectFunctionCall1(textout, datumval));

            regards, tom lane