From: | Michael Fuhr <mike(at)fuhr(dot)org> |
---|---|
To: | Kjetil Haaland <kjetil(dot)haaland(at)student(dot)uib(dot)no> |
Cc: | pgsql-novice(at)postgresql(dot)org |
Subject: | Re: user defined type |
Date: | 2004-11-08 21:24:16 |
Message-ID: | 20041108212416.GA68068@winnie.fuhr.org |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | 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/
From | Date | Subject | |
---|---|---|---|
Next Message | Ian Meyer | 2004-11-09 03:27:39 | Issue with sequence and transactions |
Previous Message | Molenda, Mark P | 2004-11-08 20:13:28 | Re: How to allow a JDBC to connect to my postgres databa |