Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit368964e

Browse files
committed
Fix security and 64-bit issues in contrib/intagg. This code could
stand to be rewritten altogether, but for now just stick a finger inthe dike.
1 parent5e95311 commit368964e

File tree

2 files changed

+50
-56
lines changed

2 files changed

+50
-56
lines changed

‎contrib/intagg/int_aggregate.c

Lines changed: 37 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
* This file is the property of the Digital Music Network (DMN).
1212
* It is being made available to users of the PostgreSQL system
1313
* under the BSD license.
14-
*
15-
* NOTE: This module requires sizeof(void *) to be the same as sizeof(int)
1614
*/
1715
#include"postgres.h"
1816

@@ -36,9 +34,6 @@
3634
#include"utils/lsyscache.h"
3735

3836

39-
/* Uncomment this define if you are compiling for postgres 7.2.x */
40-
/* #define PG_7_2 */
41-
4237
/* This is actually a postgres version of a one dimensional array */
4338

4439
typedefstruct
@@ -58,19 +53,17 @@ typedef struct callContext
5853
}CTX;
5954

6055
#defineTOASTED1
61-
#defineSTART_NUM8
62-
#definePGARRAY_SIZE(n) (sizeof(PGARRAY) + ((n-1)*sizeof(int4)))
56+
#defineSTART_NUM8/* initial size of arrays */
57+
#definePGARRAY_SIZE(n) (sizeof(PGARRAY) + (((n)-1)*sizeof(int4)))
6358

64-
staticPGARRAY*GetPGArray(int4state,intfAdd);
65-
staticPGARRAY*ShrinkPGArray(PGARRAY*p);
59+
staticPGARRAY*GetPGArray(PGARRAY*p,intfAdd);
60+
staticPGARRAY*ShrinkPGArray(PGARRAY*p);
6661

6762
Datumint_agg_state(PG_FUNCTION_ARGS);
68-
Datumint_agg_final_count(PG_FUNCTION_ARGS);
6963
Datumint_agg_final_array(PG_FUNCTION_ARGS);
7064
Datumint_enum(PG_FUNCTION_ARGS);
7165

7266
PG_FUNCTION_INFO_V1(int_agg_state);
73-
PG_FUNCTION_INFO_V1(int_agg_final_count);
7467
PG_FUNCTION_INFO_V1(int_agg_final_array);
7568
PG_FUNCTION_INFO_V1(int_enum);
7669

@@ -81,11 +74,9 @@ PG_FUNCTION_INFO_V1(int_enum);
8174
* PortalContext isn't really right, but it's close enough.
8275
*/
8376
staticPGARRAY*
84-
GetPGArray(int4state,intfAdd)
77+
GetPGArray(PGARRAY*p,intfAdd)
8578
{
86-
PGARRAY*p= (PGARRAY*)state;
87-
88-
if (!state)
79+
if (!p)
8980
{
9081
/* New array */
9182
intcb=PGARRAY_SIZE(START_NUM);
@@ -94,9 +85,7 @@ GetPGArray(int4 state, int fAdd)
9485
p->a.size=cb;
9586
p->a.ndim=0;
9687
p->a.flags=0;
97-
#ifndefPG_7_2
9888
p->a.elemtype=INT4OID;
99-
#endif
10089
p->items=0;
10190
p->lower=START_NUM;
10291
}
@@ -118,7 +107,8 @@ GetPGArray(int4 state, int fAdd)
118107
}
119108

120109
/* Shrinks the array to its actual size and moves it into the standard
121-
* memory allocation context, frees working memory*/
110+
* memory allocation context, frees working memory
111+
*/
122112
staticPGARRAY*
123113
ShrinkPGArray(PGARRAY*p)
124114
{
@@ -139,10 +129,8 @@ ShrinkPGArray(PGARRAY * p)
139129
pnew->a.size=cb;
140130
pnew->a.ndim=1;
141131
pnew->a.flags=0;
142-
#ifndefPG_7_2
143132
pnew->a.elemtype=INT4OID;
144-
#endif
145-
pnew->lower=0;
133+
pnew->lower=1;
146134

147135
pfree(p);
148136
}
@@ -153,28 +141,37 @@ ShrinkPGArray(PGARRAY * p)
153141
Datum
154142
int_agg_state(PG_FUNCTION_ARGS)
155143
{
156-
int4state=PG_GETARG_INT32(0);
157-
int4value=PG_GETARG_INT32(1);
158-
159-
PGARRAY*p=GetPGArray(state,1);
144+
PGARRAY*state;
145+
PGARRAY*p;
160146

161-
if (!p)
162-
/* internal error */
163-
elog(ERROR,"no aggregate storage");
164-
elseif (p->items >=p->lower)
165-
/* internal error */
166-
elog(ERROR,"aggregate storage too small");
147+
if (PG_ARGISNULL(0))
148+
state=NULL;
167149
else
168-
p->array[p->items++]=value;
169-
PG_RETURN_INT32(p);
150+
state= (PGARRAY*)PG_GETARG_POINTER(0);
151+
p=GetPGArray(state,1);
152+
153+
if (!PG_ARGISNULL(1))
154+
{
155+
int4value=PG_GETARG_INT32(1);
156+
157+
if (!p)/* internal error */
158+
elog(ERROR,"no aggregate storage");
159+
elseif (p->items >=p->lower)/* internal error */
160+
elog(ERROR,"aggregate storage too small");
161+
else
162+
p->array[p->items++]=value;
163+
}
164+
PG_RETURN_POINTER(p);
170165
}
171166

172-
/* This is the final function used for the integer aggregator. It returns all the integers
173-
* collected as a one dimensional integer array */
167+
/* This is the final function used for the integer aggregator. It returns all
168+
* the integers collected as a one dimensional integer array
169+
*/
174170
Datum
175171
int_agg_final_array(PG_FUNCTION_ARGS)
176172
{
177-
PGARRAY*pnew=ShrinkPGArray(GetPGArray(PG_GETARG_INT32(0),0));
173+
PGARRAY*state= (PGARRAY*)PG_GETARG_POINTER(0);
174+
PGARRAY*pnew=ShrinkPGArray(GetPGArray(state,0));
178175

179176
if (pnew)
180177
PG_RETURN_POINTER(pnew);
@@ -206,30 +203,23 @@ int_enum(PG_FUNCTION_ARGS)
206203
/* Allocate a working context */
207204
pc= (CTX*)palloc(sizeof(CTX));
208205

209-
/* Don't copy attribute if you don't needtoo */
206+
/* Don't copy attribute if you don't needto */
210207
if (VARATT_IS_EXTENDED(p))
211208
{
212209
/* Toasted!!! */
213210
pc->p= (PGARRAY*)PG_DETOAST_DATUM_COPY(p);
214211
pc->flags=TOASTED;
215-
if (!pc->p)
216-
{
217-
/* internal error */
218-
elog(ERROR,"error in toaster; not detoasting");
219-
PG_RETURN_NULL();
220-
}
221212
}
222213
else
223214
{
224215
/* Untoasted */
225216
pc->p=p;
226217
pc->flags=0;
227218
}
228-
fcinfo->context= (Node*)pc;
229219
pc->num=0;
220+
fcinfo->context= (Node*)pc;
230221
}
231-
else
232-
/* use an existing one */
222+
else/* use an existing one */
233223
pc= (CTX*)fcinfo->context;
234224
/* Are we done yet? */
235225
if (pc->num >=pc->p->items)
@@ -242,8 +232,8 @@ int_enum(PG_FUNCTION_ARGS)
242232
rsi->isDone=ExprEndResult;
243233
}
244234
else
245-
/* nope, return the next value */
246235
{
236+
/* nope, return the next value */
247237
intval=pc->p->array[pc->num++];
248238

249239
rsi->isDone=ExprMultipleResult;

‎contrib/intagg/int_aggregate.sql.in

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,34 @@ SET search_path = public;
33

44
-- Internal function for the aggregate
55
-- Is called for each item in an aggregation
6-
CREATE OR REPLACE FUNCTION int_agg_state (int4, int4)
7-
RETURNS int4
6+
CREATE OR REPLACE FUNCTION int_agg_state (int4[], int4)
7+
RETURNS int4[]
88
AS 'MODULE_PATHNAME','int_agg_state'
9-
LANGUAGE 'C' IMMUTABLE STRICT;
9+
LANGUAGE 'C';
1010

1111
-- Internal function for the aggregate
1212
-- Is called at the end of the aggregation, and returns an array.
13-
CREATE OR REPLACE FUNCTION int_agg_final_array (int4)
13+
CREATE OR REPLACE FUNCTION int_agg_final_array (int4[])
1414
RETURNS int4[]
1515
AS 'MODULE_PATHNAME','int_agg_final_array'
16-
LANGUAGE 'C'IMMUTABLESTRICT;
16+
LANGUAGE 'C' STRICT;
1717

1818
-- The aggregate function itself
1919
-- uses the above functions to create an array of integers from an aggregation.
2020
CREATE AGGREGATE int_array_aggregate (
2121
BASETYPE = int4,
2222
SFUNC = int_agg_state,
23-
STYPE = int4,
24-
FINALFUNC = int_agg_final_array,
25-
INITCOND = 0
23+
STYPE = int4[],
24+
FINALFUNC = int_agg_final_array
2625
);
2726

27+
-- The aggregate component functions are not designed to be called
28+
-- independently, so disable public access to them
29+
REVOKE ALL ON FUNCTION int_agg_state (int4[], int4) FROM PUBLIC;
30+
REVOKE ALL ON FUNCTION int_agg_final_array (int4[]) FROM PUBLIC;
31+
2832
-- The enumeration function
29-
-- returns each element in a onedimentional integer array
33+
-- returns each element in a onedimensional integer array
3034
-- as a row.
3135
CREATE OR REPLACE FUNCTION int_array_enum(int4[])
3236
RETURNS setof integer

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp