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

Lines changed: 57 additions & 1 deletion
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

Lines changed: 9 additions & 0 deletions
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

Lines changed: 6 additions & 0 deletions
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)
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