Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 82a1f09

Browse files
committed
Tighten up the sanity checks in TypeCreate(): pass-by-value types must have
a size that is one of the supported values, not just anything <= sizeof(Datum). Cross-check the alignment specification against size as well.
1 parent 3c93218 commit 82a1f09

File tree

1 file changed

+64
-7
lines changed

1 file changed

+64
-7
lines changed

src/backend/catalog/pg_type.c

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.120 2008/07/30 17:05:04 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.121 2008/08/03 15:23:58 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -213,8 +213,7 @@ TypeCreate(Oid newTypeOid,
213213
* not check for bad combinations.
214214
*
215215
* Validate size specifications: either positive (fixed-length) or -1
216-
* (varlena) or -2 (cstring). Pass-by-value types must have a fixed
217-
* length not more than sizeof(Datum).
216+
* (varlena) or -2 (cstring).
218217
*/
219218
if (!(internalSize > 0 ||
220219
internalSize == -1 ||
@@ -223,12 +222,70 @@ TypeCreate(Oid newTypeOid,
223222
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
224223
errmsg("invalid type internal size %d",
225224
internalSize)));
226-
if (passedByValue &&
227-
(internalSize <= 0 || internalSize > (int16) sizeof(Datum)))
228-
ereport(ERROR,
229-
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
225+
226+
if (passedByValue)
227+
{
228+
/*
229+
* Pass-by-value types must have a fixed length that is one of the
230+
* values supported by fetch_att() and store_att_byval(); and the
231+
* alignment had better agree, too. All this code must match
232+
* access/tupmacs.h!
233+
*/
234+
if (internalSize == (int16) sizeof(char))
235+
{
236+
if (alignment != 'c')
237+
ereport(ERROR,
238+
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
239+
errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
240+
alignment, internalSize)));
241+
}
242+
else if (internalSize == (int16) sizeof(int16))
243+
{
244+
if (alignment != 's')
245+
ereport(ERROR,
246+
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
247+
errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
248+
alignment, internalSize)));
249+
}
250+
else if (internalSize == (int16) sizeof(int32))
251+
{
252+
if (alignment != 'i')
253+
ereport(ERROR,
254+
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
255+
errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
256+
alignment, internalSize)));
257+
}
258+
#if SIZEOF_DATUM == 8
259+
else if (internalSize == (int16) sizeof(Datum))
260+
{
261+
if (alignment != 'd')
262+
ereport(ERROR,
263+
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
264+
errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
265+
alignment, internalSize)));
266+
}
267+
#endif
268+
else
269+
ereport(ERROR,
270+
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
230271
errmsg("internal size %d is invalid for passed-by-value type",
231272
internalSize)));
273+
}
274+
else
275+
{
276+
/* varlena types must have int align or better */
277+
if (internalSize == -1 && !(alignment == 'i' || alignment == 'd'))
278+
ereport(ERROR,
279+
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
280+
errmsg("alignment \"%c\" is invalid for variable-length type",
281+
alignment)));
282+
/* cstring must have char alignment */
283+
if (internalSize == -2 && !(alignment == 'c'))
284+
ereport(ERROR,
285+
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
286+
errmsg("alignment \"%c\" is invalid for variable-length type",
287+
alignment)));
288+
}
232289

233290
/* Only varlena types can be toasted */
234291
if (storage != 'p' && internalSize != -1)

0 commit comments

Comments
 (0)