Re: user defined type

Поиск
Список
Период
Сортировка
От Michael Fuhr
Тема Re: user defined type
Дата
Msg-id 20041108212416.GA68068@winnie.fuhr.org
обсуждение исходный текст
Ответ на user defined type  (Kjetil Haaland <kjetil.haaland@student.uib.no>)
Ответы Re: user defined type  (Kjetil Haaland <kjetil.haaland@student.uib.no>)
Список pgsql-novice
On Mon, Nov 08, 2004 at 01:26:55PM +0100, Kjetil Haaland wrote:

> typedef struct alignres {
>   int value;
>   char *fstring;
> }alignres;

If you want to store character data, I think the characters must
be stored in the structure itself; I don't think using a pointer
will work (somebody please correct me if I'm mistaken).  So instead
of "char *fstring" you'll need "char fstring[x]", where "x" is the
maximum size of the character data.  You could also use "char fstring[1]"
and allocate the alignres structure to be as big as necessary; if
you do that then you might want to review the paragraph regarding
TOAST-able types near the end of the "User-Defined Types" section
of the documentation.

http://www.postgresql.org/docs/7.4/static/xtypes.html

Make sure your CREATE TYPE statement has "internallength" set
correctly: either to the fixed size of the structure (including
character data) or to "variable".  If you use "variable" then make
sure you add the required length field to the beginning of the
structure.  See the CREATE TYPE documentation for more info.

http://www.postgresql.org/docs/7.4/static/sql-createtype.html

>   if(sscanf(in, "(%d, %s)", &v, &first) != 2) {

The above line has several problems:

* For a %s conversion, sscanf() expects a pointer to character;
earlier you declared first as a char *, so you're passing a pointer
to a pointer to character.  sscanf() also expects the pointer to
point to a buffer sufficiently large to hold the result; you haven't
allocated any space.

* %s is greedy, so it'll grab the closing parenthesis in addition
to what precedes it.  Consider using %[ instead or make sure you
strip extraneous characters from the end of the result string.

* Your %s conversion doesn't specify a maximum field width, so
you risk a buffer overflow if the result buffer isn't at least
as large as the input string.

Additionally, consider using %[ instead of %d for the first field
and store the result in a character array so you can do better
validity checking than sscanf().  For example, you could then use
strtol() to check for overflow -- with sscanf() you'd just get bogus
numbers that don't match the input.

>   char temp[4+sizeof(align->fstring)+4+4];

This line in your output function might not be allocating as much
space as you think.  The sizeof expression evaluates to the size
of a pointer, not to the length of the data pointed to.  You're
probably allocating about 16 bytes here, which might be less
than you need.

>   sprintf(temp, "(%d, %s)",
>      align->value,
>      align->fstring);

By using sprintf() instead of snprintf() you again risk a buffer
overflow, especially since temp might be smaller than you were
expecting.

There might be other problems but those stood out when I looked
through the code.  If you still have trouble then please post
the updated code and describe what happens when you try to use
the type.

Hope this helps.

--
Michael Fuhr
http://www.fuhr.org/~mfuhr/

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

Предыдущее
От: "Molenda, Mark P"
Дата:
Сообщение: Re: How to allow a JDBC to connect to my postgres databa
Следующее
От: Ian Meyer
Дата:
Сообщение: Issue with sequence and transactions