aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/libpq/fe-exec.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-07-21 12:24:14 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2011-07-21 12:25:14 -0400
commite06d1a88f3003bbff96ba052e5ba2366265db623 (patch)
treee774b1220538dfb7ffdccfba2125d8fce82ee55b /src/interfaces/libpq/fe-exec.c
parent92591c4c8fb4f1d454baf3fd3f3e8f44793f5b95 (diff)
downloadpostgresql-e06d1a88f3003bbff96ba052e5ba2366265db623.tar.gz
postgresql-e06d1a88f3003bbff96ba052e5ba2366265db623.zip
Fix PQsetvalue() to avoid possible crash when adding a new tuple.
PQsetvalue unnecessarily duplicated the logic in pqAddTuple, and didn't duplicate it exactly either --- pqAddTuple does not care what is in the tuple-pointer array positions beyond the last valid entry, whereas the code in PQsetvalue assumed such positions would contain NULL. This led to possible crashes if PQsetvalue was applied to a PGresult that had previously been enlarged with pqAddTuple, for instance one built from a server query. Fix by relying on pqAddTuple instead of duplicating logic, and not assuming anything about the contents of res->tuples[res->ntups]. Back-patch to 8.4, where PQsetvalue was introduced. Andrew Chernow
Diffstat (limited to 'src/interfaces/libpq/fe-exec.c')
-rw-r--r--src/interfaces/libpq/fe-exec.c27
1 files changed, 4 insertions, 23 deletions
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index c00f5eae6ab..30c2654827c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -422,28 +422,8 @@ PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len)
if (tup_num < 0 || tup_num > res->ntups)
return FALSE;
- /* need to grow the tuple table? */
- if (res->ntups >= res->tupArrSize)
- {
- int n = res->tupArrSize ? res->tupArrSize * 2 : 128;
- PGresAttValue **tups;
-
- if (res->tuples)
- tups = (PGresAttValue **) realloc(res->tuples, n * sizeof(PGresAttValue *));
- else
- tups = (PGresAttValue **) malloc(n * sizeof(PGresAttValue *));
-
- if (!tups)
- return FALSE;
-
- memset(tups + res->tupArrSize, 0,
- (n - res->tupArrSize) * sizeof(PGresAttValue *));
- res->tuples = tups;
- res->tupArrSize = n;
- }
-
/* need to allocate a new tuple? */
- if (tup_num == res->ntups && !res->tuples[tup_num])
+ if (tup_num == res->ntups)
{
PGresAttValue *tup;
int i;
@@ -462,8 +442,9 @@ PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len)
tup[i].value = res->null_field;
}
- res->tuples[tup_num] = tup;
- res->ntups++;
+ /* add it to the array */
+ if (!pqAddTuple(res, tup))
+ return FALSE;
}
attval = &res->tuples[tup_num][field_num];