From bd5e130c2c8958facf6eb676e5f6899408ef214e Mon Sep 17 00:00:00 2001 From: tgl Date: Sun, 3 Aug 2008 15:23:58 +0000 Subject: [PATCH] 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. --- src/backend/catalog/pg_type.c | 69 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 6 deletions(-) diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index 81c7be8aa9..58fc2808eb 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -213,8 +213,7 @@ TypeCreate(Oid newTypeOid, * not check for bad combinations. * * Validate size specifications: either positive (fixed-length) or -1 - * (varlena) or -2 (cstring). Pass-by-value types must have a fixed - * length not more than sizeof(Datum). + * (varlena) or -2 (cstring). */ if (!(internalSize > 0 || internalSize == -1 || @@ -223,12 +222,70 @@ TypeCreate(Oid newTypeOid, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("invalid type internal size %d", internalSize))); - if (passedByValue && - (internalSize <= 0 || internalSize > (int16) sizeof(Datum))) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + + if (passedByValue) + { + /* + * Pass-by-value types must have a fixed length that is one of the + * values supported by fetch_att() and store_att_byval(); and the + * alignment had better agree, too. All this code must match + * access/tupmacs.h! + */ + if (internalSize == (int16) sizeof(char)) + { + if (alignment != 'c') + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d", + alignment, internalSize))); + } + else if (internalSize == (int16) sizeof(int16)) + { + if (alignment != 's') + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d", + alignment, internalSize))); + } + else if (internalSize == (int16) sizeof(int32)) + { + if (alignment != 'i') + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d", + alignment, internalSize))); + } +#if SIZEOF_DATUM == 8 + else if (internalSize == (int16) sizeof(Datum)) + { + if (alignment != 'd') + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d", + alignment, internalSize))); + } +#endif + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("internal size %d is invalid for passed-by-value type", internalSize))); + } + else + { + /* varlena types must have int align or better */ + if (internalSize == -1 && !(alignment == 'i' || alignment == 'd')) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("alignment \"%c\" is invalid for variable-length type", + alignment))); + /* cstring must have char alignment */ + if (internalSize == -2 && !(alignment == 'c')) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("alignment \"%c\" is invalid for variable-length type", + alignment))); + } /* Only varlena types can be toasted */ if (storage != 'p' && internalSize != -1) -- 2.11.4.GIT