diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2011-07-21 12:24:14 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2011-07-21 12:25:14 -0400 |
commit | e06d1a88f3003bbff96ba052e5ba2366265db623 (patch) | |
tree | e774b1220538dfb7ffdccfba2125d8fce82ee55b /src/interfaces/libpq/fe-exec.c | |
parent | 92591c4c8fb4f1d454baf3fd3f3e8f44793f5b95 (diff) | |
download | postgresql-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.c | 27 |
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]; |