* pqAddTuple * add a row pointer to the PGresult structure, growing it if necessary * Returns true if OK, false if an error prevented adding the row * * On error, *errmsgp can be set to an error string to be returned. * If it is left NULL, the error is presumed to be "out of memory". */
| 926 | * If it is left NULL, the error is presumed to be "out of memory". |
| 927 | */ |
| 928 | static bool |
| 929 | pqAddTuple(PGresult *res, PGresAttValue *tup, const char **errmsgp) |
| 930 | { |
| 931 | if (res->ntups >= res->tupArrSize) |
| 932 | { |
| 933 | /* |
| 934 | * Try to grow the array. |
| 935 | * |
| 936 | * We can use realloc because shallow copying of the structure is |
| 937 | * okay. Note that the first time through, res->tuples is NULL. While |
| 938 | * ANSI says that realloc() should act like malloc() in that case, |
| 939 | * some old C libraries (like SunOS 4.1.x) coredump instead. On |
| 940 | * failure realloc is supposed to return NULL without damaging the |
| 941 | * existing allocation. Note that the positions beyond res->ntups are |
| 942 | * garbage, not necessarily NULL. |
| 943 | */ |
| 944 | int newSize; |
| 945 | PGresAttValue **newTuples; |
| 946 | |
| 947 | /* |
| 948 | * Since we use integers for row numbers, we can't support more than |
| 949 | * INT_MAX rows. Make sure we allow that many, though. |
| 950 | */ |
| 951 | if (res->tupArrSize <= INT_MAX / 2) |
| 952 | newSize = (res->tupArrSize > 0) ? res->tupArrSize * 2 : 128; |
| 953 | else if (res->tupArrSize < INT_MAX) |
| 954 | newSize = INT_MAX; |
| 955 | else |
| 956 | { |
| 957 | *errmsgp = libpq_gettext("PGresult cannot support more than INT_MAX tuples"); |
| 958 | return false; |
| 959 | } |
| 960 | |
| 961 | /* |
| 962 | * Also, on 32-bit platforms we could, in theory, overflow size_t even |
| 963 | * before newSize gets to INT_MAX. (In practice we'd doubtless hit |
| 964 | * OOM long before that, but let's check.) |
| 965 | */ |
| 966 | #if INT_MAX >= (SIZE_MAX / 2) |
| 967 | if (newSize > SIZE_MAX / sizeof(PGresAttValue *)) |
| 968 | { |
| 969 | *errmsgp = libpq_gettext("size_t overflow"); |
| 970 | return false; |
| 971 | } |
| 972 | #endif |
| 973 | |
| 974 | if (res->tuples == NULL) |
| 975 | newTuples = (PGresAttValue **) |
| 976 | malloc(newSize * sizeof(PGresAttValue *)); |
| 977 | else |
| 978 | newTuples = (PGresAttValue **) |
| 979 | realloc(res->tuples, newSize * sizeof(PGresAttValue *)); |
| 980 | if (!newTuples) |
| 981 | return false; /* malloc or realloc failed */ |
| 982 | res->memorySize += |
| 983 | (newSize - res->tupArrSize) * sizeof(PGresAttValue *); |
| 984 | res->tupArrSize = newSize; |
| 985 | res->tuples = newTuples; |
no test coverage detected