Skip to content

Commit 1d0d8d3

Browse files
committed
Mop-up for nulls-in-arrays patch: fix some places that access array
contents directly.
1 parent 3201b7f commit 1d0d8d3

File tree

8 files changed

+233
-278
lines changed

8 files changed

+233
-278
lines changed

contrib/dblink/dblink.c

Lines changed: 115 additions & 197 deletions
Large diffs are not rendered by default.

contrib/tsearch2/rank.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@
33
* Teodor Sigaev <teodor@sigaev.ru>
44
*/
55
#include "postgres.h"
6+
67
#include <math.h>
78

89
#include "access/gist.h"
910
#include "access/itup.h"
10-
#include "utils/builtins.h"
11+
#include "catalog/namespace.h"
12+
#include "commands/trigger.h"
13+
#include "executor/spi.h"
1114
#include "fmgr.h"
1215
#include "funcapi.h"
13-
#include "storage/bufpage.h"
14-
#include "executor/spi.h"
15-
#include "commands/trigger.h"
1616
#include "nodes/pg_list.h"
17-
#include "catalog/namespace.h"
18-
17+
#include "storage/bufpage.h"
1918
#include "utils/array.h"
19+
#include "utils/builtins.h"
2020

2121
#include "tsvector.h"
2222
#include "query.h"
@@ -354,6 +354,7 @@ rank(PG_FUNCTION_ARGS)
354354
int method = DEF_NORM_METHOD;
355355
float res = 0.0;
356356
float ws[lengthof(weights)];
357+
float4 *arrdata;
357358
int i;
358359

359360
if (ARR_NDIM(win) != 1)
@@ -366,9 +367,15 @@ rank(PG_FUNCTION_ARGS)
366367
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
367368
errmsg("array of weight is too short")));
368369

370+
if (ARR_HASNULL(win))
371+
ereport(ERROR,
372+
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
373+
errmsg("array of weight must not contain nulls")));
374+
375+
arrdata = (float4 *) ARR_DATA_PTR(win);
369376
for (i = 0; i < lengthof(weights); i++)
370377
{
371-
ws[i] = (((float4 *) ARR_DATA_PTR(win))[i] >= 0) ? ((float4 *) ARR_DATA_PTR(win))[i] : weights[i];
378+
ws[i] = (arrdata[i] >= 0) ? arrdata[i] : weights[i];
372379
if (ws[i] > 1.0)
373380
ereport(ERROR,
374381
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),

contrib/tsearch2/snowball/header.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33

44
#include "api.h"
55

6-
#define MAXINT INT_MAX
7-
#define MININT INT_MIN
8-
96
#define HEAD 2*sizeof(int)
107

118
#define SIZE(p) ((int *)(p))[-1]

contrib/tsearch2/ts_cfg.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ init_cfg(Oid id, TSCfgInfo * cfg)
113113
ts_error(ERROR, "Wrong dimension");
114114
if (ARRNELEMS(a) < 1)
115115
continue;
116+
if (ARR_HASNULL(a))
117+
ts_error(ERROR, "Array must not contain nulls");
116118

117119
cfg->map[lexid].len = ARRNELEMS(a);
118120
cfg->map[lexid].dict_id = (Datum *) malloc(sizeof(Datum) * cfg->map[lexid].len);

src/backend/utils/adt/acl.c

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.128 2005/11/17 22:14:52 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.129 2005/11/18 02:38:23 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -67,6 +67,7 @@ static List *cached_membership_roles = NIL;
6767
static const char *getid(const char *s, char *n);
6868
static void putid(char *p, const char *s);
6969
static Acl *allocacl(int n);
70+
static void check_acl(const Acl *acl);
7071
static const char *aclparse(const char *s, AclItem *aip);
7172
static bool aclitem_match(const AclItem *a1, const AclItem *a2);
7273
static void check_circularity(const Acl *old_acl, const AclItem *mod_aip,
@@ -359,6 +360,26 @@ allocacl(int n)
359360
return new_acl;
360361
}
361362

363+
/*
364+
* Verify that an ACL array is acceptable (one-dimensional and has no nulls)
365+
*/
366+
static void
367+
check_acl(const Acl *acl)
368+
{
369+
if (ARR_ELEMTYPE(acl) != ACLITEMOID)
370+
ereport(ERROR,
371+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
372+
errmsg("ACL array contains wrong datatype")));
373+
if (ARR_NDIM(acl) != 1)
374+
ereport(ERROR,
375+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
376+
errmsg("ACL arrays must be one-dimensional")));
377+
if (ARR_HASNULL(acl))
378+
ereport(ERROR,
379+
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
380+
errmsg("ACL arrays must not contain nulls")));
381+
}
382+
362383
/*
363384
* aclitemin
364385
* Allocates storage for, and fills in, a new AclItem given a string
@@ -612,15 +633,8 @@ aclupdate(const Acl *old_acl, const AclItem *mod_aip,
612633
int dst,
613634
num;
614635

615-
/* These checks for null input are probably dead code, but... */
616-
if (!old_acl || ACL_NUM(old_acl) < 0)
617-
old_acl = allocacl(0);
618-
if (!mod_aip)
619-
{
620-
new_acl = allocacl(ACL_NUM(old_acl));
621-
memcpy(new_acl, old_acl, ACL_SIZE(old_acl));
622-
return new_acl;
623-
}
636+
/* Caller probably already checked old_acl, but be safe */
637+
check_acl(old_acl);
624638

625639
/* If granting grant options, check for circularity */
626640
if (modechg != ACL_MODECHG_DEL &&
@@ -740,6 +754,8 @@ aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
740754
targ,
741755
num;
742756

757+
check_acl(old_acl);
758+
743759
/*
744760
* Make a copy of the given ACL, substituting new owner ID for old
745761
* wherever it appears as either grantor or grantee. Also note if the new
@@ -836,6 +852,8 @@ check_circularity(const Acl *old_acl, const AclItem *mod_aip,
836852
num;
837853
AclMode own_privs;
838854

855+
check_acl(old_acl);
856+
839857
/*
840858
* For now, grant options can only be granted to roles, not PUBLIC.
841859
* Otherwise we'd have to work a bit harder here.
@@ -916,6 +934,8 @@ recursive_revoke(Acl *acl,
916934
int i,
917935
num;
918936

937+
check_acl(acl);
938+
919939
/* The owner can never truly lose grant options, so short-circuit */
920940
if (grantee == ownerId)
921941
return acl;
@@ -1005,6 +1025,8 @@ aclmask(const Acl *acl, Oid roleid, Oid ownerId,
10051025
if (acl == NULL)
10061026
elog(ERROR, "null ACL");
10071027

1028+
check_acl(acl);
1029+
10081030
/* Quick exit for mask == 0 */
10091031
if (mask == 0)
10101032
return 0;
@@ -1091,6 +1113,8 @@ aclmask_direct(const Acl *acl, Oid roleid, Oid ownerId,
10911113
if (acl == NULL)
10921114
elog(ERROR, "null ACL");
10931115

1116+
check_acl(acl);
1117+
10941118
/* Quick exit for mask == 0 */
10951119
if (mask == 0)
10961120
return 0;
@@ -1151,6 +1175,8 @@ aclmembers(const Acl *acl, Oid **roleids)
11511175
return 0;
11521176
}
11531177

1178+
check_acl(acl);
1179+
11541180
/* Allocate the worst-case space requirement */
11551181
list = palloc(ACL_NUM(acl) * 2 * sizeof(Oid));
11561182
acldat = ACL_DAT(acl);
@@ -1240,6 +1266,7 @@ aclcontains(PG_FUNCTION_ARGS)
12401266
int i,
12411267
num;
12421268

1269+
check_acl(acl);
12431270
num = ACL_NUM(acl);
12441271
aidat = ACL_DAT(acl);
12451272
for (i = 0; i < num; ++i)

src/backend/utils/adt/varlena.c

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.139 2005/10/29 00:31:51 petere Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.140 2005/11/18 02:38:23 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2491,16 +2491,18 @@ array_to_text(PG_FUNCTION_ARGS)
24912491
int nitems,
24922492
*dims,
24932493
ndims;
2494-
char *p;
24952494
Oid element_type;
24962495
int typlen;
24972496
bool typbyval;
24982497
char typalign;
24992498
StringInfo result_str = makeStringInfo();
2499+
bool printed = false;
2500+
char *p;
2501+
bits8 *bitmap;
2502+
int bitmask;
25002503
int i;
25012504
ArrayMetaState *my_extra;
25022505

2503-
p = ARR_DATA_PTR(v);
25042506
ndims = ARR_NDIM(v);
25052507
dims = ARR_DIMS(v);
25062508
nitems = ArrayGetNItems(ndims, dims);
@@ -2522,7 +2524,7 @@ array_to_text(PG_FUNCTION_ARGS)
25222524
fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
25232525
sizeof(ArrayMetaState));
25242526
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
2525-
my_extra->element_type = InvalidOid;
2527+
my_extra->element_type = ~element_type;
25262528
}
25272529

25282530
if (my_extra->element_type != element_type)
@@ -2542,23 +2544,47 @@ array_to_text(PG_FUNCTION_ARGS)
25422544
typbyval = my_extra->typbyval;
25432545
typalign = my_extra->typalign;
25442546

2547+
p = ARR_DATA_PTR(v);
2548+
bitmap = ARR_NULLBITMAP(v);
2549+
bitmask = 1;
2550+
25452551
for (i = 0; i < nitems; i++)
25462552
{
25472553
Datum itemvalue;
25482554
char *value;
25492555

2550-
itemvalue = fetch_att(p, typbyval, typlen);
2556+
/* Get source element, checking for NULL */
2557+
if (bitmap && (*bitmap & bitmask) == 0)
2558+
{
2559+
/* we ignore nulls */
2560+
}
2561+
else
2562+
{
2563+
itemvalue = fetch_att(p, typbyval, typlen);
25512564

2552-
value = DatumGetCString(FunctionCall1(&my_extra->proc,
2553-
itemvalue));
2565+
value = DatumGetCString(FunctionCall1(&my_extra->proc,
2566+
itemvalue));
25542567

2555-
if (i > 0)
2556-
appendStringInfo(result_str, "%s%s", fldsep, value);
2557-
else
2558-
appendStringInfoString(result_str, value);
2568+
if (printed)
2569+
appendStringInfo(result_str, "%s%s", fldsep, value);
2570+
else
2571+
appendStringInfoString(result_str, value);
2572+
printed = true;
2573+
2574+
p = att_addlength(p, typlen, PointerGetDatum(p));
2575+
p = (char *) att_align(p, typalign);
2576+
}
25592577

2560-
p = att_addlength(p, typlen, PointerGetDatum(p));
2561-
p = (char *) att_align(p, typalign);
2578+
/* advance bitmap pointer if any */
2579+
if (bitmap)
2580+
{
2581+
bitmask <<= 1;
2582+
if (bitmask == 0x100)
2583+
{
2584+
bitmap++;
2585+
bitmask = 1;
2586+
}
2587+
}
25622588
}
25632589

25642590
PG_RETURN_TEXT_P(PG_STR_GET_TEXT(result_str->data));

src/include/utils/acl.h

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.87 2005/11/17 22:14:55 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.88 2005/11/18 02:38:24 tgl Exp $
1111
*
1212
* NOTES
1313
* An ACL array is simply an array of AclItems, representing the union
@@ -78,9 +78,9 @@ typedef struct AclItem
7878
#define ACLITEM_ALL_GOPTION_BITS ((AclMode) 0xFFFF << 16)
7979

8080
/*
81-
* Definitions for convenient access to Acl (array of AclItem) and IdList
82-
* (array of Oid). These are standard PostgreSQL arrays, but are restricted
83-
* to have one dimension. We also ignore the lower bound when reading,
81+
* Definitions for convenient access to Acl (array of AclItem).
82+
* These are standard PostgreSQL arrays, but are restricted to have one
83+
* dimension and no nulls. We also ignore the lower bound when reading,
8484
* and set it to one when writing.
8585
*
8686
* CAUTION: as of PostgreSQL 7.1, these arrays are toastable (just like all
@@ -100,16 +100,6 @@ typedef ArrayType Acl;
100100
#define ACL_N_SIZE(N) (ARR_OVERHEAD_NONULLS(1) + ((N) * sizeof(AclItem)))
101101
#define ACL_SIZE(ACL) ARR_SIZE(ACL)
102102

103-
/*
104-
* IdList a one-dimensional array of Oid
105-
*/
106-
typedef ArrayType IdList;
107-
108-
#define IDLIST_NUM(IDL) (ARR_DIMS(IDL)[0])
109-
#define IDLIST_DAT(IDL) ((Oid *) ARR_DATA_PTR(IDL))
110-
#define IDLIST_N_SIZE(N) (ARR_OVERHEAD_NONULLS(1) + ((N) * sizeof(Oid)))
111-
#define IDLIST_SIZE(IDL) ARR_SIZE(IDL)
112-
113103
/*
114104
* fmgr macros for these types
115105
*/
@@ -123,13 +113,6 @@ typedef ArrayType IdList;
123113
#define PG_GETARG_ACL_P_COPY(n) DatumGetAclPCopy(PG_GETARG_DATUM(n))
124114
#define PG_RETURN_ACL_P(x) PG_RETURN_POINTER(x)
125115

126-
#define DatumGetIdListP(X) ((IdList *) PG_DETOAST_DATUM(X))
127-
#define DatumGetIdListPCopy(X) ((IdList *) PG_DETOAST_DATUM_COPY(X))
128-
#define PG_GETARG_IDLIST_P(n) DatumGetIdListP(PG_GETARG_DATUM(n))
129-
#define PG_GETARG_IDLIST_P_COPY(n) DatumGetIdListPCopy(PG_GETARG_DATUM(n))
130-
#define PG_RETURN_IDLIST_P(x) PG_RETURN_POINTER(x)
131-
132-
133116
/*
134117
* ACL modification opcodes for aclupdate
135118
*/

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy