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
This commit is contained in:
parent
0ce7676aa0
commit
a9f0dbc39d
@ -424,28 +424,8 @@ PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len)
|
|||||||
if (tup_num < 0 || tup_num > res->ntups)
|
if (tup_num < 0 || tup_num > res->ntups)
|
||||||
return FALSE;
|
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? */
|
/* need to allocate a new tuple? */
|
||||||
if (tup_num == res->ntups && !res->tuples[tup_num])
|
if (tup_num == res->ntups)
|
||||||
{
|
{
|
||||||
PGresAttValue *tup;
|
PGresAttValue *tup;
|
||||||
int i;
|
int i;
|
||||||
@ -464,8 +444,9 @@ PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len)
|
|||||||
tup[i].value = res->null_field;
|
tup[i].value = res->null_field;
|
||||||
}
|
}
|
||||||
|
|
||||||
res->tuples[tup_num] = tup;
|
/* add it to the array */
|
||||||
res->ntups++;
|
if (!pqAddTuple(res, tup))
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
attval = &res->tuples[tup_num][field_num];
|
attval = &res->tuples[tup_num][field_num];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user