Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit fdac8cf

Browse files
committed
Check to ensure the number of primary key fields supplied does not
exceed the total number of non-dropped source table fields for dblink_build_sql_*(). Addresses bug report from Rushabh Lathia. Backpatch all the way to the 7.3 branch.
1 parent 73a835e commit fdac8cf

File tree

3 files changed

+72
-1
lines changed

3 files changed

+72
-1
lines changed

contrib/dblink/dblink.c

+57-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Darko Prenosil <Darko.Prenosil@finteh.hr>
99
* Shridhar Daithankar <shridhar_daithankar@persistent.co.in>
1010
*
11-
* $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.87 2010/01/24 22:19:38 joe Exp $
11+
* $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.88 2010/02/03 23:01:11 joe Exp $
1212
* Copyright (c) 2001-2010, PostgreSQL Global Development Group
1313
* ALL RIGHTS RESERVED;
1414
*
@@ -101,6 +101,7 @@ static void dblink_security_check(PGconn *conn, remoteConn *rconn);
101101
static void dblink_res_error(const char *conname, PGresult *res, const char *dblink_context_msg, bool fail);
102102
static char *get_connect_string(const char *servername);
103103
static char *escape_param_str(const char *from);
104+
static int get_nondropped_natts(Oid relid);
104105

105106
/* Global */
106107
static remoteConn *pconn = NULL;
@@ -1262,6 +1263,7 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
12621263
int src_nitems;
12631264
int tgt_nitems;
12641265
char *sql;
1266+
int nondropped_natts;
12651267

12661268
/*
12671269
* Convert relname to rel OID.
@@ -1289,6 +1291,15 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
12891291
errmsg("input for number of primary key " \
12901292
"attributes too large")));
12911293

1294+
/*
1295+
* ensure we don't ask for more pk attributes than we have
1296+
* non-dropped columns
1297+
*/
1298+
nondropped_natts = get_nondropped_natts(relid);
1299+
if (pknumatts > nondropped_natts)
1300+
ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR),
1301+
errmsg("number of primary key fields exceeds number of specified relation attributes")));
1302+
12921303
/*
12931304
* Source array is made up of key values that will be used to locate the
12941305
* tuple of interest from the local system.
@@ -1354,6 +1365,7 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
13541365
int2vector *pkattnums = (int2vector *) PG_GETARG_POINTER(1);
13551366
int32 pknumatts_tmp = PG_GETARG_INT32(2);
13561367
ArrayType *tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(3);
1368+
int nondropped_natts;
13571369
Oid relid;
13581370
int16 pknumatts = 0;
13591371
char **tgt_pkattvals;
@@ -1386,6 +1398,15 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
13861398
errmsg("input for number of primary key " \
13871399
"attributes too large")));
13881400

1401+
/*
1402+
* ensure we don't ask for more pk attributes than we have
1403+
* non-dropped columns
1404+
*/
1405+
nondropped_natts = get_nondropped_natts(relid);
1406+
if (pknumatts > nondropped_natts)
1407+
ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR),
1408+
errmsg("number of primary key fields exceeds number of specified relation attributes")));
1409+
13891410
/*
13901411
* Target array is made up of key values that will be used to build the
13911412
* SQL string for use on the remote system.
@@ -1441,6 +1462,7 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
14411462
int32 pknumatts_tmp = PG_GETARG_INT32(2);
14421463
ArrayType *src_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(3);
14431464
ArrayType *tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(4);
1465+
int nondropped_natts;
14441466
Oid relid;
14451467
int16 pknumatts = 0;
14461468
char **src_pkattvals;
@@ -1475,6 +1497,15 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
14751497
errmsg("input for number of primary key " \
14761498
"attributes too large")));
14771499

1500+
/*
1501+
* ensure we don't ask for more pk attributes than we have
1502+
* non-dropped columns
1503+
*/
1504+
nondropped_natts = get_nondropped_natts(relid);
1505+
if (pknumatts > nondropped_natts)
1506+
ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR),
1507+
errmsg("number of primary key fields exceeds number of specified relation attributes")));
1508+
14781509
/*
14791510
* Source array is made up of key values that will be used to locate the
14801511
* tuple of interest from the local system.
@@ -2442,3 +2473,28 @@ escape_param_str(const char *str)
24422473

24432474
return buf->data;
24442475
}
2476+
2477+
static int
2478+
get_nondropped_natts(Oid relid)
2479+
{
2480+
int nondropped_natts = 0;
2481+
TupleDesc tupdesc;
2482+
Relation rel;
2483+
int natts;
2484+
int i;
2485+
2486+
rel = relation_open(relid, AccessShareLock);
2487+
tupdesc = rel->rd_att;
2488+
natts = tupdesc->natts;
2489+
2490+
for (i = 0; i < natts; i++)
2491+
{
2492+
if (tupdesc->attrs[i]->attisdropped)
2493+
continue;
2494+
nondropped_natts++;
2495+
}
2496+
2497+
relation_close(rel, AccessShareLock);
2498+
return nondropped_natts;
2499+
}
2500+

contrib/dblink/expected/dblink.out

+9
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ SELECT dblink_build_sql_insert('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}');
3939
INSERT INTO foo(f1,f2,f3) VALUES('99','xyz','{a0,b0,c0}')
4040
(1 row)
4141

42+
-- too many pk fields, should fail
43+
SELECT dblink_build_sql_insert('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
44+
ERROR: number of primary key fields exceeds number of specified relation attributes
4245
-- build an update statement based on a local tuple,
4346
-- replacing the primary key values with new ones
4447
SELECT dblink_build_sql_update('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}');
@@ -47,13 +50,19 @@ SELECT dblink_build_sql_update('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}');
4750
UPDATE foo SET f1 = '99', f2 = 'xyz', f3 = '{a0,b0,c0}' WHERE f1 = '99' AND f2 = 'xyz'
4851
(1 row)
4952

53+
-- too many pk fields, should fail
54+
SELECT dblink_build_sql_update('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
55+
ERROR: number of primary key fields exceeds number of specified relation attributes
5056
-- build a delete statement based on a local tuple,
5157
SELECT dblink_build_sql_delete('foo','1 2',2,'{"0", "a"}');
5258
dblink_build_sql_delete
5359
---------------------------------------------
5460
DELETE FROM foo WHERE f1 = '0' AND f2 = 'a'
5561
(1 row)
5662

63+
-- too many pk fields, should fail
64+
SELECT dblink_build_sql_delete('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}');
65+
ERROR: number of primary key fields exceeds number of specified relation attributes
5766
-- retest using a quoted and schema qualified table
5867
CREATE SCHEMA "MySchema";
5968
CREATE TABLE "MySchema"."Foo"(f1 int, f2 text, f3 text[], primary key (f1,f2));

contrib/dblink/sql/dblink.sql

+6
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,19 @@ FROM dblink_get_pkey('foo');
3434
-- build an insert statement based on a local tuple,
3535
-- replacing the primary key values with new ones
3636
SELECT dblink_build_sql_insert('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}');
37+
-- too many pk fields, should fail
38+
SELECT dblink_build_sql_insert('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
3739

3840
-- build an update statement based on a local tuple,
3941
-- replacing the primary key values with new ones
4042
SELECT dblink_build_sql_update('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}');
43+
-- too many pk fields, should fail
44+
SELECT dblink_build_sql_update('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
4145

4246
-- build a delete statement based on a local tuple,
4347
SELECT dblink_build_sql_delete('foo','1 2',2,'{"0", "a"}');
48+
-- too many pk fields, should fail
49+
SELECT dblink_build_sql_delete('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}');
4450

4551
-- retest using a quoted and schema qualified table
4652
CREATE SCHEMA "MySchema";

0 commit comments

Comments
 (0)