From 894fc6b763c2053c01a5be5d20a76d1db650547d Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 12 Jan 2010 02:39:22 +0000 Subject: [PATCH] Fix aclexplode to not explode on a zero-entry ACL array. (An Assert is no substitute for thinking clearly :-() Minor style kibitzing too. Per report from Robert Treat. --- src/backend/utils/adt/acl.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index f705d0eac1..52e4999900 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.154 2010/01/02 16:57:53 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.155 2010/01/12 02:39:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1680,9 +1680,9 @@ convert_aclright_to_string(int aclright) Datum aclexplode(PG_FUNCTION_ARGS) { + Acl *acl = PG_GETARG_ACL_P(0); FuncCallContext *funcctx; int *idx; - Acl *acl = PG_GETARG_ACL_P(0); AclItem *aidat; if (SRF_IS_FIRSTCALL()) @@ -1722,34 +1722,36 @@ aclexplode(PG_FUNCTION_ARGS) funcctx = SRF_PERCALL_SETUP(); idx = (int *) funcctx->user_fctx; - aidat = ACL_DAT(acl); - while (1) + + /* need test here in case acl has no items */ + while (idx[0] < ACL_NUM(acl)) { + AclItem *aidata; + AclMode priv_bit; + idx[1]++; if (idx[1] == N_ACL_RIGHTS) { idx[1] = 0; idx[0]++; - if (idx[0] == ACL_NUM(acl)) - /* done */ + if (idx[0] >= ACL_NUM(acl)) /* done */ break; } + aidata = &aidat[idx[0]]; + priv_bit = 1 << idx[1]; - Assert(idx[0] < ACL_NUM(acl)); - Assert(idx[1] < N_ACL_RIGHTS); - - if (ACLITEM_GET_PRIVS(aidat[idx[0]]) & (1 << idx[1])) + if (ACLITEM_GET_PRIVS(*aidata) & priv_bit) { Datum result; Datum values[4]; bool nulls[4]; HeapTuple tuple; - values[0] = ObjectIdGetDatum(aidat[idx[0]].ai_grantor); - values[1] = ObjectIdGetDatum(aidat[idx[0]].ai_grantee); - values[2] = CStringGetTextDatum(convert_aclright_to_string(1 << idx[1])); - values[3] = BoolGetDatum(ACLITEM_GET_GOPTIONS(aidat[idx[0]]) & (1 << idx[1])); + values[0] = ObjectIdGetDatum(aidata->ai_grantor); + values[1] = ObjectIdGetDatum(aidata->ai_grantee); + values[2] = CStringGetTextDatum(convert_aclright_to_string(priv_bit)); + values[3] = BoolGetDatum((ACLITEM_GET_GOPTIONS(*aidata) & priv_bit) != 0); MemSet(nulls, 0, sizeof(nulls)); -- 2.40.0