Re: user defined type - Mailing list pgsql-novice
From | Michael Fuhr |
---|---|
Subject | Re: user defined type |
Date | |
Msg-id | 20041108212416.GA68068@winnie.fuhr.org Whole thread Raw |
In response to | user defined type (Kjetil Haaland <kjetil.haaland@student.uib.no>) |
Responses |
Re: user defined type
|
List | 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 by date: