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

Commita19f260

Browse files
committed
Add defenses against invalid operator names passed in CREATE OPERATOR
arguments (where the parser doesn't check them already). Minor codecleanups too.
1 parent970a2d1 commita19f260

File tree

1 file changed

+106
-73
lines changed

1 file changed

+106
-73
lines changed

‎src/backend/catalog/pg_operator.c

Lines changed: 106 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.61 2001/08/10 15:49:39 petere Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.62 2001/10/22 19:34:13 tgl Exp $
1212
*
1313
* NOTES
1414
* these routines moved here from commands/define.c and somewhat cleaned up.
@@ -41,11 +41,6 @@ static Oid OperatorGet(char *operatorName,
4141
char*rightTypeName,
4242
bool*defined);
4343

44-
staticOidOperatorShellMakeWithOpenRelation(Relationpg_operator_desc,
45-
char*operatorName,
46-
OidleftObjectId,
47-
OidrightObjectId);
48-
4944
staticOidOperatorShellMake(char*operatorName,
5045
char*leftTypeName,
5146
char*rightTypeName);
@@ -66,6 +61,65 @@ static void OperatorDef(char *operatorName,
6661

6762
staticvoidOperatorUpd(OidbaseId,OidcommId,OidnegId);
6863

64+
65+
/*
66+
* Check whether a proposed operator name is legal
67+
*
68+
* This had better match the behavior of parser/scan.l!
69+
*
70+
* We need this because the parser is not smart enough to check that
71+
* the arguments of CREATE OPERATOR's COMMUTATOR, NEGATOR, etc clauses
72+
* are operator names rather than some other lexical entity.
73+
*/
74+
staticbool
75+
validOperatorName(constchar*name)
76+
{
77+
size_tlen=strlen(name);
78+
79+
/* Can't be empty or too long */
80+
if (len==0||len >=NAMEDATALEN)
81+
return false;
82+
83+
/* Can't contain any invalid characters */
84+
/* Test string here should match op_chars in scan.l */
85+
if (strspn(name,"~!@#^&|`?$+-*/%<>=")!=len)
86+
return false;
87+
88+
/* Can't contain slash-star or dash-dash (comment starts) */
89+
if (strstr(name,"/*")||strstr(name,"--"))
90+
return false;
91+
92+
/*
93+
* For SQL92 compatibility, '+' and '-' cannot be the
94+
* last char of a multi-char operator unless the operator
95+
* contains chars that are not in SQL92 operators.
96+
* The idea is to lex '=-' as two operators, but not
97+
* to forbid operator names like '?-' that could not be
98+
* sequences of SQL92 operators.
99+
*/
100+
if (len>1&&
101+
(name[len-1]=='+'||
102+
name[len-1]=='-'))
103+
{
104+
intic;
105+
106+
for (ic=len-2;ic >=0;ic--)
107+
{
108+
if (strchr("~!@#^&|`?$%",name[ic]))
109+
break;
110+
}
111+
if (ic<0)
112+
return false;/* nope, not valid */
113+
}
114+
115+
/* != isn't valid either, because parser will convert it to <> */
116+
if (strcmp(name,"!=")==0)
117+
return false;
118+
119+
return true;
120+
}
121+
122+
69123
/* ----------------------------------------------------------------
70124
*OperatorGetWithOpenRelation
71125
*
@@ -157,7 +211,6 @@ OperatorGet(char *operatorName,
157211
bool*defined)
158212
{
159213
Relationpg_operator_desc;
160-
161214
OidoperatorObjectId;
162215
OidleftObjectId=InvalidOid;
163216
OidrightObjectId=InvalidOid;
@@ -215,24 +268,55 @@ OperatorGet(char *operatorName,
215268
}
216269

217270
/* ----------------------------------------------------------------
218-
*OperatorShellMakeWithOpenRelation
271+
*OperatorShellMake
219272
*
273+
*Specify operator name and left and right type names,
274+
*fill an operator struct with this info and NULL's,
275+
*call heap_insert and return the Oid to the caller.
220276
* ----------------------------------------------------------------
221277
*/
222278
staticOid
223-
OperatorShellMakeWithOpenRelation(Relationpg_operator_desc,
224-
char*operatorName,
225-
OidleftObjectId,
226-
OidrightObjectId)
279+
OperatorShellMake(char*operatorName,
280+
char*leftTypeName,
281+
char*rightTypeName)
227282
{
283+
Relationpg_operator_desc;
284+
OidoperatorObjectId;
285+
OidleftObjectId=InvalidOid;
286+
OidrightObjectId=InvalidOid;
287+
boolleftDefined= false;
288+
boolrightDefined= false;
228289
inti;
229290
HeapTupletup;
230291
Datumvalues[Natts_pg_operator];
231292
charnulls[Natts_pg_operator];
232-
OidoperatorObjectId;
233293
NameDataoname;
234294
TupleDesctupDesc;
235295

296+
/*
297+
* validate operator name
298+
*/
299+
if (!validOperatorName(operatorName))
300+
elog(ERROR,"\"%s\" is not a valid operator name",operatorName);
301+
302+
/*
303+
* get the left and right type oid's for this operator
304+
*/
305+
if (leftTypeName)
306+
leftObjectId=TypeGet(leftTypeName,&leftDefined);
307+
308+
if (rightTypeName)
309+
rightObjectId=TypeGet(rightTypeName,&rightDefined);
310+
311+
if (!((OidIsValid(leftObjectId)&&leftDefined)||
312+
(OidIsValid(rightObjectId)&&rightDefined)))
313+
elog(ERROR,"OperatorShellMake: the operand types are not valid");
314+
315+
/*
316+
* open pg_operator
317+
*/
318+
pg_operator_desc=heap_openr(OperatorRelationName,RowExclusiveLock);
319+
236320
/*
237321
* initialize our *nulls and *values arrays
238322
*/
@@ -243,7 +327,7 @@ OperatorShellMakeWithOpenRelation(Relation pg_operator_desc,
243327
}
244328

245329
/*
246-
* initialize*values with the operator name and input data types.
330+
* initialize values[] with the operator name and input data types.
247331
* Note that oprcode is set to InvalidOid, indicating it's a shell.
248332
*/
249333
i=0;
@@ -270,12 +354,10 @@ OperatorShellMakeWithOpenRelation(Relation pg_operator_desc,
270354
*/
271355
tupDesc=pg_operator_desc->rd_att;
272356

273-
tup=heap_formtuple(tupDesc,
274-
values,
275-
nulls);
357+
tup=heap_formtuple(tupDesc,values,nulls);
276358

277359
/*
278-
* insert our "shell" operator tuple and close the relation
360+
* insert our "shell" operator tuple
279361
*/
280362
heap_insert(pg_operator_desc,tup);
281363
operatorObjectId=tup->t_data->t_oid;
@@ -289,63 +371,8 @@ OperatorShellMakeWithOpenRelation(Relation pg_operator_desc,
289371
CatalogCloseIndices(Num_pg_operator_indices,idescs);
290372
}
291373

292-
/*
293-
* free the tuple and return the operator oid
294-
*/
295374
heap_freetuple(tup);
296375

297-
returnoperatorObjectId;
298-
}
299-
300-
/* ----------------------------------------------------------------
301-
*OperatorShellMake
302-
*
303-
*Specify operator name and left and right type names,
304-
*fill an operator struct with this info and NULL's,
305-
*call heap_insert and return the Oid
306-
*to the caller.
307-
* ----------------------------------------------------------------
308-
*/
309-
staticOid
310-
OperatorShellMake(char*operatorName,
311-
char*leftTypeName,
312-
char*rightTypeName)
313-
{
314-
Relationpg_operator_desc;
315-
OidoperatorObjectId;
316-
317-
OidleftObjectId=InvalidOid;
318-
OidrightObjectId=InvalidOid;
319-
boolleftDefined= false;
320-
boolrightDefined= false;
321-
322-
/*
323-
* get the left and right type oid's for this operator
324-
*/
325-
if (leftTypeName)
326-
leftObjectId=TypeGet(leftTypeName,&leftDefined);
327-
328-
if (rightTypeName)
329-
rightObjectId=TypeGet(rightTypeName,&rightDefined);
330-
331-
if (!((OidIsValid(leftObjectId)&&leftDefined)||
332-
(OidIsValid(rightObjectId)&&rightDefined)))
333-
elog(ERROR,"OperatorShellMake: the operand types are not valid");
334-
335-
/*
336-
* open pg_operator
337-
*/
338-
pg_operator_desc=heap_openr(OperatorRelationName,RowExclusiveLock);
339-
340-
/*
341-
* add a "shell" operator tuple to the operator relation and recover
342-
* the shell tuple's oid.
343-
*/
344-
operatorObjectId=OperatorShellMakeWithOpenRelation(pg_operator_desc,
345-
operatorName,
346-
leftObjectId,
347-
rightObjectId);
348-
349376
/*
350377
* close the operator relation and return the oid.
351378
*/
@@ -484,6 +511,12 @@ OperatorDef(char *operatorName,
484511
* filling in a previously-created shell.
485512
*/
486513

514+
/*
515+
* validate operator name
516+
*/
517+
if (!validOperatorName(operatorName))
518+
elog(ERROR,"\"%s\" is not a valid operator name",operatorName);
519+
487520
/*
488521
* look up the operator data types.
489522
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp