Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)